[UMLV]

Sablecc et évaluation d'expressions

Exercice 1 - Grammaire simplifiée d'évaluateur d'expression

Voici un exemple d'utilisation d'un petit évaluateur d'expressions très simples. Les lignes sont saisies, puis chacune d'elle est « évaluée » et son résultat est affiché.

Par exemple, si les lignes suivantes sont saisies :

a=2+3
b=a+2
c=3*a
d=3+2*3
a=4
b
Le résultat suivant est affiché :
5
7
15
9
4
6
Les troisièmes et sixièmes lignes peuvent paraître curieuses. La dernière valeur 6 vient du fait que, lors de la dernière évaluation de b, c'est a+2 qui est évalué avec 4 pour valeur de a. Il y a ré-évaluation de l'expression qui défini une variable à chacune de ses interprétations.

Les expressions utilisées dans cet exemple permettent de réaliser des opérations arithmétiques simples (+, -, *, /) et des affectations (=) ; dans tous les cas, le résultat de l'expression est affiché.

L'outil sablecc permet de produire, à partir d'une grammaire comme celle donnée ci-dessous, de générer un analyseur lexical (lexer) et un analyseur synatxique (parser). On peut spécifier le package de destination de toutes les classes générées par sablecc au début de la grammaire.

Package fr.umlv.sableccexample;

Tokens
 number = ['0'..'9']+;
 plus =    '+'; 
 minus =   '-';
 mult =    '*';
 div =     '/';
 l_par =    '(';
 r_par =    ')';
 blank =   (' ' | 10 | 13 | 9)+;

Ignored Tokens
 blank;

Productions
 expr = 
	{term}   term |
	{plus}   expr plus term |
	{minus}  expr minus term 
	;
 term = 
	{factor}  factor |
	{mult}    term mult factor |
	{div}	  term div factor
	;
 factor =
	{number}   number |
	{paren}    l_par expr r_par 
	;

  1. Cette grammaire ne permet pas d'utiliser des variables, ne décrit pas l'affectation et est limitée à une seule ligne d'évaluation. Modifier cette grammaire afin qu'elle accepte l'exemple du haut de page.
  2. Afin de vérifier qu'elle est correcte, lancer sablecc sur cette grammaire. Il est important de bien supprimer les anciens fichiers générés lorsqu'on relance une nouvelle fois sablecc.

Exercice 2 - Arbres des expressions

Avant d'utiliser les classes générées par sablecc, nous allons préciser les types de la hiérarchie dont nous aurons besoin pour représenter les expressions. Récupérer les classes Expr.java et Operations.java.

La classe Expr définit le type général de toute expression. Outre le type énuméré des opérateurs, la classe Operations définit des méthodes statiques permettant de construire chaque type d'expressions. En réalité, elle permet de construire des opérateurs binaires et des nombres, mais pas de variables ni d'affectations.

  1. Après avoir réfléchi d'une part à la notion de « portée»  (scope) et à la façon de l'implémenter et d'autre part à la manière d'associer un nom de variable à l'« arbre»  d'expression qu'il représente, compléter la classe Operations avec des méthodes variable() et assign() permettant de construire les expressions correspondantes. Vous aurez probablement besoin d'ajouter une nouvelle classe.
  2. Avec ces classes complétées, construisez « à la main»  des objets de type Expr représentant chacune des lignes du premier exemple du haut de cette page, et évaluez les.

Exercice 3 - Construction et utilisation de l'AST

  1. Supprimez tous les fichiers déjà générés par sablecc.
  2. Récupérez le fichier example.grammar, et relancer sablecc avec cette version. Des fichiers java sont générés dans quatre packages.
  3. Récupérez le fichier Main.java, et compléter la classe SimpleInterpret.java qui permet de réaliser l'évaluation souhaitée.