Langages et grammaires algébriques: résumé

publicité
Langages et grammaires algébriques: résumé
Licence info S5
Cours COMPIL – 2012 - 2013
Le but de ce cours est de présenter les outils pour l’analyse syntaxique : les langages algébriques,
décrits par des grammaires algébriques. À l’issue de l’UE, vous devriez être capable de concevoir une
grammaire algébrique pour un dsl et d’utiliser divers générateurs automatiques.
1
But de l’analyse syntaxique
Comme vu en cours d’introduction, l’analyseur syntaxique récupère en entrée le flot de symboles produit par l’analyseur lexical. L’analyseur syntaxique connaı̂t la structure des textes corrects, et reconnaı̂t
la structure du flot de symbole (ou le rejette si le mot d’entrée est incorrect). Cette structure apparaı̂t
sous la forme d’un arbre, appelé arbre syntaxique. Exemple :
programme
PROGRAM
IDENT(”pgm”)
FININSTR
DECL →
IDENT(”x”)
SEP
IDENT(”y”) FININSTR
listeDeclarations
listeInstructions
declaration
type
DECLINT
listeIdent
IDENT
SEP
listeIdent
IDENT
On commence par expliquer pourquoi les langages réguliers ne permettent pas de faire une analyse
syntaxique.
2
Limite des langages réguliers
L’exemple typique est celui des parenthèses imbriquées : il suffit de penser aux accolades ou parenthèses
ouvrantes et fermantes de Java. On peut considérer le langage
{an bn |n ≥ 0}
dans lequel a joue le rôle de parenthèse ouvrante et b de parenthèse fermante. Si on n’arrive déjà pas à
décrire ce langage, on n’arrivera pas non plus à décrire Java.
Il se trouve que {an bn |n ≥ 0} n’est pas un langage régulier. En effet, pour le reconnaı̂tre, il faut
mémoriser un nombre non borné de a et de b (pour vérifier qu’il y a autant de b que de a). Or les AFND
qui reconnaissent les langages réguliers ont une ”mémoire” finie (leur nombre fini d’état jouant le rôle de
”mémoire”).
3
Les langages et grammaires algébriques
La première notion abordée est celle de grammaire algébrique, que nous pratiquerons dès le TP3.
3.1
Les grammaires algébriques
Voici un exemple de grammaire algébrique :
phrase → sujet verbe complement
sujet → JE | IL
verbe → JOUE | TRAVAILLE
complement → AVECLECHAT | SURLORDINATEUR
Cours COMPIL
Langages et grammaires algébriques: résumé
Cette grammaire est constituée de 7 productions. ”phrase → sujet verbe complement” est une production qui indique qu’une phrase est un sujet suivi d’un verbe suivi d’un complément. ”verbe → JOUE
| TRAVAILLE” est en fait 2 productions de même membre gauche, qui indiquent qu’un verbe est soit
JOUE, soit TRAVAILLE (le symbole | joue donc le rôle de choix, comme dans les expressions régulières).
L’axiome (le point de départ) de cette grammaire est phrase. Le vocabulaire terminal (l’ensemble
des terminaux) est constitué des symboles { JE, IL, JOUE, TRAVAILLE, AVECLECHAT, SURLORDINATEUR}, c’est à dire que les mots engendrés par cette grammaire seront des suites de ces symboles.
Le vocabulaire non-terminal (l’ensemble des non-terminaux) est constitué des symboles {phrase, sujet,
verbe, complement}.
3.2
Langage engendré, dérivations
Pour engendrer un mot à partir d’une grammaire algébrique, on part de l’axiome, et on procède par
récritures successives jusqu’à avoir complètement éliminé les non-terminaux (comme leur nom l’indique,
on a terminé quand on se retrouve avec uniquement des terminaux). On dit qu’on effectue des dérivations.
Exemple :
phrase ⇒ sujet verbe complement ⇒ sujet TRAVAILLE complement ⇒ IL TRAVAILLE complement
⇒ IL TRAVAILLE AVECLECHAT
est une suite de dérivations directes qui part de l’axiome, et permet d’engendrer le mot IL TRAVAILLE
AVECLE CHAT.
Effectuer une dérivation directe consiste à choisir un non-terminal et une règle dans laquelle ce nonterminal apparaı̂t en partie gauche. Ensuite on remplace le non-terminal par la partie droite de la règle.
Comme on choisit le non-terminal et la production, plusieurs choix sont possibles. On peut ainsi dériver
le même mot avec la suite de dérivations :
phrase ⇒ sujet verbe complement ⇒ IL verbe complement ⇒ IL TRAVAILLE complement ⇒ IL
TRAVAILLE AVECLECHAT
On peut aussi dériver les mots JE TRAVAILLE AVECLECHAT, JE TRAVAILLE SURLORDINATEUR
et IL TRAVAILLE SURLORDINATEUR.
Sans surprise, le langage engendré par une grammaire est l’ensemble des mots composés des terminaux
qu’on peut dériver à partir de l’axiome.
3.3
Langages algébriques, comparaison avec les réguliers
Les langages engendrés par les grammaires algébriques sont appelés langages algébriques.
Les langages réguliers sont inclus dans les langages algébriques. Donc tout langage régulier est aussi
algébrique, mais l’inverse n’est pas vrai (cf {an bn |n ≥ 0} qui est algébrique mais pas régulier). En
conséquence, tout langage qu’on peut décrire par une expression régulière peut aussi être décrit par une
grammaire algébrique.
3.4
Outils pour l’analyse syntaxique
On parle souvent de ”parseur” au lieu d’analyseur syntaxique. Reconnaı̂tre un texte se dit alors
”parser”.
Un générateur d’analyseur syntaxique est un logiciel qui prend en entrée une grammaire algébrique et
qui produit en sortie un module d’analyse syntaxique (un autre logiciel) correspondant à cette grammaire.
Nous verrons deux générateurs en TP : Cup et antLR, qui utilisent des techniques de parsing différentes.
4
Arbres syntaxiques
La figure 1 montre un arbre syntaxique pour le mot : IL TRAVAILLE AVECLECHAT.
On constate que les 2 dérivations données plus haut pour ce mot permettent de construire cet arbre.
Dans le cas de cette grammaire, ce mot admet un seul arbre syntaxique, qui fixe son interprétation.
Cours COMPIL
Langages et grammaires algébriques: résumé
phrase
sujet
verbe
IL
complement
TRAVAILLE AVECLECHAT
Figure 1 – Un arbre syntaxique
Voici une autre grammaire qui engendre des expressions arithmétiques construites sur les terminaux
{id, +, *, (, )} :
E → E + E | E * E | ( E ) | id
Le mot id * id + id admet deux arbres syntaxiques (donc 2 interprétations), correspondant à 2 dérivations
différentes, cf figure 2.
(1) E ⇒ E * E ⇒ E * E + E ⇒∗ id * id + id
(2) E ⇒ E + E ⇒ E * E + E ⇒∗ id * id + id
E
(1)
E
(2)
E
E
E
id
*
id
E
E
+
E
id
id
E
E
*
id
+
id
Figure 2 – Un mot admettant 2 arbres syntaxiques
5
Grammaires ”pathologiques”
Quand on donne une grammaire algébrique à un générateur de parseur, plusieurs cas sont possibles :
– génération de code sans warning (cas favorable) ;
– rejet de la grammaire car elle ne convient pas à l’algorithme de parsing de l’outil (cas qu’on verra
plus tard, pas facile) ;
– génération de code avec warning : il faut bien comprendre le message car ce n’est pas bon signe ;
– rejet de la grammaire pour une autre raison : il faut comprendre pourquoi la grammaire est pathologique.
On s’intéresse ici aux 2 derniers cas : grammaires pathologiques car contenant des productions qui ne
servent pas (cas du warning) et grammaire ambiguës qui admettent plusieurs interprétations pour un
mot et sont cause de non déterminisme (cas du rejet).
5.1
Ambiguı̈té
Le mot de la figure 2 est ambigü car il admet plusieurs arbres syntaxiques, donc plusieurs interprétations. Pour faire simple, le générateur de parseur ne sait pas quel code générer pour prévoir
la reconnaissance d’un tel mot. Une grammaire dite ambiguë, qui engendre au moins un mot ambigü,
sera donc rejetée par le générateur.
Quand une grammaire est ambiguë, il n’y a plus qu’à la retravailler pour obtenir une grammaire
équivalente (= qui engendre le même langage) et qui n’est pas ambiguë. Parfois on a juste une grammaire
mal fichue, il suffit de réfléchir un peu (mais ce n’est pas si simple quand on n’a pas d’expérience).
Cours COMPIL
5.1.1
Langages et grammaires algébriques: résumé
Le cas des grammaires à opérateurs
C’est un cas bien connu qu’on sait ”désambiguer”. Cette grammaire à opérateurs présente des productions récursives et symétriques (par rapport aux opérateurs) qui conduisent fatalement à une ambiguı̈té.
E → E + E | E * E | ( E ) | id
Le problème est double :
– l’associativité des opérateurs binaires n’est pas spécifiée. Le mot id + id + id admet 2 arbres
syntaxiques correspondant à un associativité gauche ou droite de l’opérateur + ;
– la priorité des opérateurs n’est pas spécifiée, les 2 interprétations du mot id * id + id données
figure 2 correspondent à un opérateur + prioritaire sur *, ou à l’inverse.
Il suffit d’intégrer ces informations de priorité et d’associativité dans une nouvelle grammaire plus structurée, en suivant la recette suivante :
– on ajoute un non terminal par niveau de priorité (S pour somme - +, P pour produit - *, F pour
facteur, etc) ;
– les moins prioritaires en haut de l’arbre, proches de l’axiome ;
– les plus prioritaires en bas de l’arbre, proches des feuilles ;
– les atomes tout en bas ;
– associativité gauche/droite ⇒ récursivité gauche/droite.
On obtient pour notre exemple (d’axiome S) :
S→S+P | P
P →P *F | F
F → ( S ) | id
La grammaire obtenue est nettement moins lisible. Des outils comme Cup automatisent la transformation
de la grammaire : on donne à l’outil une grammaire ambiguë et des indications d’associativité et de
priorité, et il génère par derrière la version non ambiguë. L’outil antLR ne le fait pas, il faut lui donner
directement une grammaire non ambiguë.
5.2
Les grammaires dont des productions ne servent à rien
Ces grammaires contiennent :
– des non-terminaux improductifs qui, même s’ils sont membre gauches de production, ne permettent
pas d’engendrer un mot ;
– des non-terminaux inaccessibles qu’on ne voit jamais apparaı̂tre dans une dérivation issue de
l’axiome.
Il s’ensuit que toute une partie de la grammaire ne sert à rien alors que ce n’était pas l’intention de celui
qui l’a écrite ! Le message d’erreur des outils n’étant pas toujours des plus clairs, il faut savoir détecter
les improductifs et les inaccessibles, et savoir réparer sa grammaire en conséquence.
6
Les algébriques. . . et les autres
On a vu que les algébriques contiennent les réguliers. Mais tous les langages ne sont pas algébriques.
L’exemple type est le langage {an bn cn | n ≥ 0}, qu’on ne peut pas décrire par une grammaire algébrique.
Noam Chomsky a introduit dans sa célèbre classification d’autres grammaires plus générales que les
algébriques :
régulière ⊂ algébrique ⊂ contextuelle ⊂ quelconque
Téléchargement