我正在构建以下语法:
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一个浮点数。但是看到解析树:
答案 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'
;