我正在尝试用ANTLR学习EBNF语法。所以我想我会将维基百科的EBNF语法转换为ANTLR 4并使用它。不过,我度过了一段可怕的时光。我能够将语法简化为产生问题的一步。
似乎我只有一个令牌引用另一个令牌,然后ANTLR 4无法解析输入。
这是我的语法:
grammar Hello;
program : statement+ ;
statement : IDENTIFIER STATEMENTEND /*| LETTERS STATEMENTEND */ ;
LETTERS : [a-z]+ ;
IDENTIFIER : LETTERS ;
SEMICOLON : [;] ;
STATEMENTEND : SEMICOLON NEWLINE* | NEWLINE+ ;
fragment NEWLINE : '\r' '\n' | '\n' | '\r';
注意IDENTIFIER
仅指LETTERS
。
如果我提供此输入:
a;
然后我收到此错误:
line 1:0 mismatched input 'a' expecting IDENTIFIER
(program a ;\n)
但是,如果我取消注释代码并提供相同的输入,我将得到合法的输出:
(program (statement a ;\n))
我不明白为什么一个有效,另一个没有。
答案 0 :(得分:2)
令牌a
只会被分配一种令牌类型。由于此输入文本与LETTERS
和IDENTIFIER
规则匹配,因此ANTLR 4将根据词法分析器中出现的第一个规则指定类型,这意味着输入a
将是输入LETTERS
。
如果您仅将LETTERS
作为其他词法规则的子部分,而不是自己形成LETTERS
令牌,则可以将其声明为fragment
规则。
fragment LETTERS : [a-z]+;
IDENTIFIER : LETTERS;
在这种情况下,a
将被分配令牌类型IDENTIFIER
,原始解析器规则将起作用。