2009-09-21 9 views
3

J'essaie d'implémenter une grammaire de gestion d'expression (qui traite les parenthèses imbriquées et autres). J'ai ce qui suit jusqu'à présent, mais ils ne peuvent pas traiter certains cas (les cas de réussite/échec apparaissent après le bloc de code suivant). Quelqu'un sait ce qu'il se passe?ANTLR Grammaire pour les expressions

Note: Le varname + = et varname = choses ne sont que des trucs d'aide supplémentaire de génération AST dans XText. Ne vous inquiétez pas pour eux pour le moment.

... 

NilExpression returns Expression: 
    'nil'; 

FalseExpression returns Expression: 
    'false'; 

TrueExpression returns Expression: 
    'true'; 

NumberExpression returns Expression: 
    value=Number; 

StringExpression returns Expression: 
    value=STRING; //EllipsesExpression: '...'; 
//FunctionExpression: function=function; //don't allow random functions 


UnaryExpression: 
    op=unop ('(' expr=Expression ')')|expr=Expression; 

BinaryExpression: 
    'or'? AndOp; //or op 

AndOp: 
    'and'? ComparisonOp; 

ComparisonOp: 
    ('>'|'<'|'>='|'<='|'=='|'~=')? ConcatOp; 

ConcatOp: 
    '..'? AddSubOp; 

AddSubOp: 
    ('+' '-')? MultDivOp; 

MultDivOp: 
    ('*' '/')? ExpOp; 

ExpOp: 
    '^'? (('(' expr=Expression ')')|expr=Expression); 

ExprSideOne : Variable|NilExpression|FalseExpression|TrueExpression| 
    NumberExpression|StringExpression|UnaryExpression; 

Expression: 
    ( 
    '(' 
    expression1=ExprSideOne expression2+=BinaryExpression* 
    ')' 
) 
    | 
    (expression1=ExprSideOne expression2+=BinaryExpression*) 
; 
... 

Et voici la liste des Parsis/échoue:

c = ((b)); //fails 
c = ((a not b)); //fails 
c = b; //parses 
d = (b); //parses 
+0

Besoin de récurrence. Par pure curiosité, pourquoi vos règles d'opérateur binaire sont-elles écrites comme des opérateurs unaires? Est-ce que nil> = .. + * (1) est censé signifier quelque chose? –

Répondre

4

Qu'est-ce qui se passe est que votre expression/expressions entre parenthèses support unique, mais pas plusieurs parenthèses (comme vous concluez). Je n'ai pas d'expérience spécifique à ANTLR mais j'ai travaillé avec Javacc qui partage de nombreux concepts similaires (j'ai écrit une grammaire pour Prolog ... ne demandez pas).

Pour gérer des parenthèses imbriquées, vous avez généralement quelque chose de similaire à:

ParenthesisExpression: '(' (ParenthesisExpression | Expression) ')'; 

Cela signifie que l'expression est soit enveloppé entre parenthèses ou il est juste une expression brute. En ce qui concerne la façon dont l'AST traite de cela, une Expression Parenthesis 'est une Expression, donc elle peut être représentée comme une sous-classe ou une implémentation de (si Expression est une sorte d'interface/classe abstraite).

+0

En outre, vous devrez peut-être aussi gérer ce cas: ((a) not (b ou (c))), donc vous vous amuserez à faire en sorte que votre Expression puisse aussi revenir à une expression Parenthesis. – Malaxeur

+0

Cela ne forcerait-il pas un()? Autour de (ParenthesisExpression | Expression) vous avez une paire de (...) s. – jameszhao00

+0

Désolé je voulais dire le '(' ')' autour de votre truc, pas le() :) – jameszhao00

1

Faire usage du ^ placé après le nom de jeton/règle est très utile pour définir des expressions.

expression : e1 (OR^ e1)* ; 
    e1 : e2 (AND^ e2)*; 
    e2 : e3 (PIPE^ e3)*; 
    e3 : e4 (ANDSYMB^ e4)*; 
    e4 : e5 ((EQUAL^|NOTEQUAL^) e5)*; 
    e5 : e6 ((LESS^|GREATER^) e6)*; 
    e6 : e7 ((PLUS^|MINUS^) e7)* ; 
    e7 : e8 ((STAR^|SLASH^) e8)* ; 
    e8 : e9 (NEW^ ID LPAREN RPAREN)*; 
    e9 : (NOT^)? e10; 
    e10 : e11 | call_def; 
    e11 : constant 
     | '(' expression ')' -> expression; 
+0

Que signifie le signe^après la règle? Mise à jour: je vois une autre SOF semble l'expliquer http://stackoverflow.com/questions/11365781/caret-prefix-instead-of-postfix-in-antlr – javadba

Questions connexes