voici un petit bout de parser pour l'outil java cup (partie expressions) :
Code :
- terminal TOK_MINUS;
- terminal TOK_PLUS;
- terminal TOK_DIV;
- terminal TOK_TIMES;
- non terminal Expression expression;
- precedence left TOK_MINUS;
- precedence left TOK_PLUS;
- precedence left TOK_DIV;
- precedence left TOK_TIMES;
- expression ::= TOK_PO expression:e TOK_PC {: RESULT = e; :}
- | expression:e1 TOK_PLUS expression:e2 {: RESULT = new BinaryPlus(e1, e2); :}
- | expression:e1 TOK_MINUS expression:e2 {: RESULT = new BinaryMinus(e1, e2); :}
- | expression:e1 TOK_TIMES expression:e2 {: RESULT = new BinaryTimes(e1, e2); :}
- | expression:e1 TOK_DIV expression:e2 {: RESULT = new BinaryDiv(e1, e2); :}
- | literal:lit {: RESULT = lit; :}
- | identifier:i {: RESULT = i; :}
- | func_call:fc {: RESULT = fc; :};
|
Ce code fonctionne et les opérateurs + * / - sont biens associatifs à gauche (avec les priorités dans le bon sens).
Le code suivant :
Code :
- terminal TOK_MINUS;
- terminal TOK_PLUS;
- terminal TOK_DIV;
- terminal TOK_TIMES;
- non terminal Expression expression;
- non terminal BinaryOperatorFactory bin_op;
- precedence left TOK_MINUS;
- precedence left TOK_PLUS;
- precedence left TOK_DIV;
- precedence left TOK_TIMES;
- precedence left bin_op;
- expression ::= TOK_PO expression:e TOK_PC {: RESULT = e; :}
- | expression:e1 bin_op:fact expression:e2 {: RESULT = fact.createOperator(e1, e2) :}
- | literal:lit {: RESULT = lit; :}
- | identifier:i {: RESULT = i; :}
- | func_call:fc {: RESULT = fc; :};
- bin_op := TOK_MINUS {: RESULT = BinaryMinus.factory(); :}
- | TOK_PLUS {: RESULT = BinaryPlus.factory(); :}
- | TOK_DIV {: RESULT = BinaryDiv.factory(); :}
- | TOK_TIMES {: RESULT = BinaryTimes.factory(); :};
|
Dans ce code, tout le monde est associatif avec tout le monde à droite (gros énervé du décalage quoi).
Quelqu'un pourrrait m'expliquer finement le fonctionnement de la chose et la raison profonde de cette différence ?