我正在使用 ANTLR 并基于分离的 Java6 词法分析器和语法构建 AST。词法分析器定义包含在 Java6Lex.g 中,并生成语法使用的标记。解析器消耗这些没有问题,但是当我生成 AST 时,我想引入虚构的标记 - 但是,ANTLR 似乎不喜欢这个模型。
解析器语法包括来自词法分析器的标记词汇表——它应该为语法可用的标记提供基线。
parser grammar Java6Parse;
options {
tokenVocab=Java6Lex;
backtrack=true;
memoize=true;
output=AST;
language = CSharp3;
}
现在假设,我想获取 fieldDeclaration 并使用重写规则将其转换为根节点。我假设(显然是错误的)我可以将虚构的标记直接引入解析器语法,如下所示:
fieldDeclaration
: modifiers type variableDeclarator (COMMA variableDeclarator)* SEMI
-> ^(FIELD modifiers type variableDeclarator+)
;
但是,这只会导致发生以下错误:
reference to undefined token in rewrite rule: FIELD
没问题,我明白了,我没有定义它。所以,我尝试在解析器语法的标记部分中定义它。再次错误地认为,tokenVocab 应该提供基线。
tokens { FIELD; }
不,似乎即使定义令牌块也会导致 EarlyExitException 和指示 Java6Parse.g 没有规则的错误。我想,解析器语法根本不喜欢在解析器中定义标记。所以,我在词法分析器中定义了它。再一次,那失败了。然后我在词法分析器和解析器中定义了每个标记 - 再次失败。
所以,这就是我需要知道的。当词法分析器和解析器分开时,有没有办法定义一个虚构的标记,如果是的话,如何。如果不是,是否是将语法和词法分析器组合回同一个文件的唯一选择?