You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:54:54