Domanda

Sto cercando di implementare una gestione espressione di grammatica (che si occupa di parentesi nidificate e roba del genere). Ho il seguente fino ad ora, ma non posso affrontare alcuni casi (casi di successo / insuccesso compaiono dopo il seguente blocco di codice). Qualcuno sa cosa sta succedendo?

Nota: Il varname + = e varname = solo roba alcune cose aiutante sono ulteriore generazione AST in xtext. Non preoccuparti di loro per ora.

...

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* )
;
...

Ed ecco l'elenco dei analizza / fallisce:

c = ((b)); //fails
c = ((a not b)); //fails
c = b; //parses
d = (b); //parses
È stato utile?

Soluzione

Cosa sta succedendo è che la vostra espressione / Espressioni supportano parentesi singoli ma non multipli parentesi (come avete concluso). Non ho ANTLR specifica esperienza, ma ho lavorato con JavaCC che condivide molti concetti simili (ho scritto una grammatica per Prolog ... non chiedere).

Per gestire parentesi nidificate, è in genere necessario qualcosa di simile a:

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

Ciò significa che l'espressione o è avvolto in parentesi o è solo un'espressione grezzo. Per quanto riguarda come le offerte AST con questo, un ParenthesisExpression 'è un' espressione, in modo che possa essere rappresentato come una sottoclasse o di un'implementazione di (se espressione è un'interfaccia / classe astratta di sorta).

Altri suggerimenti

Sfruttate l'^ posto dopo il token / nome della regola è molto utile per la definizione delle espressioni.

    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;

Ho usato questo grammatica per semplici espressioni: http: //fisheye2.atlassian .com / browse / ~ grezzo, r = 5175 / antlr-examples / C / polydiff / Poly.g

Ho anche usato la grammatica contiene in questo progetto per le espressioni più complesse: http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top