ANTLR4解析器中用Java System.out.println直接生成XML报错如何解决
错误原因及解决方案
1. 编译报错的直接原因
你在message规则的内嵌Java代码中,给规则返回值value赋值时没有加$前缀。ANTLR规定访问规则自身的返回值必须使用$value格式,不加前缀时ANTLR会将其识别为生成的MyParser类的普通成员变量,自然找不到对应符号,触发编译错误。
2. 其他隐藏问题修正
你当前的代码还存在几个问题会导致输出不符合预期:
- 使用
message+匹配多条消息时,直接拼接$message.value只会拿到最后一条消息的返回值,需要循环拼接所有消息的结果 - 需求要求人名对应标签为
<person>,你的代码中写的是<name>,标签不匹配 - 定义了
EOL词法规则但没有在语法规则中处理,匹配多行内容时会报错 - 缺少缩进、换行逻辑,输出格式和示例要求不符
修正后的完整代码
词法规则文件MyLexer.g4(无修改,保持即可)
lexer grammar MyLexer; GREETING : ('Hello' | 'Greeting') ; ID : [a-zA-Z]+ ; WS : [ \t]+ -> skip ; EOL : [\r\n]+ ;
解析器规则文件MyParser.g4(核心修改点)
parser grammar MyParser; options { tokenVocab=MyLexer; } document @init { StringBuilder allMsg = new StringBuilder(); } // 初始化字符串拼接容器 : (message EOL { allMsg.append($message.value).append("\n"); })+ { System.out.println("<messages>"); System.out.print(allMsg); System.out.println("</messages>"); } ; message returns [String value] : GREETING ID { $value = " <message>\n" +" <greeting>"+$GREETING.text+"</greeting>\n" +" <person>"+$ID.text+"</person>\n" +" </message>"; } ;
修正点说明
message规则中返回值赋值改为$value = xxx,直接解决编译报错- 给
document规则新增初始化的StringBuilder,循环拼接所有匹配到的消息内容 - 补充
EOL匹配逻辑,支持多行输入解析 - 将
<name>标签改为需求要求的<person>,同时增加缩进、换行逻辑,输出结果和示例完全一致 - 外层
<messages>标签单独打印,格式更清晰
内容的提问来源于stack exchange,提问作者Roger Costello
相关产品推荐
相关产品推荐

