[antlr-interest] Return Values

John B. Brodie jbb at acm.org
Sun May 15 09:13:50 PDT 2011


Greetings!

On Sun, 2011-05-15 at 16:11 +0200, Bart Kiers wrote:
> Hi Philip,
> 
> You can't since aParserToken will be initialized as a
> org.antlr.runtime.Token type.
> You will have to do it (the hard way) like this:
> 
> parserRule0
>   :  ( parserRule1
> {DoSomethingWithTheReturnValue($parserRule1.returnValue);}
>      | parserRule2
> {DoSomethingWithTheReturnValue($parserRule2.returnValue);}
>      | parserRule3
> {DoSomethingWithTheReturnValue($parserRule3.returnValue);}
>      )
>   ;
> 

if your processing of the sub-rules' return value is more complicated
than just a simple method call you might want to keep a single action at
the end of the rule and gather up the return values along the way.

something like this (tested):

test_1 @init{ String a = "test_1"; }
   : (x_1{a=$x_1.retVal;} | y_1{a=$y_1.retVal;} | z_1{a=$z_1.retVal;})
      { System.out.println(a); } ;

x_1 returns [String retVal] : 'x' { $retVal = "x_1"; } ;
y_1 returns [String retVal] : 'y' { $retVal = "y_1"; } ;
z_1 returns [String retVal] : 'z' { $retVal = "z_1"; } ;

another possibility is to use a Scope.

note that I have not used Scopes very much, so I may be way off base
here.

something like this (tested, test rig attached):

test_2 scope { String retVal; } @init{ $test_2::retVal = "test_2"; }
   : (x_2 | y_2 | z_2) { System.out.println($test_2::retVal); } ;

x_2 : 'x' { $test_2::retVal = "x_2"; } ;
y_2 : 'y' { $test_2::retVal = "y_2"; } ;
z_2 : 'z' { $test_2::retVal = "z_2"; } ;

Hope this helps...
   -jbb

> 
> Regards,
> 
> Bart.
> 
> 
> On Sun, May 15, 2011 at 12:09 AM, Philip Mötteli
> <Philip.Moetteli at tele2.ch>wrote:
> 
> > Hi,
> >
> >
> > I know, how to access a return value from a parser rule/token: By calling
> > "$rule.returnValue". E. g:
> >
> > parserRule0     :       parserRule1
> >                                {
> > DoSomethingWithTheReturnValue($parserRule1.returnValue);        }
> >                        ;
> >
> >
> > But how do I access the return value, if it's one of several options
> > ('or'ed together):
> >
> > parserRule0     :       aParserToken=( parserRule1 | parserRule2 |
> > parserRule3 )
> >                                {       // How do I access
> > "$aParserToken.returnValue"? }
> >                        ;
> >
> >
> > Thanks for any help
> >
> >
> > List: http://www.antlr.org/mailman/listinfo/antlr-interest
> > Unsubscribe:
> > http://www.antlr.org/mailman/options/antlr-interest/your-email-address
> >
> 
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address


-------------- next part --------------
grammar Test;

options {
   output = AST;
   ASTLabelType = CommonTree;
}

// tokens { /* imaginary tokens go here */ }

@members {
   private static final String [] x = new String[] {
      "1 x y z",
      "2 x y z",
      "1 x y z 2 x y z"
   };

   public static void main(String [] args) {
      for( int i = 0; i < x.length; ++i ) {
         try {
            System.out.println("about to parse:`"+x[i]+"`");

            TestLexer lexer = new TestLexer(new ANTLRStringStream(x[i]));
            CommonTokenStream tokens = new CommonTokenStream(lexer);

            TestParser parser = new TestParser(tokens);
            TestParser.prog_return p_result = parser.prog();

            // System.out.format("the token stream:\%n");
            // for( int j = 0; j < tokens.size(); ++j ) {
            //    Token token = tokens.get(j);
            //    System.out.format("\%d: type = \%s, text = `\%s`\%n",
            //                      j,
            //                      tokenNames[token.getType()],
            //                      token.getText());
            // }

            CommonTree ast = p_result.tree;
            if( ast == null ) {
               System.out.println("resultant tree: is NULL");
            } else {
               System.out.println("resultant tree: " + ast.toStringTree());
            }
            System.out.println();
         } catch(Exception e) {
            e.printStackTrace();
         }
      }
   }
}

prog : test+ EOF! ;

test : ('1' test_1+) | ('2' test_2+);

// one possibility, not using scopes...
test_1 @init{ String a = "test_1"; }
   : ( x_1 {a=$x_1.retVal;} | y_1 {a=$y_1.retVal;} | z_1 {a=$z_1.retVal;} )
      { System.out.println(a); } ;

x_1 returns [String retVal] : 'x' { $retVal = "x_1"; } ;
y_1 returns [String retVal] : 'y' { $retVal = "y_1"; } ;
z_1 returns [String retVal] : 'z' { $retVal = "z_1"; } ;

test_2 scope { String retVal; } @init{ $test_2::retVal = "test_2"; }
   : (x_2 | y_2 | z_2) { System.out.println($test_2::retVal); } ;

x_2 : 'x' { $test_2::retVal = "x_2"; } ;
y_2 : 'y' { $test_2::retVal = "y_2"; } ;
z_2 : 'z' { $test_2::retVal = "z_2"; } ;

fragment DIGIT : '0'..'9';
fragment LETTER : 'a'..'z' | 'A'..'Z' ;

IDENT : LETTER ( LETTER | DIGIT | '_' )* ;
INT : DIGIT+ ;

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



More information about the antlr-interest mailing list