2009-09-20 25 views
5

W jaki sposób w ANTLR zaimplementowano pierwszeństwo operatora?Pierwszeństwo operatora ANTLR

Używam w tej chwili pakietu XText/Antlr.

Edit:

Zrobiłem co sepp2k zasugerował, a pierwszeństwo operator działa teraz, ale rzeczy jak 3 + * również działać teraz. Operatorzy zasadniczo "wpadają" na drzewo.

Próbowałem także gramatyki C na stronie internetowej ANTLR i to samo stało się w ANTLRworks.

Ktoś wie, na czym polega problem?

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

AndOp: 
    'and'? ComparisonOp; 

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

ConcatOp: 
    '..'? AddSubOp; 

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

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

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

Wywołanie do wyrażenia powinno prawdopodobnie znajdować się pomiędzy "(" i ")". Wygląda na to, że wszyscy operatorzy tracą lewy operand. – sepp2k

+0

Naprawiłem to za pomocą metody znalezionej w moim komentarzu. Również lewy operand został przeniesiony do pierwszego wyrażenia, aby zapobiec rekursji lewej. – jameszhao00

Odpowiedz

9

Z ANTLR kodujesz pierwszeństwo w zasadach gramatycznych. Jak:

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

Byłoby to zanalizować "1 + 2 * 3 + (4 * 5 + 6)," AS "(1 + (2 * 3)) + ((4 * 5) + 6)"

+0

Proszę przeczytać moją aktualizację :) – jameszhao00

+0

Może mógłbym robić rzeczy takie jak AndOp: ('i' Wyrażenie) | ComparisonOp – jameszhao00

+0

Aby wyjaśnić bardziej szczegółową zasadę gramatyczną, dopasuj większą jej pierwszeństwo. W powyższym przykładzie "wyraż -> wiele -> atom *" jest bardziej szczegółowy niż ścieżka do znaku plusa. Dlatego ścieżka * ma pierwszeństwo. –

2

Ponieważ używasz Xtext, polecam użyć koncepcji działania Xtext. Oznacza to, że prosta gramatyka wyraz typowo wyglądać podobnie do tego:

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

Proszę spojrzeć na docs dla szczegółów.