Search code examples
pyparsing

Infinite loop while trying simple indentedBlock expression in pyparsing


I'm trying to parse indented blocks with pyparsing and indentedBlock

Here my code

from pyparsing import *

indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))

# Work
data = """  foo
  bar
  tar
"""

block.parseString(data).pprint()

The problem is that parseString won't return. It seems to be waiting for more input or maybe I hit an infinite loop. If I put an unidnented line in the block start to work

data = """  foo
  bar
  tar

end
"""

But I want to be able to parse up to unindented line (the working case), or to the end of string (the not working case)


Solution

  • This is a bug in pyparsing. indentedBlock uses OneOrMore internally to implement the repetition of the embedded lines. But restOfLine does not fail if it is at the end of a line, and so once you get to the end of the string, indentedBlock's repetition just keeps finding empty restOfLines, and so indentedBlock just loops forever.

    A workaround for now, until this bug gets fixed and released, is to change your definition of line from:

    line = ungroup(restOfLine)
    

    to

    line = ungroup(~StringEnd() + restOfLine)