Problème 1.1 : améliorer l'existant
Définir un nouvel outil, c'est d'abord améliorer les outils existants. Concernant l'édition de texte, une qualité implicitement admise est celle d'être "WYSIWYG (What You See Is What You Get)" : on veut au minimum que le texte saisi – dans lequel on attache des relations sémantiques – et le texte lu – produit final de la phase d'édition – soient semblables.
Réponse 1.1 : interface utilisateur
La solution consiste à définir une bonne interface utilisateur. Ceci semble peut-être une première évidence, mais fallait-il encore le dire.
Problème 1.2 : environnement de programmation
Comment faire le lien entre un tel texte traité et les outils présents dans l'environnement – analyseur syntaxique, compilateur, interpréteur, ... ?
Le problème soulevé est double :
Réponse 1.2 : représentation par les arbres syntaxiques
On constate que, s'il est peut-être mauvais d'accorder trop d'importance à la syntaxe des syntaxes des langages de programmation, c'est tout de même celle-ci qui guide le choix des relations sémantiques qu'on détecte dans le programme. On peut en effet s'interroger sur la sémantique commune à deux morceaux d'instructions, tous deux incomplets, et qui ne représentent aucune structure syntaxique.
On s'imposera donc de ne lier sémantiquement deux "morceaux de texte" que si ces deux "morceaux de texte" sont en fait des structures syntaxiquement complètes, quoique éventuellement paramétrées. Par exemple, si l'on a :
"X:=val" et "Y:=val"
on ne lie pas :
":=val"
mais :
"<param>:=val"
sachant que <param> vaut X ou Y selon le cas.
Problème 1.2.1 : création des identificateurs
La seule restriction qu'apporterait vraiment cette contrainte concerne la manipulation lexicale des identificateurs. On ne peut en effet plus définir un identificateur comme le produit de la concaténation de deux autres identificateurs, moyen qui permet de construire sans trop d'effort des identificateurs "sémantiquement parlants".
Réponse 1.2.1 : intérêt de la création
La question est de savoir si la création dynamique de symboles est un aspect bien important, ou bien plutôt une facilité dont on peut aisément se dispenser.
Problème 1.3 : traitement de programmes existants
Que faire des traitement de programmes existants ?
Réponse 1.3.a : concentration lexicale des identificateurs
Une première réponse, et non des moindres, concerne les identificateurs : il faut définir un outil d'analyse lexicale, qui regroupe les identificateurs. De là on peut déduire :
- une trace des appels de procédures,
- un trace des utilisations des variables globales,
- une cohérence entre l'évolution possible des identificateurs.
Problème 1.3.a.1 : langages à structure de blocs statique
Que dire des langages pour lesquels la déclaration des identificateurs a une portée limitée ? Par exemple en Pascal :
function A(x:integer);
function B(x:integer);
begin
B:=x+1;
end;
begin
A:=B(x)+1;
end;
Réponse 1.3.a.1 : concentration syntaxique des identificateurs
L'outil de concentration des identificateurs doit connaître la portée des déclarations. Il faut alors définir un outil d'analyse syntaxique qui attache au niveau de l'en-tête de chaque bloc les déclarations et utilisations des identificateurs apparaissant dans le bloc.
Problème 1.3.a.1.1 : surcharge des identificateurs
Il s'agit de la notion de surcharge : dans un contexte donné, on a la visibilité de deux objets :
- qui sont de même nature syntaxique (procédure ou fonction) ;
- qui sont reconnus par le même identificateur ;
- qui peuvent avoir le même nombre de paramètres.
Comment alors distinguer ces deux objets ?
Réponse 1.3.a.1.1 : concentration syntaxique des identificateurs avec contrôle de type
Il faut donc définir un outil d'analyse syntaxique avec contrôle de type. La surcharge est un concept simple dans son principe : si l'on sait déterminer le type des paramètres effectifs, alors on sait aussi sélectionner le bon sous-programme.
Problème 1.3.a.2 : langages à structure de blocs dynamique
Que dire des langages pour lesquels la portée des identificateurs est en partie déterminée dynamiquement ? Par exemple en Lisp :
(de incr ()
(1+ a)
(de fct1 (x)
(let ((a x))
(incr)))
(de fct2 (x)
(let ((a x)))
(incr))
incr : a est une variable libre ;fct1 : a est une variable locale ; la variable libre de incr est liée à cette variable ;fct2 : a est une variable locale ; mais la variable libre de incr est liée à celle de l'environnement global.La grande différence avec un langage comme Pascal est que, dans le cas de Lisp, les identificateurs ne servent pas à nommer d'une façon concise des objets définis "plus haut" mais son bien des symboles à part entière, pour lesquels on déterminera dynamiquement quels objets ils représentent. Dès qu'on parle de généricité, héritage, polymorphisme, on ne peut plus statiquement reconnaître les objets symboliquement nommés.
Réponse 1.3.a.2 : exécution symbolique
Il ne peut y avoir une solution automatique simple. La tâche incombe au programmeur de concentrer, a posteriori, des identificateurs identiques. On se heurte ici à deux problèmes :
- le passage implicite de paramètres,
- le rendu implicite de valeurs, par « effet de bord ».
Déterminer les règles de dépendances sémantiques nécessiterait donc l'exécution symbolique des programmes – par exemple : avec les graphes de flot de données.
Problème 1.3.a.3 : langages à structure faible
Que dire enfin des langages à portée trop large ? Dans un tel langage, on peut utiliser plusieurs fois une même variable alors que les divers emplois de cette variable sont totalement indépendants. Ceci sera dû : aux limitations du langage – pas de mécanisme de masquage des déclarations ; à un souci, bien avouable, de limitation de l'espace mémoire utilisé ; à un souci, non moins avouable, de moindre effort – trouver un nouvel identificateur alors qu'on veut dire exactement la même chose, revenir à la zone des déclarations dans le programme alors qu'on ne s'y trouve pas, ...
Réponse 1.3.a.3 : analyse globale du programme
Là encore, il n'y a pas de solution simple. Il faudrait à nouveau envisager une analyse globale du programme, pour déterminer à quel endroit une variable non seulement est déclarée mais aussi possède une valeur pertinente.
Réponse 1.3.b : concentration des traitements
Il y a d'autres notions qui impliquent des liens sémantiques et ne sont pas de simples identificateurs. La solution de saurait être simple. Il faut en effet comprendre ce que le texte veut dire pour y reconnaître un schéma plus général. L'existence d'un tel outil d'analyse des programmes est bien sûr vivement souhaitable, mais est bien sûr aussi un très vaste sujet d'étude.