2010-10-25 11 views
7

Ich verwende ANTLR (3.2), um einige ziemlich einfache Grammatik zu analysieren. Leider stieß ich auf ein kleines Problem. Nehmen Sie die follwoing Regel:ANTLR: Problem unterscheidet unäre und binäre Operatoren (z. B. Minuszeichen)

exp 
: NUM 
| '(' expression OPERATOR expression ')' -> expression+ 
| '(' (MINUS | '!') expression ')' -> expression 
; 

OPERATOR enthält die gleichen Minuszeichen ('-') als mit MINUS definiert ist. Jetzt scheint ANTLR mit diesen beiden Regeln nicht fertig zu werden. Wenn ich eins entferne, funktioniert alles gut.

Wer Ideen?

Antwort

9

Machen Sie den unären Ausdruck zu dem mit der höchsten Priorität. Ich würde auch ein anderes Token für das unäre verwenden, um die Unterscheidung zwischen dem Minus besser zu machen. Eine Demo:

grammar Exp; 

options { 
    output=AST; 
} 

tokens { 
    UNARY; 
} 

parse 
    : exp EOF 
    ; 

exp 
    : additionExp 
    ; 

additionExp 
    : multiplyExp ('+'^ multiplyExp | '-'^ multiplyExp)* 
    ; 

multiplyExp 
    : unaryExp ('*'^ unaryExp | '/'^ unaryExp)* 
    ; 

unaryExp 
    : '-' atom -> ^(UNARY atom) 
    | '!' atom -> ^('!' atom) 
    | atom 
    ; 

atom 
    : '(' exp ')' -> exp 
    | Number  -> Number 
    ; 

Number : ('0'..'9')+ ('.' ('0'..'9')+)? ; 

Spaces : (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;} ; 

Ein Schnelltest mit der Quelle:

3 * -4 + 7/6 * -(3 + -7 * (4 + !2)) 

erzeugte den folgenden AST:

alt text

+0

wow, tolle Arbeit, vielen Dank! – Christian

+0

@Christian, gern geschehen. –

+0

Und wie soll der Tokenizer wissen, wenn er ein Minus liest, wenn es einem UNARY entspricht? –

Verwandte Themen