Génération et auto-génération d’analyseurs syntaxiques |
Une page de suivie sera fournie, qui sera complétée au fur et à mesure des questions.
Il s’agit de programmer une version simplifiée du programme yacc (yet another compiler’s compiler). Il s’agit d’un utilitaire d’analyse syntaxique. Une originalité du sujet est que ce programme génère lui-même des programmes.
Comme cela sera traité lors de l’amphi 14 du cours, un analyseur syntaxique, ou parseur est un programme qui:
La forme de la structure attendue est donnée par une grammaire.
Un générateur de parseurs est un programme qui va fabriquer un autre programme. Pour cela, il va prendre en entrée une grammaire annotée, c’est-à-dire, en première approximation:
A partir de cette grammaire annotée, le générateur fabriquera le parseur. C’est-à-dire qu’il fabriquera un fichier contenant le code source du programme qui implémente la grammaire annotée.
Voici une grammaire annotée pour une calculette 4 opérations simple. J’ai repris volontairement l’exemple de l’amphi 5:
expr ::= prod '+ expr -> { $1 + $3 } | prod '- expr -> { $1 - $3 } | prod -> { $1 } ;; prod ::= fun '* prod -> { $1 * $3 } | fun '/ prod -> { $1 / $3 } | fun -> { $1 } ;; fun ::= int -> { $1 } | '( expr ') -> { $2 } ;;
On appelle expr, prod et fun les ées de la grammaire. Elles sont composées respectivement de 3, 3 et 2 règles séparées par le signe "|".
Dans chaque règle, on trouve à gauche du "->" la description de la syntaxe
correspondante. À droite on trouve entre accolades un petit bout de
programme java qui décrit ce qu’il faut faire avec l’expression
parsée. Ces bouts de programme sont les actions de la grammaire.
Dans ces actions, $1
désigne la première composante de
la règle de grammaire, $2
la deuxième, etc…
Je fournirai un début d’analyseur syntaxique pour la calculette. C’est-à-dire que ce programme, une fois achevé, prendra en entrée une chaine de caractères (comme (” 1+2*2 ") et rendra le résultat (dans ce cas, 5). Ce début de programme donnera une bonne idée du fonctionnement de l’analyseur.
Le premier travail sera de terminer ce programme.
Le deuxième travail demandé est donc d’écrire un générateur de parseurs. C’est-à-dire un programme qui à partir d’une grammaire annotée engendrera un programme java exécutable correspondant à cette grammaire (par exemple fournira le programme de la question 1 à partir de la grammaire ci-dessus.
}
par
}}
, }}
par }}}
, etc.Pour construire le programme demandé, il est utile de remarquer que ce programme demandé effectue lui-même une analyse syntaxique; plus précisément il analyse la description d’une grammaire. En d’autres termes: il existe une grammaire des descriptions de grammaire.
Il est fortement recommandé de construire cette grammaire des grammaires sur papier avant de commencer l’écriture du programme. Ce n’est pas très difficile et vous simplifiera la tâche. Surtout, ce travail est de toute façon nécessaire pour la question suivante.
Appelons Zacc le programme écrit dans la question précédente. Ce programme écrit est donc un programme qui analyse une grammaire pour fabriquer un (autre) programme d’analyse syntaxique. Il s’agit ensuite de réussir à ce que ce programme s’engendre lui-même !
Pour cela il suffit de:
Si votre programme Zacc est correct, il doit alors produire un programme Zacc’ à peu près identique à Zacc et surtout équivalent. C’est-à-dire que Zacc’, si on lui passe la même grammaire annotée rendra une nouvelle copie de lui même en résultat.
La possibilité pour un programme de s’engendrer lui-même est habituelle en compilation. Par exemple, un compilateur (C, java, caml…) sera souvent lui-même écrit en C, java ou caml. En anglais on appelle cela le bootstrap, puisque tout se passe comme si on pouvait décoller en tirer sur la languette de ses propres bottes !
En pratique, dans le cas des compilateurs, la première version doit, bien sûr, avoir été écrite dans un autre langage.
Par ailleurs, le bootstrap est, comme dans ce sujet, une bonne manière de vérifier la correction du programme écrit.
Yacc.
Un exemple en français ici.
This document was translated from LATEX by HEVEA.