1

I have a simple rule in ANTLR:

title returns [ElementVector<Element> v]
@init{

    $v = new ElementVector<Element>() ;

}
    :   '[]'    
    |   '[' title_args {$v.add($title_args.ele);} (',' title_args {$v = $title_args.ele ;})* ']' 
    ;

with title_args being:

title_args returns [Element ele]
    :   author {$ele = new Element("author", $author.text); }
    |   location {$ele = new Element("location", $location.text); }
    ;

Trying to compile that I get confronted with a 127 error in the title rule: title_args is a non-unique reference.

I've followed the solution given to another similar question in this website (How to deal with list return values in ANTLR) however it only seems to work with lexical rules.

Is there a specific way to go around it ?

Thank you, Christos

Community
  • 1
  • 1

3 Answers3

3

You have 2 title_args in your expression, you need to alias them. Try this:

|   '[' t1=title_args {$v.add($t1.ele);} (',' t2=title_args {$v = $t2.ele ;})* ']' 

t1 and t2 are arbitrary aliases you can choose anything you want as long as they match up.

Ted Elliott
  • 3,415
  • 1
  • 27
  • 30
0

I think the problem is your reusing the title_args var. Try changing one of those variable names.

Jorn
  • 20,612
  • 18
  • 79
  • 126
0

Yeah, I had the same problem. You need to change one of the variable names; for example, do like the following:

title_args
title_args1

in your code instead of using title_args twice.

If title_args is a parser rule, then just create the same rule with the name title_args1. So, basically there would be two rules with the same functionality.

eeerahul
  • 1,629
  • 4
  • 27
  • 38
loki
  • 1
  • 1
    This is a hack and bad advice. The right answer is the one above, declare a variable name for each production using = and then reference that. – user430788 Nov 07 '11 at 01:54