Antlr4识别异常:void被判定为identifier而非kind的问题求助
问题
定义了如下Antlr4语法规则:
method_declaration : protection? expression identifier LEFT_PARENTHESES (method_argument (COMMA method_argument)*)? RIGHT_PARENTHESES method_block; expression : ... | ... | identifier | kind ; identifier : IDENTIFIER ; kind : ... | ... | VOID_KIND; // void为示例,还有其他类型 IDENTIFIER : (LETTER | '_') (LETTER | DIGIT | '_')*; VOID_KIND : 'void'; fragment LETTER : [a-zA-Z]; fragment DIGIT : [0-9];
注:method_declaration的其他规则与本问题无关。
输入void Start() { }后查看ParseTree,发现Antlr4将void识别为identifier而非kind,尝试调整.g4文件中kind和identifier的规则顺序,但无效果,请问原因是什么?如何解决?
原因分析
这是Antlr4词法分析阶段的优先级问题:
- Antlr4的词法规则遵循自上而下的匹配优先级,先定义的词法规则会优先被匹配。
IDENTIFIER的规则可以匹配void(因为void符合字母开头、后续为字母的格式),且IDENTIFIER在VOID_KIND之前定义,所以词法分析器会直接把void识别为IDENTIFIER,根本不会触发VOID_KIND的匹配逻辑。- 调整
kind和identifier这两个语法(parser)规则的顺序没用,因为词法分析是在语法分析之前完成的,语法规则的顺序不影响词法阶段的识别结果。
解决方法
将所有关键字的词法规则(比如VOID_KIND)放在IDENTIFIER规则之前,示例调整后的词法部分:
VOID_KIND : 'void'; // 其他关键字规则也需要放在IDENTIFIER之前 IDENTIFIER : (LETTER | '_') (LETTER | DIGIT | '_')*; fragment LETTER : [a-zA-Z]; fragment DIGIT : [0-9];
这样Antlr4词法分析器会优先匹配VOID_KIND,当遇到void时会直接识别为VOID_KIND,而非IDENTIFIER,后续语法分析时就能进入kind分支。
内容的提问来源于stack exchange,提问作者1Mangomaster1
相关产品推荐
相关产品推荐

