我正在构建以下语法:
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 是 float 。但请参阅解析树:
最佳答案
问题似乎出在 Number 和 Float 规则中。这两个规则有歧义,但由于 Number 和 Float 都是词法分析器规则,因此您必须记住 antlr 隐式创建了一个 nextToken 规则来处理所有标记。示例中的 nextToken 如下所示:
nextToken: Letter | Number | Float;
当antlr找到一个数字时,他会遍历DFA来查找跳转到哪个规则,但在这种情况下,他无法决定跳转到哪个规则(数字或 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'
;
关于ANTLR谓词-LL(*)解析机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27280219/