Comment 1 for bug 310640

Revision history for this message
Enrico (ricercar) wrote :

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>)
"""