3. L'analyse grammaticale avec Yacc
Pour les puristes : Yacc (Yet Another Compiler Compiler) est un programme destiné à compiler une grammaire du type LALR(1) et à produire le texte source d'un analyseur syntaxique du langage engendré par cette grammaire. Il est aussi possible, en plus de la vérification de la syntaxe de la grammaire, de lui faire effectuer des actions sémantiques.
De la même manière que pour un fichier Lex, un fichier Yacc se compose de trois parties, de cette façon :
déclarations %% productions %% code additionnel |
seuls le premier séparateur %% et la deuxième partie étant obligatoires.
3.1. La première partie d'un fichier Yacc
La première partie d'un fichier Yacc peut contenir :
- Des spécifications écrites dans le langage cible, placées entre %{ et %}, ces deux symboles étant obligatoirement en début de ligne.
- La déclaration des terminaux pouvant être rencontrés, grâce au mot-clé %token
- Le type de donnée du terminal courant, avec le mot-clé %union
- Des informations donnant la priorité et l'associativité des opérateurs.
- L'axiome de la grammaire, avec le mot-clé %start (si celui-ci n'est pas précisé, l'axiome de la grammaire est la première production de la deuxième partie).
La variable yylval, déclarée implicitement du type de %union a une importance fondamentale dans le fichier, puisque celle-ci contient la description du dernier terminal lu.
3.2. La deuxième section d'un fichier Yacc
Cette partie, qui ne peut pas être vide, contient :
- des déclarations et/ou définitions encadrées par %{ et %} ;
- des productions de la grammaire du langage choisi.
Ces productions s'écrivent sous la forme générale :
notion_non_terminale:
corps_1 { action_sémantique_1 }
| corps_2 { action_sémantique_2 }
| ...
| corps_n { action_sémantique_n }
;
|
sachant que les corps_i peuvent être des notions terminales ou non terminales du langage.
Et enfin, on trouve...
3.3. La troisième partie d'un fichier Yacc
Cette partie, qui comporte le code additionnel, devra obligatoirement comporter une déclaration du main() (qui devra appeler la fonction yyparse()), et de la fonction yyerror(char *message), appelée lorsqu'une erreur de syntaxe est trouvée.
3.4. Conclusion sur Yacc
Ici aussi, nous sommes loin d'avoir fait le tour de Yacc, et je ne t'ai d'ailleurs pas tout expliqué. Nous allons préciser certains points dans l'exemple qui va suivre.