1.3 Presentation et organisation des travaux
2.1.2 Notation fonctionnelle des grammaires attribuees
Les grammaires attribuees, habituellement speciees sur des grammaires independantes du contexte, peuvent egalement ^etre vues comme des specications sur des types algebriques. Chirica et Martin [CM76, CM79] ou Ganzinger et Giegerich [Gan80, GG84] ont deja etudie cette representation, plus souple qu'avec des CFGs, dans laquelle les constructeurs de type jouent le r^ole des productions de la CFG. Les terminaux d'une CFG sont alors les variables d'une denition de type algebrique (gure 2.5); en supposant que leur type est un parametre, on obtient alors une representation polymorphique. Pour des raisons historiques de domaine d'application, cette modication du formalisme original n'a pas ete approfondie dans la ma-jorite des etudes sur les grammaires attribuees, mais cela n'entame en rien leur principe et leurs methodes d'evaluation.
An de rapprocher les notations des grammaires attribuees de celles classiquement utilisees
list
=cons
(list
)j
nil
tree
=node
(tree
) (tree
)j
leaf
20 Chapitre 2. Grammaires attribuees dans les programmes fonctionnels, je vais maintenant introduire une nouvelle notation pour les grammaires attribuees. Le principe de cette notation est de voir une production comme un ltrage syntaxique (pattern matching) implicite6. Au lieu d'utiliser des symboles de non-terminaux et de non-terminaux des productions classiques (
p
:X
0!
X
1:::Xn
) qui correspondent aux constructeurs et a leurs parametres du type de donnee represente par la grammaire, j'utilise des noms de variables, comme dans un pattern. Le premier nom apparaissant dans le pattern represente alors le nom du constructeur de type, correspondant au nom de la production, soit p var1:::
varn. Plus concretement, la production de la grammaire des listes cons : L0!e L1 est par exemple utilisee comme dans un pattern fonctionnel: cons head tail ou cons, head et tail sont des variables de type jouant respectivement le r^ole des non-terminaux ou terminaux
L
0,e
etL
1. Une originalite, par rapport aux patterns fonctionnels classiques, qui peut ^etre vue comme une ambigute dans un premier temps est alors de pouvoir utiliser le nom d'un constructeur, representant une production, comme un non-terminal pouvant porter un attribut.La gure 2.5 presente en rappel deux exemples de denitions de types algebriques simples qui sont couramment utilises. Les grammaires attribuees peuvent donc ^etre denies sur de tels types algebriques en ajoutant un
prol
pour chaque grammaire attribuee. Ce prol est une sorte de constructeur particulier qui porte le m^eme nom que la grammaire attribuee. Il permet de palier l'absence de racine (root : Z !:::
) dans les types algebriques et distingue ainsi le premier pattern matching correspondant a l'appel de la grammaire attribuee, speciant son resultat par un attribut particulier note result et tenant le r^ole de l'attributz
classique. Outre ces petites dierences purement syntaxiques, ce prol permet egalement de specier, en plus de l'argument syntaxique correspondant a l'arbre d'entree, des parametres supplementaires pour la grammaire attribuee qui seront alors vus comme des attributs herites en t^ete de l'arbre d'entree. La souplesse de cette notation rapproche les specications de grammaires attribuees de celles des fonctions classiques, sans remettre en cause leurs principes fondamentaux.La syntaxe donnee a la gure 2.6 formalise cette notation fonctionnelle pour les grammaires attribuees. Par sa forme, proche des specications fonctionnelles, elle facilite la comprehension des exemples et l'illustration des techniques que je vais presenter, ainsi que les comparaisons avec les dierents formalismes fonctionnels presentes dans les prochains chapitres. Par ailleurs, elle est equivalente a la notation classique deja presentee et j'utiliserai indieremment l'une ou l'autre de ces notations. En fait, pour tous les resultats classiques des grammaires attribuees, concernant leur methodes d'evaluation ou leurs analyses statiques, la notation utilisant les non-terminaux et leur position dans une production est mieux adaptee pour une presenta-tion simple. En revanche, la specicapresenta-tion des foncpresenta-tions est plus naturelle et plus facilement comprehensible sous la forme de variables de patterns expressives que sur des non-terminaux numerotes d'une grammaire independante du contexte.
Dans la syntaxe de la gure 2.6, une grammaire attribuee
f
est vue comme un bloc conte-nant plusieurs patterns, dont au moins un pour le prol. La notation surligneex
represente un nombre ni d'elements et evite de specier les indicesx
1:::xn
. Chacune des regles se-mantiques est une equation orientee, avec une occurrence d'attributx:a
en partie gauche (eventuellementf:result
pour le prol) et avec en partie droite une expression. Uneexpres-6. Cette idee a deja ete evoquee dans dierents travaux, dont ceux de Johnsson, qui parlait alors de construc-tioncase rec[Joh87].
2.1. Notations et formalismes 21 bloc : : = aglet
f
=ff x
!semrulgfpat !semrulg
semrul : : = occ = exp occ : : =
x:a
jf:
result exp : : = Constantej
y:b
2Occurences d0attributsj
x
2Variablesj
g
expFig. 2.6: Une notation fonctionnelle pour les grammaires attribuees
agletrev = rev
x l
!rev
:
result =x:r
x:
h = lcons head tail !
cons
:
r = tail:
rtail
:
h = cons head cons:
h nil !nil
:
r = nil:
hFig. 2.7: Grammaire attribuee en notation fonctionnelle pour rev
sion est construite a partir de constantes, de variables, d'occurrences d'attributs ou d'appels de fonctions.
Pour illustrer cette notation, la gure 2.7 presente la grammaire attribuee correspondant a la fonction rev qui retourne une liste passee en argument, en utilisant un parametre (
l
) initialisee a nil. Par opposition a la grammaire attribuee classique reverse presentee a la gure 2.3, la valeur nil n'est plus une constante necessairement xee dans la regle semantique initialisant l'attribut heriteh
, mais peut ^etre vue comme un parametre de la grammaire attribuee, comme c'est le cas dans la denition de fonction correspondante. Autrement dit, l'appel de cette grammaire attribuee pour inverser une listex
se fait \a la fonctionnelle" par rev x nil.Avec cette notation, le nom rev represente a la fois le nom de la grammaire attribuee et le nom du constructeur de prol. Cela peut semer la confusion chez le lecteur peu habitue a cette notation, mais ce choix est justie par la necessite de dierencier (resp. identier) les prols des grammaires attribuees dierentes (resp. identiques); par ailleurs, le nom de la grammaire attribuee est plus pertinent que root. Le chapitre 7 traitant d'une transformation de programmes fonctionnels en grammaires attribuees permettra a cette remarque de prendre tout son sens.
De m^eme, les noms des constructeurs (e.g., cons) peuvent ^etre utilises comme tels dans les patterns (e.g., cons head tail), comme des non-terminaux pouvant porter des attributs (e.g., cons
:
r) ou comme des fonctions de construction (e.g., tail:
h = cons head cons:
h). Cette am-bigute est similaire a celle des grammaires attribuees classiques et, si elle semble compliquer les notations, elle est neanmoins tres pratique lors de la specication d'un programme.22 Chapitre 2. Grammaires attribuees
agletlength = length x !
length
:
result = x:
s cons head tail !cons
:
s = succ tail:
s nil !nil
:
s = zeroaglet sumleaves= sumleaves t !
sumleaves
:
result = t:
s node left right !node
:
s = left:
s+ right:
s leaf n !leaf
:
s= nFig. 2.8: Denitions des grammaires attribuees length et sumleaves
Pour familiariser le lecteur avec cette notation, deux autres exemples de grammaires at-tribuees simples sont donnes dans la gure 2.8: la longueur d'une liste length et la somme des feuilles d'un arbre binaire sumleaves.
2.2 Evaluation des grammaires attribuees
Pour une specication de grammaire attribuee donnee, dierentes techniques d'evaluation de leur resultat sur un parametre donne peuvent ^etre employees. Je rappelle brievement quelques-unes de ces techniques a la n de cette section, mais elles sont toutes fondees sur la notion de dependance, que je vais presenter apres avoir deni la notion d'arbre d'entree, fondamentale dans l'evaluation d'une grammaire attribuee.
Comme je l'ai deja dit, la notation fonctionnelle des grammaires attribuees est particulie-rement adaptee pour faciliter la comprehension des exemples et leur comparaison avec les pro-grammes fonctionnels. Cependant, pour les techniques d'evaluations dont traite cette section, je lui prefererai la notation classique utilisant les non-terminaux numerotes de grammaire, mieux adaptee a la presentation de ces notions. Neanmoins, dans les exemples illustratifs, je prefererai les noms de variables, plus intuitifs, aux numeros de non-terminaux (cons, tail ou nil plut^ot que L0, L1 ou L).