Pregunta

Estoy tratando de implementar un manejo de la gramática de expresión (que se ocupa de paréntesis anidado y esas cosas). Tengo el siguiente hasta ahora, pero no pueden hacer frente a algunos casos (casos de éxito / fracaso aparecen después de que el siguiente bloque de código). Alguien sabe lo que está pasando?

Nota: El nombre_var + = y code = cosas son sólo algunas cosas ayudante generación AST adicional en xtext. No se preocupe de ellos por ahora.

...

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

Y aquí está la lista de los análisis sintácticos / falla:

c = ((b)); //fails
c = ((a not b)); //fails
c = b; //parses
d = (b); //parses
¿Fue útil?

Solución

Lo que está pasando es que tu expresión / expresiones admiten paréntesis individuales, pero no múltiples paréntesis (como se concluyó). No tengo experiencia específica antlr pero he trabajado con javacc que comparte muchos conceptos similares (I escribió una gramática para Prolog ... no pregunte).

Para manejar paréntesis anidados, que suelen tener algo similar a:

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

Esto significaría que la expresión se envuelve ya sea entre paréntesis o es sólo una expresión cruda. En cuanto a cómo las ofertas de AST con esto, un ParenthesisExpression 'es una' expresión, por lo que se puede representar como una subclase o una implementación de (si es una expresión / clase abstracta interfaz de tipo).

Otros consejos

Hacer uso de la ^ colocado después el nombre del token / regla es muy útil para definir expresiones.

    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;

He usado esta gramática de expresiones simples: http: //fisheye2.atlassian .com / browse / ~ cruda, r = 5,175 / antlr-ejemplos / C / polydiff / Poly.g

También he utilizado la gramática contiene en este proyecto para las expresiones más complejas: http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top