ANTLR组合语法中如何指定Lexer的superClass而非仅修改Parser?
解决ANTLR组合语法中修改Lexer父类的问题
可行方案1:分别指定Lexer和Parser的父类(无需拆分语法)
在组合语法文件中,不要使用全局的superClass选项,而是通过@lexer::superClass和@parser::superClass指令分别给Lexer和Parser指定父类,示例如下:
grammar YourCombinedGrammar; // 指定Parser的父类(不需要可省略) @parser::superClass = YourParserBase; // 指定Lexer的父类 @lexer::superClass = LexerBase; // 编写Lexer规则(大写开头) ID: [a-zA-Z_][a-zA-Z0-9_]*; INT: [0-9]+; // ... 其他Lexer规则 // 编写Parser规则(小写开头) start: ID INT; // ... 其他Parser规则
这样设置后,Lexer会继承LexerBase,Parser会继承YourParserBase(或默认的ANTLR Parser类,若省略@parser::superClass),不会出现Parser错误继承Lexer父类的问题。
可行方案2:拆分语法文件(官方推荐的规范方式)
将组合语法拆分为独立的Lexer语法和Parser语法文件:
- 创建
YourLexer.g4,设置Lexer的父类:
lexer grammar YourLexer; superClass = LexerBase; ID: [a-zA-Z_][a-zA-Z0-9_]*; INT: [0-9]+; // ... 其他Lexer规则
- 创建
YourParser.g4,设置Parser的父类(可选)并导入Lexer:
parser grammar YourParser; import YourLexer; superClass = YourParserBase; start: ID INT; // ... 其他Parser规则
拆分语法的好处是职责更清晰,便于维护,尤其适合规则较多的场景。
为什么之前设置全局superClass会报错?
在组合语法中,全局的superClass选项仅会作用于Parser类,如果将其设为LexerBase(Lexer的父类),会导致Parser错误地继承Lexer的父类,而Parser的父类必须是ANTLR的Parser类或其子类,因此触发类型冲突报错。
内容的提问来源于stack exchange,提问作者Forsteri123
相关产品推荐
相关产品推荐

