

/* ANALYSE DES EXPRESSIONS ARITHMETIQUES CLASSIQUES */


/* variation sur les regles terminales */

/*======================================================================*/

/* Primo : en Completement Parenthesee  et en  Prefixee */
/* Grammaires analysables de maniere descendante !!! */
/* Pour la postfixee et la notation a precedences, c'est plus dur. */

/* Appel par exp("chose", []). On traite donc une liste de codes ASCII ... */
/* ascii('(') = 40 ')' = 41 '+' = 43  'x' = 120 */

/* Pour les deux :  Op -> +|* , Var -> x|y|z */

opr(42). 	/* * */
opr(43). 	/* + */

variable(120).	/* x */
variable(121).	/* y */
variable(122).	/* z */

/* Prefixee : E -> Op E E, E -> Var */

expref([Op |X], Y) :- opr(Op), expref(X, X1), expref(X1, Y).
expref([V | X], X) :- variable(V).

/* Completement parenthese : E -> (E Op E) , E -> Var */

parouv(40).
parfer(41).

expcp([P | X], Y) :- parouv(P),
	     expcp(X, [Op | X1]), opr(Op), expcp(X1, [Q | Y]), 
	     parfer(Q).
expcp([V | X], X) :- variable(V).

/* EXERCICE : analyser sur ce modele la notation  incompletement parenthesee
   a deux operateurs + et *, AVEC ASSOCIATION A DROITE
   E -> T + E, E -> T, T -> F * T, F -> ( E ), F -> Var */


/*========================================================================*/

/* Secundo : Traitement d'une grammaire recursive a gauche : la postfixee */

/* E -> E E Op, E -> Var  recursive a gauche se transforme en
   E -> Var S, E -> Var, S -> E Op S, S -> E Op */

expost([V | X], Y) :- variable(V), suite(X, Y).
expost([V | X], X) :- variable(V).

suite(X, Y) :- expost(X, [Op | X1]), opr(Op), suite(X1, Y).
suite(X, Y) :- expost(X, [Op | Y]), opr(Op).

/* Dans le meme esprit, la notation a precedences classique, 
	AVEC ASSOCIATION A GAUCHE */

/* E -> E Op T, E -> T,  T -> ( E ), T -> Var  
   recursive a gauche se transforme en
   E -> T S, E -> T, S -> Op T S, S -> Op T, T -> ( E ), T -> Var */

expclas(X, Y) :- terme(X, X1), sclas(X1, Y).
expclas(X, Y) :- terme(X, Y).

sclas([Op | X], Y) :- opr(Op), terme(X, X1), sclas(X1, Y).
sclas([Op | X], Y) :- opr(Op), terme(X, Y).

terme([P | X], Y) :- parouv(P), expclas(X, [Q | Y]), parfer(Q).
terme([V | X], X) :- variable(V).

