由于歧义导致antlr4词法分析器/解析器冲突

由于歧义导致antlr4词法分析器/解析器冲突,antlr4,Antlr4,我试图解析MS的SQL方言。根据规范,“top”的表达式必须用括号括起来 选择顶部(@rows*2)a、b、c从 但作为例外,如果值是无符号文字整数,则可以忽略这些值,因此 从以下位置选择前75名 我尝试在解析器中嵌入这个文本整数特例(松散地): top_子句:'top'[0-9]+|'top'('expression') 因此,第一种选择是纯词法规则,第二种选择是解析器规则。因为整型常量是一个有效的表达式,所以它选择将其解析为表达式 问题是,1)我可以强制它作为没有谓词的lexer规则进行匹配

我试图解析MS的SQL方言。根据规范,“top”的表达式必须用括号括起来

选择顶部(@rows*2)a、b、c从

但作为例外,如果值是无符号文字整数,则可以忽略这些值,因此

从以下位置选择前75名

我尝试在解析器中嵌入这个文本整数特例(松散地):

top_子句:'top'[0-9]+|'top'('expression')

因此,第一种选择是纯词法规则,第二种选择是解析器规则。因为整型常量是一个有效的表达式,所以它选择将其解析为表达式

问题是,1)我可以强制它作为没有谓词的lexer规则进行匹配吗?2)最重要的是,我应该这样做吗

我的猜测是我不应该——这是一个明显的歧义(事实上,是我语法中的一个错误),我想我应该把它作为一个纯粹的解析器规则(只是“'TOP'表达式”)进行匹配,然后进行排序。 欢迎指教


编辑:根据Matt Timmermans的观点进行修改。

答案取决于您实际想要实现的目标,但我猜您希望允许顶部和数字之间存在空白。如果将其定义为lexer规则,则必须在其中显式指定空白。对于解析器规则,这是不必要的,因为(我在这里再次猜测)您有一个跳过whitspaces的lexer规则

我建议您始终将文本定义为lexer规则(解析器规则中没有“TOP”,没有数字),并保持TOP_子句不变,只需使用新的lexer规则(和一个小的重构):


你不想要
'TOP'[0-9]+|'TOP'('expression')”
?好吧,表达式已经定义为“('expression')”,因为我希望删除lexer-only规则,所以我在这里跳过了它们(因为如果表达式的其余部分只是一个整数,我不想要求它们)。但是是的,你是对的。将编辑。现在它不是含糊不清的提示我。感觉自己像个傻瓜:(关于问题的另一部分,我应该做吗?你有什么意见吗?对不起,我熟悉这类系统,但不熟悉antlr4,所以我无法回答你的具体问题。但是没有理由在这里做任何奇怪的事,所以你可能不应该:)嗨,不,这不仅仅是因为“top”结构有一个特例,如果只是数字,就不需要括号;我应该用它自己的lexer规则来处理这个特殊情况吗?马特·蒂默曼斯说不,听起来不错。重新。lexer规则,我在简化这个帖子;我所有的词法分析都是使用命名规则完成的,唯一的例外是“(”和“)”,根据你的敦促,我现在将使用en-rule-ify.Small note-ANTLR的词法分析程序功能强大,我使用它而不是复杂结构的解析器,这给自己带来了问题。向其他人提示-将所有结构放在解析器中并保持词法分析的简单。
DIGITS: [0-9]+;
TOP: 'TOP';
OPEN_PAR: '(';
CLOSE_PAR: ')';

top_clause: TOP (DIGITS | OPEN_PAR expression CLOSE_PAR);