Reputation: 1770
Could you explain why the second execution of exactly the same parseString
throws the pyparsing.ParseException: not a subentry
exception, please?
Code:
from pyparsing import *
from pprint import pprint
indentStack = [1]
stmt = Forward()
suite = indentedBlock(stmt, indentStack)
funcDecl = "def" + Word(printables)
funcDef = Group( funcDecl + suite )
stmt << ( funcDef | "open" | "close")
module_body = OneOrMore(stmt)
code="""\
def process
open
close"""
# first execution - works fine, but modifies funcDef
pprint(funcDef)
f1 = funcDef.parseString(code)
pprint(f1)
# second execution
pprint(funcDef)
f2 = funcDef.parseString(code) ### throws pyparsing.ParseException: not a subentry (at char 16), (line:2, col:5)
pprint(f2)
pyparsing.ParseException: not a subentry (at char 16), (line:2, col:5)
I tried to simplify the the example available in the pyparsing wiki: http://pyparsing.wikispaces.com/file/view/indentedGrammarExample.py
Full stacktrace: https://pastebin.com/QXF5ZJZ7
Link to the documentation of parseString
: https://pythonhosted.org/pyparsing/pyparsing.ParserElement-class.html#parseString
I extended the code by pprint(funcDef)
and I found out that after the first execution of
funcDef.parseString(code)
the definition of funcDef
has changed from:
from:
Group:({{"def" W:(0123...)} indented block})
to:
Group:({"def" W:(0123...) indented block})
Adding indentStack.pop()
before the 2nd execution of funcDef.parseString(code)
solved the problem.
It's worth to mention that it's indentStack = [1]
does not solve the problem. It's very interesting case so I created two snippets to show the difference (I also added few extra debug print's into the library):
indentStack = [1]
: https://pastebin.com/adPiuE8CindentStack.pop()
: https://pastebin.com/dzWkdjniUpvotes: 3
Views: 122
Reputation: 1770
In this case stack is multiple levels deep.
Adding indentStack[:] = [1]
before the 2nd execution of funcDef.parseString(code)
solved the problem.
Upvotes: 1