2

I'm trying to create a parser using Treetop that is somewhat recursive. An expression can be a number but it also can be an addition of expressions, so I wrote this:

grammar Language
  rule expression
    "(" _ expression _ ")" / addition / integer 
  end

  rule addition
    expression _ "+" _ expression
    /
    expression _ "-" _ expression
  end

  rule integer
    '-'? _ [0-9]+
  end

  # space
  rule _
   ' '*
  end
end

That just doesn't work. Any time I'm trying to parse anything I get an exception "SystemStackError: stack level too deep" (stack overflow! yay!). Any ideas why? what's the correct way to specify such a recursive definition with Treetop?

Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622

1 Answers1

2

You grammar is left-recursive: i.e. a expression can immediately be an addition which in its turn can be an expression etc. causing the parser to go in an infinite loop.

Try something like this instead (untested!):

grammar Language

  rule expression
    addition
  end

  rule addition
    multiplication (_ [+-] _ multiplication)*
  end

  rule multiplication
    unary (_ [*/%] _ unary)*
  end

  rule unary
    "-"? _ atom
  end

  rule atom
    number / "(" _ expression _ ")"
  end

  rule number
    float / integer
  end

  rule float
    [0-9]+ "." [0-9]+
  end

  rule integer
    [0-9]+
  end

  rule _
    ' '*
  end

end
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • Doesn't that mean that everything I parse will be an addition and a multiplication (albeit with nothing)? – Pablo Fernandez Jul 13 '11 at 09:42
  • Yes, you simply take no action inside your `addition` rule if the `*` matches nothing in which case you return what the (leftmost) `multiplication` returns. This is the way it's done with LL grammars/parsers. – Bart Kiers Jul 13 '11 at 09:46