3

I am trying to define a simple functional language grammar, I am almost done with my definitions, but I can't get past the following ambiguities.

[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ATOM" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input 

[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ID" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input

here are what I think are the relevant rules the drawing is almost identical for ATOM and ID:

program : (statement'.')* ;

statement : assignment
          | expression;

assignment : func '->' statement ((','statement)=> ',' statement)*
           | ID '->' expression
           | ATOM '->' ( string | number ); 

func : (ID '(' args ')')=> ID '(' args ')'; 

term : func
     | '(' expression ')'  
     | number
     | string
     | ID
     | ATOM ;

ATOM : ('A'..'Z'|'_')+;

ID : ('a'..'z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

here is the syntax tree from ANTLRWorks

id alternatives http://www.vertigrated.com/images/id_alternatives.png

Here is a rough straw man of what I am trying to support parsing.

hypotenuse(a,b) -> 
  sqr(x) -> x * x,
  sqr(sqr(a) + sqr(b)). 

print(hypotnenuse(2,3)).

so I need to be able to support nesting statements inside of functions

where -> is my assignment operator, this is a single assignment language

where . is my statement end marker

Is this even possible to parse with ANTLR3?

  • This is the same problem as in your [previous question](http://stackoverflow.com/questions/8125141/how-to-get-rid-of-the-following-multiple-alternatives-warnings-in-my-antlr3-gram): the grammar is ambiguous and therefor the generated parser can choose more than one parse for a particular input. Eliminate the ambiguity by placing predicates where needed (not preferable), or change the grammar so that it's not ambiguous anymore (preferable). – Bart Kiers Nov 14 '11 at 21:09
  • By explaining in your [previous question](http://stackoverflow.com/questions/8125141/how-to-get-rid-of-the-following-multiple-alternatives-warnings-in-my-antlr3-gram) how a certain input can be parsed into two different parse trees, I had hoped you'd have a handle on how to fix this yourself... – Bart Kiers Nov 14 '11 at 21:11
  • @BartKiers I didn't fully grok your explaination, I understand that there is an ambiguity, I just don't understand where to put the predicates. I have Googled the syntactical predicates and read them all, I can't figure out where to put the predicates or how to change the grammar to make it non-ambiguous without putting extraneous characters where I don't want them. Everytime I change something it seems to make it worse not better :-( –  Nov 14 '11 at 21:29
  • Here is a link to the complete grammar ... remember I am a newbie at this https://gist.github.com/1365264 –  Nov 14 '11 at 21:38
  • If you don't understand something about my answer, please say so. If you don't, I assume it's all clear. – Bart Kiers Nov 14 '11 at 22:11
  • I have tried to explain the problem in your other question. The key here is that you can't just _not_ use "extraneous characters": you need them to properly define your language. If you don't want extra printable chars, then at least go for line-breaks as end-of-statement tokens. You just have to do something to remove all the ambiguities. – Bart Kiers Nov 14 '11 at 22:19
  • @BartKiers I guess I need to know if the syntax in the example I want to use is even possible with ANTLR3? –  Nov 15 '11 at 04:49
  • @fututre readers possibly looking looking for an answer, also asked here: http://antlr.markmail.org/message/x3fj2zegvtnfrmh3 – Bart Kiers Nov 15 '11 at 06:39

1 Answers1

2

Some tips to make your grammar less ambiguous:

  1. remove the '.' as an end-of-statement char. Replace it with, say, a ';'. Both are just one character, and a ';' does not conflict with the '.' inside a float;
  2. create a lexer rule that matches a float;
  3. a function is followed by one or more statements, but has no obvious end (except for the "main" function which now ends with a '.'). You must either tell your parser where a function ends (not just the "main" function), or must introduce a rule that matches an "inner" function that does not have multiple trailing statements, but a single expression;
  4. do you really need a expression in your statement rule? Both can be a function (makein it, again, ambiguous).

These are just a few of the problems with the way you've defined your language. If I were you, I wouldn't continue this way: you might fix some things with predicates, but altering something on another place will open yet another can of worms. I advise you redesign your language drastically.

If you don't want to redesign it, simply remove all predicates from your grammar and put the following line in your options {...} section:

backtrack=true;

which will (seemingly) magically remove all warnings regarding ambiguous rules, but this is not a recommended fix. That way, ANTLR will choose parse trees for you when it encounters an ambiguity, (highly) possibly resulting in unexpected behavior, and for large input, it results in longer parse times. Again, this is not what I'd go for! See the Wiki for more info regarding global backtracking: http://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • I finally understand, the ambiguity is at the end of the `function` assignment definition not at the `start` which was throwing me off, thanks for persisting with your explanations I think I finally get what the problem is and how to begin to solve it. –  Nov 15 '11 at 15:57
  • @JarrodRoberson, you're welcome. I understand that it's not easy to fully grasp where the ambiguity exactly originates. The end of the function is just one of the ambiguities in your grammar however... Good luck! – Bart Kiers Nov 15 '11 at 16:11