【发布时间】:2012-08-30 05:38:54
【问题描述】:
我的语法如下:
rule: 'aaa' | 'a' 'a';
它可以成功解析字符串'aaa',但它无法解析'aa'并出现以下错误:
line 1:2 mismatched character '<EOF>' expecting 'a'
仅供参考,这是词法分析器的问题,而不是解析器的问题,因为我什至不调用解析器。主要功能如下:
@members {
public static void main(String[] args) throws Exception {
RecipeLexer lexer = new RecipeLexer(new ANTLRInputStream(System.in));
for (Token t = lexer.nextToken(); t.getType() != EOF; t = lexer.nextToken())
System.out.println(t.getType());
}
}
结果与更明显的版本相同:
rule: AAA | A A;
AAA: 'aaa';
A: 'a';
显然,ANTLR 词法分析器尝试将输入“aa”与失败的规则 AAA 匹配。除了 ANTLR 是一个 LL(*) 解析器或其他什么之外,词法分析器应该与解析器分开工作,它应该能够解决歧义。该语法适用于旧的 lex(或 flex),但它似乎不适用于 ANTLR。那么这里的问题是什么?
感谢您的帮助!
【问题讨论】:
-
词法分析器中的标记是如何定义的?在我看来,词法分析器更喜欢匹配
a而不是aaa给定一个a作为输入。 -
@Dervall 令牌文件看起来像:
A=4 AAA=5它更喜欢aaa而不是a。它可以解析aaa和a但不能解析aa。 -
@AustinHenley:是的,从某种意义上说,当有多种选择时它更喜欢较长的令牌,这是贪婪的。但是对于输入“aa”,“aaa”甚至不是一个可能的选择。
-
查看这个非常详细但易于关注的页面:wincent.com/wiki/ANTLR_lexers_in_depth。它对我理解 ANTLR Lexer 的怪癖有很大帮助。尤其是“.+ 和 .* 默认为非贪婪行为”非常令人惊讶!