如果我有如下的ANTLR语法:
grammar Test;
options {
language = Java;
}
rule : (foo | bar);
foo : FOO ',' FOO;
bar : BAR;
FOO: ('0'..'9')+;
BAR: ('a'..'z' | 'A'..'Z' | '0'..'9' | ' ')+;
WHITESPACE: (' ' | '\t')+ { $channel=HIDDEN; };
我使用测试字符串:
12abc3
这(我相信)是一个BAR
令牌,它满足bar
规则并被解析。喝彩。
但是,如果我有这个字符串:
12
我收到line 1:2 mismatched input '' expecting ','
这似乎相当不确定,尽管我确定不是。我知道我已经因为有两个令牌而遇到麻烦:FOO
和BAR
接受数字。但是如果解析器成功或失败,它应该成功或失败。换句话说,在第一种情况下,第一个字符是1并且显然被评估为BAR
标记的成员,因此解析器向下成功路径。在第二种情况下,SAME第一个字符被评估为FOO
令牌,因此尽管字符串COULD是成功的bar
解析,但路径注定要失败。为什么不一致?或者我错过了一些关于ANTLR和/或解析的更基本的东西?
答案 0 :(得分:3)
ANTLR在查看下一个标记(或EOF)的第一个字符之前不会确定标记类型。 ANTLR也将尝试最长的匹配,这就是为什么你看到'12abc3'为BAR而不是FOO BAR。在第二种情况下,ANTLR将使用FOO作为'12',因为它在语法中首先列出。
答案 1 :(得分:0)
除了Adam回答之外,您必须意识到词法分析器和解析器虽然在相同的语法中定义,但是在不同的时间构建。首先,输入源被标记化,当发生这种情况时,解析器才对这些标记进行操作。当解析器通过源(字符流)以支持完全匹配(即令牌化"12"
为BAR
时,令牌不创建)。将"12"
标记为FOO
的事实是因为FOO
位于BAR
规则之前,并且在长期匹配相等的情况下具有更高的优先级。
简而言之:ANTLR语法不 PEG。