如何在ANTLR4中格式化Token输出以显示自定义Token名称?
如何让ANTLR的grun命令输出自定义Lexer规则名称?
问题场景
执行ANTLR测试命令获取Token时:
$ grun TestLexer tokens -tokens myfile.sql
当前输出示例(最后一个TYPECAST规则的Token显示不符合预期):
[@0,0:5='SELECT',<'SELECT'>,1:0] [@1,7:7='1',<NUMBER>,1:7] [@2,9:12='with',<'WITH'>,2:0] [@3,14:20='my_data',<IDENTIFIER>,2:5] [@4,22:23='as',<'AS'>,2:13] [@5,25:25='(',<'('>,2:16] [@6,27:32='select',<'SELECT'>,2:18] [@7,34:40=''text1'',<STRING_TOKEN>,2:25] [@8,41:42='::',<'::'>,2:32]
用户已在TestLexer.g4中定义自定义Lexer规则:
// Cast operator, '2014-01-01'::DATE TYPECAST :'::' ;
希望将最后一个Token的输出改为:
[@8,41:42='::',<'TYPECAST(::)'>,2:32]
实现方法
ANTLR的grun工具默认的Token输出格式由Lexer的Token字符串表示逻辑决定,要实现自定义显示,可通过以下方式:
方法1:在.g4文件中添加自定义成员方法(以Java目标为例)
在TestLexer.g4中添加@lexer::members块,重写Token的显示逻辑:
@lexer::members { @Override public String getTokenDisplay(Token token) { String tokenText = token.getText(); String ruleName = this.getRuleNames()[token.getType()]; return String.format("%s(%s)", ruleName, tokenText); } }
添加后重新生成Lexer代码,再执行grun命令,输出的Token就会显示为<规则名称(Token文本)>的格式。
方法2:修改生成的Lexer类
直接修改ANTLR生成的Lexer类(比如TestLexer.java)中负责Token字符串输出的方法,将原有的仅显示Token文本的逻辑,替换为规则名称加Token文本的组合。
注:不同目标语言(如Python、C#)的具体实现细节略有差异,但核心思路都是自定义Token的字符串表示逻辑。
内容的提问来源于stack exchange,提问作者samuelbrody1249
相关产品推荐
相关产品推荐

