为何Antlr4的ErrorListener未触发SyntaxError方法?
问题诊断与解决方案
你遇到的核心问题是错误监听器的类型不匹配——你实现的是词法分析器(Lexer)专用的错误监听器接口,却把它注册到了解析器(Parser)上,导致解析器的语法错误无法触发你的回调方法。
具体原因
你定义的ReaderErrorListener实现了IAntlrErrorListener<IToken>,这个接口是专门给Lexer捕获词法错误(比如非法字符)用的。而你需要捕获的是Parser的语法错误(比如期望write却得到writqwee),Parser需要的是通用错误监听器或Parser专用的错误监听器接口。
修复步骤
1. 修改错误监听器的实现
将监听器改为继承BaseErrorListener(这是Antlr4提供的通用错误监听器基类,同时支持Lexer和Parser的错误捕获):
class ReaderErrorListener : BaseErrorListener { public override void SyntaxError(IRecognizer recognizer, object offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) { System.Diagnostics.Debug.WriteLine("Invalid Expressions: line {0}:{1} - {2}", line, charPositionInLine, msg); } }
2. 正确注册监听器
如果你需要同时捕获词法错误和语法错误,记得给Lexer也注册这个监听器;如果只关注语法错误,给Parser注册即可:
string str = "writqwee(path.subnode.field, 0xa5)"; // 处理Lexer(可选,若需要捕获词法错误) var lexer = new ReaderLexer(new AntlrInputStream(str)); lexer.RemoveErrorListeners(); lexer.AddErrorListener(new ReaderErrorListener()); // 处理Parser(核心) var tokens = new CommonTokenStream(lexer); var parser = new ReaderParser(tokens); parser.RemoveErrorListeners(); parser.AddErrorListener(new ReaderErrorListener()); var tree = parser.root();
额外验证点
确保你的Parser规则确实引用了TWO_ARG_KEYWORD,比如类似这样的定义:
root : TWO_ARG_KEYWORD '(' expression ',' expression ')' ;
只有当Parser明确期望TWO_ARG_KEYWORD时,输入writqwee(会被识别为普通标识符)才会触发语法错误。
内容的提问来源于stack exchange,提问作者NirMH
相关产品推荐
相关产品推荐

