Arguments bug: is input rewind wrong?
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
PyMeta |
New
|
Undecided
|
Unassigned |
Bug Description
Hello, maybe this is a bug or there's something I don't understand. After some debug I found a simple example that shows the problem:
rule_x = """
first ::= <letter>:a <letter>:b => [a,b]
let :n ::= <first>:xs (<letter>:x ?(len(xs)<n+2) !(xs.append(x)))* => xs
two_or_three ::= (<let 2>:x <end>)|(<let 3>:x <end>)
"""
g = OMeta.makeGramm
print g('ab')
print g('abcc'
print g('abccc'
.....ParseError.
The problem is in "xs.append". If I omit this everything is fine. It seems that it is not possible to append a result to another one.
Inspecting the code with a debugger I can say that:
if the match with (<let 2>:x <end>) fails the input is not rewind properly, as in the last test
I think the problem is in runtime.py, line 194:
memoRec = self.input. setMemo( ruleName,
[ rule(), self.input])
If the result from rule() is a list or a mutable object, then it can be changed affecting the rest of the process in case a failure in the parser and a following rewind. At line 214 and 215 we have:
self.input = memoRec[1]
return memoRec[0]
i.e. we restore the input but we return a result, memoRec[1], that could have been changed.
A dirty solution is to rewrite my previous example as:
rule_x = """
first ::= <letter>:a <letter>:b => [a,b]
let :n :xx ::= <first>:xs (<letter>:x ?(xx or len(xx)<n+2) !(xx.append(x)))* => xs+xx
two_or_three ::= (<let 2 []>:x <end>)|(<let 3 []>:x <end>)
"""