如何调试ANTLR4 Go目标监听器?特定规则监听器未触发
ANTLR4 Go目标监听器特定规则ExitVar_assignment不触发问题排查
问题概述
全局规则EnterEveryRule可正常触发并打印内容,但特定规则ExitVar_assignment的监听器方法无法触发。语法已验证可用,监听器按官方示例编写。
可正常运行的代码
func (f *FSLListener) EnterEveryRule(ctx antlr.ParserRuleContext) { fmt.Printf("EnterEveryRule %v\n", ctx.GetText()) }
无法触发的代码
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) error { fmt.Printf("Complete var assignment: %s\n", ctx.GetText()) return nil }
Parser Grammar
parser grammar fslParser; options { tokenVocab=fslLexer; } r: script* EOF; script: var_assignment* init_function function_definition*; var_assignment: VAR VALUE; init_function: INIT cmd_list RBRACK; function_definition: VALIDFUNCTIONID cmd_list RBRACK; cmd_list: (cmd_expression)*; cmd_expression: CMD FUNCTIONCALL | CMD FUNCTIONCALLWITHARGS param_list //function call | CMD VARREF COMMA param_list // variable reference | CMD builtin_functions param_list // user-defined function call ; builtin_functions: (CREATE | DELETE | UPDATE | ADD | SUBTRACT | MULTIPLY | DIVIDE | PRINT); param_list: ARG param (COMMA ARG param)*; param: VARREF | VALUE | LETTERS VALUE | VARPARAM | VARPARAM VALUE ;
Lexer Grammar
lexer grammar fslLexer; INIT : 'init: [' ; VALIDFUNCTIONID : [a-zA-Z]+ ': ['; VAR : 'var' [0-9]+':' ; VALUE : [0-9]+ ('.' [0-9]+)? ; CMD : 'cmd:' ; VARREF : '#var'[0-9]+ ; FUNCTIONCALL : '#' [a-zA-Z]+ ; FUNCTIONCALLWITHARGS : '#' [a-zA-Z]+',' ; VARPARAM : '$' [a-zA-Z]+ ; DIGITS: [0-9]+; LETTERS: [a-zA-Z]+; ARG: LETTERS DIGITS? COLON; // Define function names as keywords CREATE : 'create,' ; DELETE : 'delete,' ; UPDATE : 'update,' ; ADD : 'add,' ; SUBTRACT: 'subtract,' ; MULTIPLY: 'multiply,' ; DIVIDE : 'divide,' ; PRINT : 'print,' ; COLON : ':'; COMMA : ','; RBRACK : ']'; SPACE : [ \t\r\n]+ -> skip ;
测试输入示例
var1: 1 var2: 2 init: [ cmd: #setup ] setup: [ cmd: #sum, id: var1, value1: #var1, value2: #var2 cmd: #printAll ] sum: [ cmd: add, id: $id, operand1: $value1, operand2: $value2 ] printAll: [ cmd: print, value: #var1 cmd: print, value: #var2 cmd: print, value: #var3 ]
排查与解决方案
1. 监听器方法签名错误
ANTLR4 Go目标生成的Listener接口中,ExitXXX方法无返回值。当前方法带有error返回类型,导致未正确实现接口,因此ANTLR不会调用该方法。
2. Context类型名称错误
ANTLR4 Go代码生成器会将语法中的下划线命名规则转换为驼峰命名:
- 语法中的
var_assignment规则,生成的Context类型是VarAssignmentContext,而非Var_assignmentContext。参数类型不匹配会导致方法无法被识别为接口实现。
修正后的代码
func (f *FSLListener) ExitVarAssignment(ctx *parser.VarAssignmentContext) { fmt.Printf("Complete var assignment: %s\n", ctx.GetText()) }
额外验证步骤
- 运行代码生成命令时,确保使用最新版ANTLR4 Go目标生成器,避免版本兼容性问题。
- 尝试添加
EnterVarAssignment方法,验证规则是否被正确解析。
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

