:: Enseignements :: ESIPE :: E4INFO :: 2011-2012 :: Génération de code ::
[LOGO]

Langset - Correction


L'objectif de ce TD est d'implanter une grammaire pour un langage exprimant des ensembles d'entiers et ensuite d'évaluer des expressions exprimées à l'aide de ce langage.

Présentation du langage Langset

Le langage Langset permet d'exprimer des ensembles d'entiers ; voici quelques exemples d'opérations sur les ensembles utilisant Langset :
  • 1 représente l'ensemble à un élément {1}.
  • 1 + 2 + 3 + 5 + 8 + 5 permet d'exprimer l'ensemble des entiers {1, 2, 3, 5, 8} (on rappelle qu'un ensemble ne contient au plus qu'un exemplaire d'un élément) : + est l'opérateur d'union d'ensembles.
  • 1 + 2 * 2 + 4 représente l'intersection des ensembles {1, 2} et {2,4} soit l'ensemble {2} : * est l'opérateur d'intersection d'ensembles
  • 1 + 2 + 3 - 1 + 2 représente l'ensemble {1, 2, 3} privé des éléments de l'ensemble {1, 2} : - est l'opérateur de soustraction d'ensemble.

Préparation du projet

On se rapportera aux consignes du TD 0 préliminaire pour la préparation d'un projet utilisant Tatoo. Les sources de ce projet seront situées dans le paquetage fr.upemlv.langset et le projet sera nommé Langset.

Fichier EBNF et construction des tables des automates

La première étape est d'exprimer le lexique (tokens) et la grammaire de Langset dans le fichier grammar.ebnf. On exprimera pour l'instant les tokens entier et l'opérateur d'union + dans le lexique. Nous écrivons les règles de la grammaire afin de supporter des expressions composée d'un entier (ensemble singleton) ou d'une union de deux ensembles. On ne se préoccupe pas pour l'instant de la priorité et de l'associativité de l'opérateur d'union.

Analyse lexicale

On écrit maintenant un analyseur lexical (LangsetLexer) décomposant une expression Langset en une suite de lexèmes. L'expression est fournie sur l'entrée standard ou dans un fichier et l'on retourne sur la sortie standard la suite des lexèmes (un lexème par ligne).

On implante un LexerListener réalisant ce travail d'écriture de lexèmes : pour chaque lexème on indique son type (entier, opérateur +, -, *...) ainsi que sa valeur textuelle et si possible sa localisation dans le code . Il faudra implanter la méthode de signature void ruleVerified(LangsetRuleEnum rule, int lastTokenLength, B buffer) (l'argument lastTokenLength ne sert à rien ici).

Une fois l'implantation et la compilation réalisée avec la règle Ant ad-hoc, on teste l'analyseur sur quelques entrées valides (exemple : 1 + 2 * 4) mais également invalides (exemple : 1.2 + a - 3).

Évaluateur

On souhaite maintenant évaluer les expressions représentant des ensembles dans une classe LangsetEvaluator. On initialise à cet effet un analyseur syntaxique lisant l'entrée standard ou un fichier et retournant l'expression évaluée. On lui fournit une implantation de ToolsListener avec quatre méthodes à implanter :
  • comment() appelée lors qu'un commentaire est reconnu ;
  • shift() appelée lorsqu'un décalagage (lecture de token) est effectué ;
  • reduce() appelée lors qu'une réduction est réalisée ;
  • accept() appelée lorsque le texte en entrée est accepté par l'analyseur.
Nous utiliserons à cet effet une pile d'ensembles d'entiers (Stack<Set<Integer>>). Lors d'un shift d'un entier, nous pouvons empiler un ensemble singleton de cet entier ; lors d'une réduction sur une opération binaire, nous pouvons dépiler les deux ensembles en haut de pile, réaliser l'opération et réempiler son résultat.



Une archive avec une proposition de correction peut être trouvée ici