Craiten
Craiten

Reputation: 109

Antlr 3.3 return values in java

I try to figure out how to get values from the parser. My input is 'play the who' and it should return a string with 'the who'.

Sample.g:

text returns [String value]
 : speech = wordExp space name {$value = $speech.text;}
 ;

name returns [String value] 
 : SongArtist = WORD (space WORD)*  {$value = $SongArtist.text;}
 ;

wordExp returns [String value] 
 : command = PLAY {$value = $command.text;} | command = SEARCH {$value = $command.text;}
 ; 

PLAY   : 'play';
SEARCH : 'search';
space : ' ';

WORD : ( 'a'..'z' | 'A'..'Z' )*; 


WS  
 : ('\t' | '\r'| '\n') {$channel=HIDDEN;}
 ;

If I enter 'play the who' that tree comes up:

https://i.sstatic.net/ET61P.png

I created a Java file to catch the output. If I call parser.wordExp() I supposed to get 'the who', but it returns the object and this EOF failure (see the output below). parser.text() returns 'play'.

import org.antlr.runtime.*;

import a.b.c.SampleLexer;
import a.b.c.SampleParser;

public class Main {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("play the who");

        SampleLexer lexer = new SampleLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        SampleParser parser = new SampleParser(tokens);

        System.out.println(parser.text());
        System.out.println(parser.wordExp());
    }
}

The console return this:

play
a.b.c.SampleParser$wordExp_return@1d0ca25a
line 1:12 no viable alternative at input '<EOF>'

How can I catch 'the who'? It is weird for me why I can not catch this string. The interpreter creates the tree correctly.

Upvotes: 1

Views: 442

Answers (1)

Marc Q.
Marc Q.

Reputation: 551

First, in your grammar, speech only gets assigned the return value of parser rule wordExp. If you want to manipulate the return value of rule name as well, you can do this with an additional variable like the example below.

text returns [String value]
 : a=wordExp space b=name {$value = $a.text+" "+$b.text;}
 ;

Second, invoking parser.text() parses the entire input. A second invocation (in your case parser.wordExp()) thus finds EOF. If you remove the second call the no viable alternative at input 'EOF' goes away.

There may be a better way to do this, but in the meantime this may help you out.

Upvotes: 1

Related Questions