In a grammar that defines optional rules (see SQL-ANSI-89.grm) the number of rules can be greatly reduced by defining rules that may be empty.
<Constraint Opt> ::= <Constraint>
|
However the rule <Constraint Opt> can sometimes contain no token on the stack when it is reduced.
The problem in the code is in the method Parser::reduce
the rule length is obviously 0 but when the code calls
self._tempstack.popTokensInto(reduction, len(rule))
while you would expect the code to pop 0 tokens from the stack you actually find that the code does the following: TokenStack::popTokensInto(reduction, count)
del self.items[-count:]
effectively ruining the stack and causing the parser to fail on the next token.
I suggest to add a test in popTokensInto
if count == 0:
return
---------------------------------------------------
def popTokensInto(self, reduction, count):
''' Pops 'count' tokens from the stack and appends them
to specified 'reduction'.
Returns None.
'''
if count == 0:
return
l = self.items[-count:]
del self.items[-count:]
for i in l:
reduction.append(i)