ANTLR的谓词-LL(*)解析机制

时间:2014-12-03 19:39:17

标签: antlr antlrworks

我正在构建以下语法:

Letter     : 'a'..'z'|'A'..'Z'     ; 

Number      : '0'..'9'     ; 

Float 
   :   Number+ '.' Number+  
   ; 

a5 
@init 
{ 
 int n = 1; 
} 
: ({n<=5}?=>(Letter|Number){n++;})+  
;

它没有成功解析字符串“CD923IJK”,因为我需要使用“CD923”而不是“CDIJK”就像正在发生

如果注释了FLoat,问题就会消失并像我想要的那样消耗“CD923”

显然需要高级解析,因为这个语法是LL(K),我设置了前瞻深度

options
{
k=5;
}

但没有解决任何问题。有什么想法吗?

更新

对建议500 - Internal Server Error的回应 我添加了以下规则

public test :a5 Float   ;

我需要匹配CD9231.23,其中CD923是一个字母数字和1.23一个浮点数。但是看到解析树: enter image description here

2 个答案:

答案 0 :(得分:1)

我想也许你可以做一个更简单的解决方案:如果你知道你的a5规则的项目总是一个大小为5或更小的文本你可以根据它编写规则:

A5 
: (Letter|Number)(Letter|Number)(Letter|Number)(Letter|Number)(Letter|Number) 
  | (Letter|Number)(Letter|Number)(Letter|Number)(Letter|Number) 
  | (Letter|Number)(Letter|Number)(Letter|Number) 
  | (Letter|Number)(Letter|Number) 
  | (Letter|Number) 
;

其他解决方案可以制定规则而不考虑lenthg,然后在语义阶段检查它:

AK 
    : (Letter|Number)+
;

这是一些想法,希望有帮助...

答案 1 :(得分:1)

问题似乎在规则Number and Float中。你有两个规则含糊不清,但由于Number和Float都是词法规则,你必须记得antlr隐式创建了一个nextToken规则来处理所有的令牌。示例中的nextToken如下所示:

nextToken: Letter | Number | Float;

当antlr找到一个数字时,他走过DFA找到哪个规则跳转,但在这种情况下,他无法决定跳转到哪个正确的规则(Number或Float)。您可以避免此行为,使Float规则成为解析器规则。你可以尝试这样的事情:

grammar a5;

s   : a5 coordinate? 
    ;

a5 
@init{
 int n = 0;
}
: ({n<5}?=> (LETTER|Number){n++;})+
;


Number  :   '0'..'9'
    ;

coordinate  :    Number+ '.' Number+
    ;

LETTER
    :   'a'..'z'|'A'..'Z'
    ;