2011-12-12 34 views
0

我使用以下語法定義了算術表達式的語法。它是一個更復雜整體的子集,但問題只發生在我將語法擴展到包含邏輯運算時。ANTLRWorks - 代碼生成卡住而不生成

當我嘗試使用antlrworks編碼gen時,甚至需要很長時間才能開始生成。我認爲問題在於paren的規則,因爲它包含了一個循環到expr的開始。在固定任何幫助,這將事先很大

感謝

的選項:用於進行語法

options { 
tokenVocab = MAliceLexer; 
backtrack = true; 
} 

代碼如下:

type returns [ASTTypeNode n] 
: NUMBER {$n = new IntegerTypeNode();} 
| LETTER {$n = new CharTypeNode();} 
| SENTENCE { $n = new StringTypeNode();} 
; 

term returns [ASTNode n] 
: IDENTIFIER {$n = new IdentifierNode($IDENTIFIER.text);} 
| CHAR {$n = new LetterNode($CHAR.text.charAt(1));} 
| INTEGER {$n = new NumberNode(Integer.parseInt($INTEGER.text));} 
| STRING { $n = new StringNode($STRING.text); } 
; 

paren returns [ASTNode n] 
:term { $n = $term.n; } 
| LPAR expr RPAR { $n = $expr.n; } 
; 

negation returns [ASTNode n] 
:BITNEG (e = negation) {$n = new BitNotNode($e.n);} 
| paren {$n = $paren.n;} 
; 

unary returns [ASTNode n] 
:MINUS (u =unary) {$n = new NegativeNode($u.n);} 
| negation {$n = $negation.n;} 
; 

mult returns [ASTNode n] 
: unary DIV (m = mult) {$n = new DivideNode($unary.n, $m.n);} 
| unary MULT (m = mult) {$n = new MultiplyNode($unary.n, $m.n);} 
| unary MOD (m=mult) {$n = new ModNode($unary.n, $m.n);} 
| unary {$n = $unary.n;} 
; 

binAS returns [ASTNode n] 
: mult PLUS (b=binAS) {$n = new AdditionNode($mult.n, $b.n);} 
| mult MINUS (b=binAS) {$n = new SubtractionNode($mult.n, $b.n);} 
| mult {$n = $mult.n;} 
; 

comp returns [ASTNode n] 
: binAS GREATEREQ (e =comp) {$n = new GreaterEqlNode($binAS.n, $e.n);} 
|binAS GREATER (e = comp) {$n = new GreaterNode($binAS.n, $e.n);} 
|binAS LESS (e = comp) {$n = new LessNode($binAS.n, $e.n);} 
|binAS LESSEQ (e = comp) {$n = new LessEqNode($binAS.n, $e.n);} 
|binAS {$n = $binAS.n;} 
; 

equality returns [ASTNode n] 
: comp EQUAL (e = equality) {$n = new EqualNode($comp.n, $e.n);} 
|comp NOTEQUAL (e = equality) {$n = new NotEqualNode($comp.n, $e.n);} 
|comp { $n = $comp.n; } 
; 

bitAnd returns [ASTNode n] 
: equality BITAND (b=bitAnd) {$n = new BitAndNode($equality.n, $b.n);} 
| equality {$n = $equality.n;} 
; 

bitXOr returns [ASTNode n] 
: bitAnd BITXOR (b = bitXOr) {$n = new BitXOrNode($bitAnd.n, $b.n);} 
| bitAnd {$n = $bitAnd.n;} 
;  

bitOr returns [ASTNode n] 
: bitXOr BITOR (e =bitOr) {$n = new BitOrNode($bitXOr.n, $e.n);} 
| bitXOr {$n = $bitXOr.n;} 
    ; 

logicalAnd returns [ASTNode n] 
: bitOr LOGICALAND (e = logicalAnd){ $n = new LogicalAndNode($bitOr.n, $e.n); } 
| bitOr { $n = $bitOr.n; } 
;  

expr returns [ASTNode n] 
: logicalAnd LOGICALOR (e = expr) { $n = new LogicalOrNode($logicalAnd.n, $e.n); } 
| IDENTIFIER INC {$n = new IncrementNode(new IdentifierNode($IDENTIFIER.text));} 
    | IDENTIFIER DEC {$n = new DecrementNode(new IdentifierNode($IDENTIFIER.text));} 
    | logicalAnd {$n = $logicalAnd.n;} 
; 

`

回答

1

這似乎是版本3.3(及更高版本)中引入的錯誤。

warning(205): Test.g:31:2: ANTLR could not analyze this decision in rule equality; often this is because of recursive rule references visible from the left edge of alternatives. ANTLR will re-analyze the decision with a fixed lookahead of k=1. Consider using "options {k=1;}" for that decision and possibly adding a syntactic predicate. error(10): internal error: org.antlr.tool.Grammar.createLookaheadDFA(Grammar.java:1279): could not even do k=1 for decision 6; reason: timed out (>1000ms)

在我看來你已經使用LR語法爲您的ANTLR語法的基礎:ANTLR 3.2生成從你的語法分析器時產生以下錯誤。考慮重新開始,然後考慮LL解析。看看以下是問答&一個來看看如何使用ANTLR解析表達式:ANTLR: Is there a simple example?

而且,我看到你正在使用的一些標記,看起來極像是對方:LETTERCHARSENTENCEIDENTIFIER。你必須認識到,如果所有人都可能以小寫字母開頭,那麼只有其中一個規則是匹配的(匹配最多的規則,或者在匹配的情況下,在詞法分析器語法中首先定義的那個) 。詞法分析器而不是根據解析器「詢問」的內容產生標記,它獨立於解析器創建標記。

最後,對於一個簡單的表達式解析器,你真的不需要謂詞(和backtrack=true導致ANTLR自動插入謂詞的所有語法規則面前!)。