1

I am feeling quite nostalgic so I've decided to write an adventure game creator that allows complex sentences to be entered by the user.

I have hand rolled a lexer and parser that uses the visitor pattern and it works quite well, until I encountered a left-recursion issue with one of my BNF (Backus-Naur Form) rules:

object          ::= {adjective} noun 
                  | object AND {adjective} noun 

After removing the left-recursion by following this wiki entry does this look right?

object      ::= {adjective} noun object2
object2     ::= AND {adjective noun} 
              | !Empty

Edited:

I am hand rolling the lexer and parser using C# by following the guide given here. I an not using any parser generators for this exercise.

Also, I got the BNF rules for the parser from this website.

wintermute
  • 488
  • 1
  • 9
  • 22
Intrepid
  • 2,781
  • 2
  • 29
  • 54
  • It would be helpful if you explained what tools or algorithms you're using for parsing. Since you're having trouble with left recursion, I deduce that you're using recursive descent, which is fine, but it would be helpful to know for sure, and what parser generator (if any) you're using. – rob mayoff Jul 15 '13 at 08:28
  • I've updated my original question with further information. – Intrepid Jul 15 '13 at 08:36

2 Answers2

2

Is there any reason to prefer left-recursion over right recursion in this case? Wouldn't this be simpler:

object ::= {adjective} noun |
           {adjective} noun AND object

If you really want to make your solution work, you need to make object2 right-recursive:

object      ::= {adjective} noun object2
object2     ::= AND {adjective noun} object2 |
                !Empty
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Using left-recursion is resulting in a stack overflow error and I had to change the rule to use right-recursion to get around this. The original BNF rule for `object` only allows a single `AND`, that's why I haven't made `object2` right recursive. – Intrepid Jul 15 '13 at 08:31
  • The first BNF rule in your question allows one or more repetitions. It doesn't limit the input to two repetitions. – rob mayoff Jul 15 '13 at 08:59
  • Rob: Actually yes, you're quite correct it does allow or or more repetitions. My mistake! I am accepting your second answer after changing my code to follow this rule and it now works. Thanks! – Intrepid Jul 15 '13 at 09:21
2

Usually when I have this rule (yours):

object          ::= {adjective} noun | 
                    object AND {adjective} noun 

I apply the following transformations:

Stage 1 (still left recursion) -

object          ::= ad_noun | 
                    object AND ad_noun

ad_noun         ::=  {adjective} noun 

Stage 2 (change to right recursion) -

object          ::= ad_noun | 
                    ad_noun AND object

ad_noun         ::=  {adjective} noun 
Itay Maman
  • 30,277
  • 10
  • 88
  • 118