title: Pyparsing - grammar with recursion
body: <p>I am trying to create grammar which will parse the following expressions:</p>
  
  <ol>
  <li><p><code>func()</code></p></li>
  <li><p><code>func(a)</code></p></li>
  <li><p><code>func(a) + func(b)</code></p></li>
  <li><p><code>func(func(a) + func()) + func(b)</code></p></li>
  </ol>
  
  <p>I implemented it for (1) and (2), but once I extended <code>rvalue &lt;&lt; (identifier | function_call)</code> by <code>operation</code>, it stopped working due to:</p>
  
  <pre><code>Exception raised:Expected W:(ABCD...), found ')'  (at char 5), (line:1, col:6)
  Exception raised:maximum recursion depth exceeded
  </code></pre>
  
  <p>Can anyone of you explain why? As far as I understood in expression <code>rvalue &lt;&lt; (identifier | function_call | operation)</code>  <code>function_call</code> should be matched before <code>operation</code> and the recursion shouldn't take place.</p>
  
  <p><strong>Code:</strong></p>
  
  <pre><code>from pyparsing import Forward, Optional, Word, Literal, alphanums, delimitedList
  
  rvalue = Forward()
  
  operation = rvalue + Literal('+') + rvalue
  identifier = Word(alphanums + '_')('identifier')
  function_args = delimitedList(rvalue)('function_args')
  
  function_name = identifier('function_name')
  function_call = (
      (function_name + Literal("(") + Optional(function_args) + Literal(")"))
  )('function_call')
  
  rvalue &lt;&lt; (identifier | function_call | operation)
  function_call.setDebug()
  
  
  def test_function_call_no_args():
      bdict = function_call.parseString("func()", parseAll=True).asDict()
      assert bdict['function_name'] == 'func'
      assert 'function_args' not in bdict
  
  
  def test_function_call_one_arg():
      bdict = function_call.parseString("func(arg)", parseAll=True).asDict()
      assert bdict['function_name'] == 'func'
      assert 'function_args' in bdict
  
  
  def test_function_call_many_args():
      bdict = function_call.parseString("func(arg1, arg2)", parseAll=True).asDict()
      assert bdict['function_name'] == 'func'
      assert 'function_args' in bdict
  </code></pre>