recursion loop in compose(a production derived from a scalar with a tuple grammar)

Issue #14 invalid
Anonymous created an issue

parse works as expected, compose crashes from infinite recursion in compose_tuple:

from __future__ import unicode_literals                  
from __future__ import print_function

import pypeg2 as p
import re

def doit(T):

  class P(T):
    grammar = '.', p.blank, T, p.endl

  ex = P(T(42))

  try:
    rv = p.compose(ex), repr(ex)
  except RuntimeError, e:
    assert None, e
  else:
    assert '. 42\n' == rv

def testInt():
  return doit(int)

def testStr():
  return doit(p.str)

result:

FF
======================================================================
FAIL: tuple-warning.testInt
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/roman/wc/pypeg-bugs/tuple-warning.py", line 22, in testInt
    return doit(int)
  File "/home/roman/wc/pypeg-bugs/tuple-warning.py", line 17, in doit
    assert None, e
AssertionError: maximum recursion depth exceeded while calling a Python object

======================================================================
FAIL: tuple-warning.testStr
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/roman/wc/pypeg-bugs/tuple-warning.py", line 25, in testStr
    return doit(p.str)
  File "/home/roman/wc/pypeg-bugs/tuple-warning.py", line 17, in doit
    assert None, e
AssertionError: maximum recursion depth exceeded while calling a Python object

----------------------------------------------------------------------
Ran 2 tests in 0.098s

FAILED (failures=2)

letting the RuntimeError escape:

  File "/home/roman/wc/pypeg-bugs/tuple-warning.py", line 21, in testStr
    return doit(p.str)
  File "/home/roman/wc/pypeg-bugs/tuple-warning.py", line 14, in doit
    rv = p.compose(ex), repr(ex)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 584, in compose
    return parser.compose(thing, grammar)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1161, in compose
    result = compose_tuple(thing, L, grammar)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1134, in compose_tuple
    text.append(self.compose(things.pop(), g))
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1192, in compose
    result = self.compose(thing)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1161, in compose
    result = compose_tuple(thing, L, grammar)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1134, in compose_tuple
    text.append(self.compose(things.pop(), g))
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1192, in compose
    result = self.compose(thing)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1161, in compose
    result = compose_tuple(thing, L, grammar)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1134, in compose_tuple
    text.append(self.compose(things.pop(), g))
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1192, in compose
    result = self.compose(thing)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1161, in compose
    result = compose_tuple(thing, L, grammar)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1134, in compose_tuple
    text.append(self.compose(things.pop(), g))
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1192, in compose
    result = self.compose(thing)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1161, in compose
    result = compose_tuple(thing, L, grammar)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1134, in compose_tuple
    text.append(self.compose(things.pop(), g))
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1192, in compose
    result = self.compose(thing)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1161, in compose
    result = compose_tuple(thing, L, grammar)
...
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1134, in compose_tuple
    text.append(self.compose(things.pop(), g))
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1192, in compose
    result = self.compose(thing)
  File "/usr/local/lib/python2.7/site-packages/pypeg2/__init__.py", line 1059, in compose
    elif isinstance(grammar, (RegEx, _RegEx)):

Comments (4)

  1. Volker Birk repo owner

    Your sample cannot work. What should the "str" in the grammar do? Maybe you're searching for something like this?

    class T(str): grammar = '.', blank, word, endl
    
    >>> compose(T("hello"))
    '. hello\n'
    >>> _
    
  2. Volker Birk repo owner

    I'm not fully understanding what you're trying to achive. Probably something like this?

    from pypeg2 import *
    
    class Str(str): grammar = word
    
    class Int(int): grammar = re.compile(r"\d+")
    
    class P(T):
        grammar = '.', blank, T.grammar, endl
    
  3. Volker Birk repo owner

    BTW:

    from pypeg2 import *
    
    def f(g):
        return '.', blank, g, endl
    
    class Str(str): grammar = f(word)
    
    class Int(int): grammar = f(re.compile(r"\d+"))
    
  4. Log in to comment