2011-12-12 32 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自动插入谓词的所有语法规则面前!)。