ANTLR lexer can';我一点也不向前看

ANTLR lexer can';我一点也不向前看,antlr,lex,antlr3,lexer,Antlr,Lex,Antlr3,Lexer,我的语法如下: rule: 'aaa' | 'a' 'a'; 它可以成功解析字符串“aaa”,但无法解析“aa”,出现以下错误: line 1:2 mismatched character '<EOF>' expecting 'a' 结果与更明显的版本相同: rule: AAA | A A; AAA: 'aaa'; A: 'a'; 显然,ANTLR lexer试图将输入“aa”与失败的规则AAA相匹配。除了ANTLR是一个LL(*)解析器或其他什么,lexer应该与解析器分开工

我的语法如下:

rule: 'aaa' | 'a' 'a';
它可以成功解析字符串“aaa”,但无法解析“aa”,出现以下错误:

line 1:2 mismatched character '<EOF>' expecting 'a'
结果与更明显的版本相同:

rule: AAA | A A;
AAA: 'aaa';
A: 'a';
显然,ANTLR lexer试图将输入“aa”与失败的规则AAA相匹配。除了ANTLR是一个LL(*)解析器或其他什么,lexer应该与解析器分开工作,并且应该能够解决歧义。语法可以很好地与旧的lex(或flex)配合使用,但与ANTLR似乎不一样。那么这里的问题是什么


谢谢你的帮助

ANTLR生成的解析器是(或可以是)LL(*),而不是它的lexer

当lexer看到输入
“aa”
,它会尝试匹配令牌
AAA
。当它不这样做时,它会尝试匹配任何其他也匹配
“aa”
(lexer不会回溯到匹配
A
!)。由于这是不可能的,因此会产生错误


这通常不是问题,因为在实践中,通常会有某种标识符规则
“aa”
可以回溯到。那么,你想解决的实际问题是什么,或者你只是对内部工作方式好奇?如果是第一个问题,请编辑您的问题并描述您的实际问题。

您的lexer中如何定义标记?在我看来,如果给定一个
a
作为输入,lexer更倾向于匹配
a
而不是
aaa
。@Dervall令牌文件看起来像:
a=4 aaa=5
它更倾向于
aaa
而不是
a
。它可以解析
aaa
a
,但不能解析
aa
@AustinHenley:是的,它是贪婪的,因为当有多种选择时,它更喜欢更长的令牌。但输入“aa”时,“aaa”甚至不是一个可能的选择。请查看此难以置信的详细信息,但很容易阅读:。理解ANTLR Lexer的怪癖对我帮助很大。尤其是“+和。*默认为非贪婪行为”是非常令人惊讶的!谢谢你的澄清,巴特。我想离第二个更近了。我一直在使用lex/yacc,我正在尝试切换到ANTLR。ANTLR解析器作为LL解析器已经有其局限性,但正如您所指出的,这是关于词法分析器而不是解析器的。老实说,如果ANTLR lexer不能处理这么多的复杂性,我会有点失望,而像
lex
这样的其他lexer也能做到这一点。回溯成本不会很大,最坏的情况是O(n^2),如果处理得当,回溯成本可能会更好。@KJ,当然有办法解决这个问题。但与其解释如何解决你的“稻草人”的例子,我倒不如尝试提出一个解决眼前“真正”问题的方案(否则我会回答两次…)。我恐怕不是在寻找解决某个特定问题的方法。正如我所说,当我考虑使用ANTLR时,它更接近于好奇,因为它支持JAVA,不像yacc,但我越来越谨慎。我知道手动前瞻可以解决这个问题(我看过你的),但是逐案处理类似的问题似乎不可靠。。谢谢你的回答!
rule: AAA | A A;
AAA: 'aaa';
A: 'a';