我正在尝试用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))
我不明白为什么一个工作而另一个不行。
令牌a
只被分配一种令牌类型。由于此输入文本匹配LETTERS
和IDENTIFIER
规则,ANTLR 4将根据词法分析器中出现的第一条规则分配类型,这意味着输入的a
将是LETTERS
类型的令牌。
如果你只是想让LETTERS
成为其他词法分析器规则的子部分,而不是自己形成LETTERS
令牌,你可以将它声明为fragment
规则。
fragment LETTERS : [a-z]+;
IDENTIFIER : LETTERS;
在这种情况下,a
将被分配标记类型IDENTIFIER
,并且原始解析器规则将正常工作。