:: Enseignements :: ESIPE :: E4INFO :: 2007-2008 :: Compilation ::
[LOGO]

Petit langage de redéfinition d'opérateurs


Le but de ce projet est d'implémenter un compilateur d'un petit langage manipulant des classes Java et permettant la redéfinition d'opérateurs sur ces classes. Ce compilateur générera du Bytecode.

Présentation

Le but de ce projet est d'implémenter un compilateur d'un petit langage manipulant des classes Java et permettant la redéfinition d'opérateurs sur ces classes. Ce compilateur générera du Bytecode.
			import Matrix;
				
			Matrix a = Matrix();
			Matrix b = Matrix();
			Matrix c;
			c = a + b; #addition de deux matrices
			print c;
			
Par exemple, le code ci-dessus permet de faire la somme de deux matrices. Le type Matrix est une classe Java importée. L'opérateur + fait référence à une méthode add de la classe Matrix. La fonction print est une fonction d'affichage pré-définie dans le langage. Le texte précédé du symbole # est un commentaire.
Ce projet contient 5 niveaux différents de difficulté.

Niveau 1

Dans ce premier niveau, les types de base sont les entiers (int) et les booléens (bool). Le langage autorise les opérations arithmétiques +, -, * et / et l' opération booléenne not. Il permet l'importation de classes Java et l'utilisation de leurs méthodes. Il existe une fonction prédéfinie d'affichage print qui fait appel à la méthode System.out.println. Les instructions conditionnelles sont également autorisées au moyen de l'instruction if ... then...else...fi. Pour comparer deux variables, on utilise les symboles == pour tester l'égalité et != pour l'inégalité. Dans ce premier niveau, le language ne permet pas de redéfinir des opérations. Un commentaire est un texte sur une ligne précédé du symbole #. La définition de fonction est également possible à l'aide du mot clé function. L'exemple ci-dessous illustre la syntaxe et les différentes instructions possibles pour ce niveau :

			import Point;
			
			Point p = Point(1,2);
			int x = p.getX();
			int y = p.getY();
			bool b = true;
			
			function int diff(int x, int y)
			   int z = x + y;
			   return z * y;
			end
			    
						
			if diff(x,y) == 0 then
			   print not b; 
			else
			   print p; # on affiche le point
			fi		
		
La classe Point est définie ci-dessous:

Niveau 2

Le langage autorise maintenant le type réel (float). Les tests d'égalité se font dorénavant à l'aide de la méthode equals pour les classes importées. La redéfinition des opérateurs +, -, *, ^ pour les classes importées est maintenant autorisée. Le principe est le suivant : les classes dont on souhaite redéfinir des opérateurs doivent implémenter une méthode statique associée à chaque opérateur : plus pour +, minus pour -, mult pour * et exp pour ^ ; à chaque fois que l'on utilise ces opérateurs dans notre langage, ce sont les méthodes correspondantes qui sont appelées.
			import Complexe;
			
			Complexe c1 = Complexe(1.0,2.0);
			Complexe c2 = Complexe(1.0,3.7);
			Complexe c3 = c1 - c2; # appelle la méthode statique minus de Complexe
			
			if c3 == c2 then
			   print c3;
			fi
			
		
Les boucles foreach sont également permises. L'exemple suivant montre leur syntaxe :
			import Complexe;
			import java.util.ArrayList;

			function ArrayList liste()
			  ArrayList list = ArrayList();
			  list.add(Complexe(8,8));
			  list.add(Complexe(10,10));
			  return list;
			end

			Complexe y;
			foreach y in liste() do
			  print y;
			done
			
Le code ci-dessus permet d'afficher une liste de complexes. Le comportement de la boucle est équivalent au code Java suivant où l'on suppose que liste() renvoie une ArrayList de nombres complexes.
			Iterator it = liste().iterator();
			while(it.hasNext()){
			   Complexe y = (Complexe)it.next();
			   System.out.println(y);
			 }			
		

Niveau 3

  • Le type string doit être géré, ainsi que les diverses opérations sur ce type (assignation, concaténation (+), répétition(*))
  • Les redéfinitions des opérateurs peuvent maintenant être faites dans le petit langage.
    			redefine Matrix.+ toto;
    					
    L'instruction ci-dessus indique que l'opérateur + pour la classe Matrix est redéfinie pour la fonction toto du petit langage.
    Remarque : en cas de conflit, ce type de redéfinition est plus prioritaire que celle du niveau 2.
  • Dans les boucles foreach, il sera possible d'avoir le code ci-dessous :
    				foreach Complexe  y in liste() do
    					print y;
    				done
    					

Niveau 4

L'héritage des classes devra être géré. Pour cela, vous utiliserez un graphe représentant l'héritage entre les classes. Par exemple, en cas d'opération entre deux instances de deux types différents, le compilateur cherchera le type commun par relation d'héritage dans ce graphe. Il appelera la méthode associée à l'opération. S'il ne le trouve pas, un message d'erreur sera affiché.
			import X;
			import Y;
						
			X x = X();
			Y y = Y();
			print x + y;
					
Dans le code ci-dessus, si les classes X et Y héritent d'une même classe Z, alors la méthode plus de cette classe sera appelée pour effectuer l'opération +.

Niveau 5

On autorise la redéfinition de n'importe quoi dans le petit langage sauf redefine.

Bonus

Le compilateur génèrera aussi de l'ASM Intel.

Résumé

Vous trouverez ici un résumé des points importants du projet.
Les codes suivant (exemple_niveau1_1.txt et exemple_niveau1_2.txt) sont des exemples supplémentaires de codes du niveau 1.
Pour vous aider à personnaliser votre gestion d'erreurs lors de l'analyse lexicale et de l'analyse syntaxique, voici le code modifié de la classe BooleanExprMain du td7.

Rendu

Votre projet devra être envoyé à Julien Cervelle, Matthieu Constant et Gautier Loyauté avant le 25 février 23h59. Votre rendu sera une archive qui contiendra tout ce qui est nécessaire pour compiler et exécuter votre projet.