0

I'm trying to write a simple calculation grammar with Treetop. To simplify my example for this question, I'm only using variables, numbers and the + operator. I'd like to be able to write expressions like this:

  • A
  • 1
  • A+B
  • A+1
  • A+1+B

Here's my grammar:

grammar Calculation

  rule expression
    (plus / number / variable)
  end

  rule plus
    expression "+" expression
  end

  rule number
    '-'? [0-9]+ ('.' [0-9]+)?
  end

  rule variable
    [A-Za-z0-9]+
  end
end

When I run this, it infinitely recurses. After googling for a while, I think my problem has something to do with left-recursion, but I'm new to parsers and I don't really understand what that means. Could somebody explain why my particular example isn't working and how I can fix it?

LandonSchropp
  • 10,084
  • 22
  • 86
  • 149
  • Try this one: https://medium.com/@gvanrossum_83706/left-recursive-peg-grammars-65dab3c580e1 – rici Oct 09 '19 at 21:47
  • The treetop examples contain an arithmetic grammar, see my example at https://github.com/cjheath/treetop/blob/master/examples/lambda_calculus/arithmetic.treetop – cliffordheath Oct 10 '19 at 22:15
  • @rici Thanks for the link! That helps illustrate the problem, and I think I see some ways that could be applied in this particular case. – LandonSchropp Oct 11 '19 at 00:18
  • @cliffordheath Thanks for the link! Is there a link available to documentation on `head` and `tail`? – LandonSchropp Oct 11 '19 at 00:18
  • head and tail are just node labels, they can be anything, but this is my idiom for list-like structures (one or more). Labels are in the normal documentation for Treetop syntax. – cliffordheath Oct 11 '19 at 23:05
  • The original error is that the first thing `expression` tries is `plus`, and the first thing `plus` tries is `expression`, which both do without moving forward. This `left recursion` has nothing to stop it so it races away until the stack overflows. Left recursion can be ok, but you must consume something before recursing. – cliffordheath Oct 11 '19 at 23:09

1 Answers1

0

To avoid the left recursion, you can break up the expression rule into two parts like below:

grammar Calculation

  rule expression
    plus / symbol
  end

  rule symbol
     number / variable
   end

  rule plus
    symbol "+" expression
  end

  rule number
    '-'? [0-9]+ ('.' [0-9]+)?
  end

  rule variable
    [A-Za-z0-9]+
  end
end
Josh Voigts
  • 4,114
  • 1
  • 18
  • 43