如何使用 Java System.out.println 在解析器中直接生成 XML

How to generate XML directly within the parser using Java System.out.println

我要解析的输入文件由一行或多行组成,每行包含一个问候语(你好或问候语),后跟一个人的名字。这是一个示例输入:

Hello Roger
Greeting Sally

我想创建一个输出 XML 的解析器。对于示例输入,我希望解析器生成此 XML:

<messages>
    <message>
        <greeting>Hello</greeting>
        <person>Roger</person>
    </message>
    <message>
        <greeting>Greeting</greeting>
        <person>Sally</person>
    </message>
</messages>

我想使用 Java System.out.println

在解析器文件 (MyParser.g4) 中直接生成 XML

这是我的词法分析器:

lexer grammar MyLexer;

GREETING : ('Hello' | 'Greeting') ;
ID  : [a-zA-Z]+ ;
WS  : [ \t]+ -> skip ;
EOL : [\n] ;

这是我的解析器:

parser grammar MyParser;

options { tokenVocab=MyLexer; }

document:  (message+ {System.out.println("<messages>" + $message.value + "</messages>");});

message returns [String value]: (GREETING ID {value = "<message><greeting>" + $GREETING.text + "</greeting><name>" + $ID.text + "</name></message>";}) ;

I 运行 ANTLR 在词法分析器和解析器上,然后编译 ANTLR 生成的 Java 代码。这导致了以下错误消息。

MyParser.java:154: error: cannot find symbol
                        value = "<message><greeting>" + (((MessageContext)_localctx).GREETING!=null?((MessageContext)_localctx).GREETING.getText():null) + "</greeting><name>" + (((MessageContext)_localctx).ID!=null?((MessageContext)_localctx).ID.getText():null) + "</name></message>";
                        ^
  symbol:   variable value
  location: class MyParser

请问我做错了什么?

你忘了value前面的$,应该是:$value = "<message><greeting>" + ….

而且您还想打印每个 message,所以不是:

message+ {System.out.println( … );}

只打印一次,但像这样:

(message {System.out.println( … );})+

应该这样做:

parser grammar MyParser;

options { tokenVocab=MyLexer; }

document
 : {System.out.println("<messages>");}
   ( message EOL? {
     System.out.println("  " + $message.value);
   })+
   {System.out.println("</messages>");}
   EOF
 ;

message returns [String value]
 : GREETING ID {
     $value = "<message><greeting>" + $GREETING.text + "</greeting><name>" + $ID.text + "</name></message>";
   }
 ;

可以这样测试:

String source = "Hello Roger\nGreeting Sally";
MyLexer lexer = new MyLexer(CharStreams.fromString(source));
MyParser parser = new MyParser(new CommonTokenStream(lexer));
parser.document();