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

标签 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 是 float 。但请参阅解析树: enter image description here

最佳答案

问题似乎出在 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/

相关文章:

parsing - 使用 lex/yacc 替代方案的原因?

ANTLR - 带有空格的标识符

android - Android 应用程序中的 Gradle ANTLR4 插件 : build fails

java - 什么是 ANTLR4 的最小示例 Gradle 项目(带有 antlr 插件)?

parsing - ANTLR:当其他数字文字也可能时解析 2 位数字

python - ANTLR解析MismatchedTokenException

parsing - Antlr 条件重写

return-value - 如何处理ANTLR中的列表返回值

java - ANTLR/语法问题 : calculator language