Reputation: 3209
The input file that I want to parse consists of one or more rows and each row consists of a greeting (Hello or Greeting) followed by a person's first name. Here is a sample input:
Hello Roger
Greeting Sally
I want to create a parser that outputs XML. For the sample input I want the parser to generate this XML:
<messages>
<message>
<greeting>Hello</greeting>
<person>Roger</person>
</message>
<message>
<greeting>Greeting</greeting>
<person>Sally</person>
</message>
</messages>
I want the XML generated directly within the parser file (MyParser.g4) using Java System.out.println
Here is my lexer:
lexer grammar MyLexer;
GREETING : ('Hello' | 'Greeting') ;
ID : [a-zA-Z]+ ;
WS : [ \t]+ -> skip ;
EOL : [\n] ;
Here is my parser:
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 ran ANTLR on the lexer and parser and then compiled the Java code that ANTLR generated. This resulted in the following error message.
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
What am I doing wrong, please?
Upvotes: 2
Views: 155
Reputation: 170178
You forgot the $
before value
, it must be: $value = "<message><greeting>" + …
.
And you also want to print every message
, so not:
message+ {System.out.println( … );}
which will print just once, but like this instead:
(message {System.out.println( … );})+
This ought to do it:
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>";
}
;
Can be tested like this:
String source = "Hello Roger\nGreeting Sally";
MyLexer lexer = new MyLexer(CharStreams.fromString(source));
MyParser parser = new MyParser(new CommonTokenStream(lexer));
parser.document();
Upvotes: 2