2009-09-20 26 views
5

¿Cómo se implementa la precedencia del operador en ANTLR?ANTLR Precedencia del operador

Estoy usando el paquete XText/Antlr en este momento.

Editar:

hice lo sepp2k sugirió, y precedencia de los operadores funciona ahora, pero cosas como 3 + * También funciona en este momento. Los operadores básicamente están "cayendo" en el árbol.

Además, probé la gramática C en el sitio web de ANTLR y sucedió lo mismo en ANTLRworks.

¿Alguien sabe cuál es el problema?

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

AndOp: 
    'and'? ComparisonOp; 

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

ConcatOp: 
    '..'? AddSubOp; 

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

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

ExpOp: 
    '^'? expr=Expression; 
+0

La llamada a Expression probablemente debería estar entre '(' y ')'. Además, todos sus operadores parecen haber perdido un operando de la izquierda. – sepp2k

+0

Lo arreglé usando el método que se encuentra en mi comentario. Además, el operando de la izquierda se ha movido a la primera expresión para evitar la recursión a la izquierda. – jameszhao00

Respuesta

9

Con ANTLR codifica la precedencia en las reglas de la gramática. Como:

expr: mult ('+' mult)* ; 
mult: atom ('*' atom)* ; 
atom: INT | '(' expr ')' ; 

Esto analizar "1 + 2 * 3 + (4 * 5 + 6)" como "(1 + (2 * 3)) + ((4 * 5) + 6)"

+0

Lea mi actualización :) – jameszhao00

+0

Tal vez podría hacer cosas como AndOp: ('y' Expresión) | ComparisonOp – jameszhao00

+0

Para aclarar, cuanto más detallada coincida una regla de gramática, mayor será su precedencia. En el ejemplo anterior, "expr -> multi -> atom *" es más detallado que la ruta al signo más. Por lo tanto, la * ruta tiene prioridad. –

2

Como usas Xtext, te recomiendo usar el concepto de acción de Xtext. Es decir, una gramática de expresión simple normalmente tendría un aspecto similar a éste:

Sum: Product ({Sum.left=current} operator=('+'|'-') right=Product)*; 
Product: Atom ({Product.left=current} operator=('+'|'-') right=Atom)*; 
Atom: Number | Paren; 
Paren: '(' Sum ')'; 
Number: value=INT; 

Por favor, echar un vistazo a la documentación para obtener más detalles.

Cuestiones relacionadas