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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:36:04