2014-03-13 93 views
2

我停留在ANTLR的一個非常基礎的層面。通過Parr博士的「最終ANTLR 4參考」。在4.2節,「建立一個計算器使用訪問者以下語法列出:ANTLR4書,計算器鍛鍊

grammar LabeledExpr; // rename to distinguish from Expr.g4 

prog: stat+ ; 

stat: expr NEWLINE    # printExpr 
    | ID '=' expr NEWLINE   # assign 
    | NEWLINE      # blank 
    ; 

expr: expr op=('*'|'/') expr  # MulDiv 
    | expr op=('+'|'-') expr  # AddSub 
    | INT       # int 
    | ID       # id 
    | '(' expr ')'    # parens 
    ; 

MUL : '*' ; // assigns token name to '*' used above in grammar 
DIV : '/' ; 
ADD : '+' ; 
SUB : '-' ; 
ID : [a-zA-Z]+ ;  // match identifiers 
INT : [0-9]+ ;   // match integers 
NEWLINE:'\r'? '\n' ;  // return newlines to parser (is end-statement signal) 
WS : [ \t]+ -> skip ; // toss out whitespace 

我想clear語句添加到上面,從書:

移動之前,你可能需要花一些時間嘗試通過添加clear語句來擴展此表達式語言。該clear命令應該清除掉memory地圖,你會需要在規則stat一個新的選擇承認它。用# clear標記備選方案,然後在文法上運行ANTLR以獲得增強的訪問者界面。

這是我的嘗試:

grammar LabeledExpr; 

prog: stat+ ; 

stat: expr NEWLINE   # printExpr 
    | ID '=' expr NEWLINE # assign 
    | clear NEWLINE   # clearMem 
    | NEWLINE    # blank 
    ; 

expr: expr op=('*'|'/') expr # MulDiv 
    | expr op=('+'|'-') expr # AddSub 
    | INT     # int 
    | ID     # id 
    | '(' expr ')'   # parens 
    ; 

clear: CLEAR    
    ; 

MUL: '*' ; // assigns token name to '*' used above in grammar 
DIV: '/' ; 
ADD: '+' ; 
SUB: '-' ; 

ID : [a-zA-Z]+ ; 
INT : [0-9]+ ; 
NEWLINE: '\r'?'\n' ; 
WS : [ \t]+ -> skip ; 
CLEAR: 'clear'; 

然而,visitClearMem不會被調用:

@Override 
public Integer visitClearMem(LabeledExprParser.ClearMemContext ctx) { 
    String text = ctx.getText(); 
    if (text.equalsIgnoreCase("clear")) { 
     memory.clear(); 
    } 
    return 0; 
} 
+0

我知道這是超過3歲,但你可以發佈你是如何解決的呢? –

回答

4

的問題是在你的詞法分析器的CLEAR規則的位置。由於輸入clear匹配兩者的規則IDCLEAR,ANTLR選擇首先出現在語法中的一個。在這種情況下,輸入clear變爲ID

一般情況下,要放置所有關鍵字爲其他標識符規則之前你的語言,以確保他們得到適當的匹配。