2009-09-20 15 views
5

Come viene implementata la precedenza degli operatori in ANTLR?ANTLR Precedenza operatore

Attualmente sto utilizzando il pacchetto XText/Antlr.

Edit:

ho fatto quello che sepp2k suggerito, e precedenza degli operatori ora funziona, ma roba come 3 + * funziona anche ora. Gli operatori stanno fondamentalmente "cadendo" dall'albero.

Inoltre, ho provato la grammatica C sul sito Web di ANTLR e la stessa cosa è accaduta in ANTLRworks.

Qualcuno sa qual è il problema?

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

AndOp: 
    'and'? ComparisonOp; 

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

ConcatOp: 
    '..'? AddSubOp; 

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

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

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

La chiamata a espressione dovrebbe essere probabilmente tra '(' e ')'. Anche ai tuoi operatori sembra manchi un operando di sinistra. – sepp2k

+0

L'ho risolto usando il metodo trovato nel mio commento. Inoltre, l'operando di sinistra è stato spostato nella prima espressione per impedire la ricorsione a sinistra. – jameszhao00

risposta

9

Con ANTLR codificare la precedenza nelle regole grammaticali. Come:

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

Ciò analizzare "1 + 2 * 3 + (4 * 5 + 6)" come "(1 + (2 * 3)) + ((4 * 5) + 6)"

+0

Si prega di leggere il mio aggiornamento :) – jameszhao00

+0

Forse potrei fare cose come AndOp: ('e' Expression) | ComparisonOp – jameszhao00

+0

Per chiarire il più dettagliato, una regola di grammatica corrisponderà a maggiore è la sua precedenza. Nell'esempio sopra "expr -> multi -> atom *" è più dettagliato del percorso del segno più. Quindi il percorso * ha la precedenza. –

2

Dato che usi Xtext, ti consiglio di utilizzare il concetto di azione di Xtext. Che è, una semplice grammatica espressione sarebbe tipicamente simile a questa:

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

si prega di dare uno sguardo ai documenti per i dettagli.