1

I am trying to write an Expression Grammar where there are 3 operators '+','-' and '/'. The multiplication operator is implied by juxtaposition as in:

(1+2)(3+4 5)

Here is the Grammar:

S -> A ('+' A)*

A -> B ('-' B)*

B -> C ('/' C)*

C -> D ( D )*

D ->ID
    |Num
    |'(' S ')'

I am using Xtext which uses the ANTLR parser and it says this is left recursive on Rule C. If I were to change Rule 4 as

C -> D ('\*' D)*

Then error is eliminated. I am confused. Would like some help!

eliasah
  • 39,588
  • 11
  • 124
  • 154

1 Answers1

1

I don't know anything about Xtext, but Antlr 4 has no problem with this grammar:

grammar Expr; 
s: a ('+' a)* ;
a: b ('-' b)* ;
b: c ('/' c)* ;
c: d ( d )* ;
d: ID | NUM |'(' s ')' ;
ID: [a-z][a-z0-9]* ;
NUM: [0-9]+ ;
WS: [ \t\r\n]+ -> skip ;

When I compile and run your example (1+2)(3+4 5), I get this parse tree: parse tree

It may be Xtext is using an old version of Antlr. It's a great bit of software, but in older versions especially it's not perfect. This grammar is not left-recursive by the standard definition. It's possible Antlr is transforming it into a simpler grammar that is left recursive, but that would be a bug that's apparently been fixed.

So if my guess is correct, you'll be successful with the following explicitly "simplified" grammar:

grammar Expr; 
s: a ap ;
ap: '+' a ap | /* eps */ ;
a: b bp ;
bp: '-' b bp | /* eps */ ;
b: c cp ;
cp: '/' c cp | /* eps */ ;
c: d dp ;
dp: d dp | ;
d: ID | NUM |'(' s ')' ;
ID: [a-z][a-z0-9]* ;
NUM: [0-9]+ ;
WS: [ \t\r\n]+ -> skip ;

New parse tree:new parse tree

Gene
  • 46,253
  • 4
  • 58
  • 96
  • This is exactly the parse tree I would like to generate. However, I am stuck with Xtext which uses ANTLR 3.2, it seems. I would just like to know how to left factor this grammar. – Kartik Sayani Jul 01 '17 at 02:32
  • I think I will have to convince my group to switch to ANTLR 4. There are going to be a lot of such Left Recursions ahead. Thank You! – Kartik Sayani Jul 01 '17 at 02:37
  • You can't factor out left recursion because the grammar is not left-recursive. There must be a bug in ANTLR 3 that's causing it to rewrite into something that is left-recursive. Best guess is in rewriting the Kleene star operations as grammar rules. – Gene Jul 01 '17 at 02:37
  • @KartikSayani Thanks. I added a potential workaround. I'm interested in whether it works in your environment. – Gene Jul 01 '17 at 02:55
  • Thanks a lot. The Xtext still prompts a Left Recursion on Rule C and DP. I think the problem is with the parenthesis. Both C and DP call for D which calls for '(' S ')' and it recurses? – Kartik Sayani Jul 01 '17 at 03:41
  • By definition left recursion involves non-terminals in the leftmost position of rule right-hand-sides. The paren prevents that. This grammar would make a fine LL(1) parser. This is definitely a bug in ANTLR 3. – Gene Jul 01 '17 at 05:19
  • Either a bug in ANTLR 3 or something that Xtext doesn't allow. I'll check it out. Thank a lot! – Kartik Sayani Jul 01 '17 at 06:20
  • can you please tell me how you generated those parse trees? – Kartik Sayani Jul 01 '17 at 08:08
  • @KartikSayani See the example on the ANTLR web page. It's built in to ANTLR 4. – Gene Jul 01 '17 at 15:03