ANTLRWorks - 代码生成卡住而不生成

时间:2011-12-12 13:47:14

标签: math antlr grammar expression 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 个答案:

答案 0 :(得分:1)

这似乎是版本3.3(及更高版本)中引入的错误。从语法生成解析器时,ANTLR 3.2会产生以下错误:

  

警告(205):Test.g:31:2:ANTLR无法在规则平等中分析此决定;通常这是因为从备选方案的左边缘可见的递归规则引用。 ANTLR将使用k = 1的固定前瞻重新分析决策。考虑对该决定使用“options {k = 1;}”并可能添加语法谓词。   error(10):内部错误:org.antlr.tool.Grammar.createLookaheadDFA(Grammar.java:1279):对于决策6,甚至不能做k = 1;原因:超时(> 1000毫秒)

在我看来,你已经使用LR语法作为你的ANTLR语法的基础。考虑重新开始,然后考虑LL解析。查看以下Q& A,了解如何使用ANTLR解析表达式:ANTLR: Is there a simple example?

另外,我发现你正在使用一些看起来非常像彼此的令牌:LETTERCHARSENTENCEIDENTIFIER。您必须意识到,如果所有这些规则都以小写字母开头,则只匹配其中一个规则(匹配最多的规则,或者如果是平局,则首先在词法分析器语法中定义规则) 。词法分析器根据解析器“请求”的内容生成令牌,它独立于解析器创建令牌。

最后,对于一个简单的表达式解析器,你真的不需要谓词(而backtrack=true会导致ANTLR在所有解析器规则前面自动插入谓词!)。