Closed jwilk closed 8 years ago
I'm not sure I understand why this causes unbound recursion :-(
The relevant code is:
def next(self):
if self.idx >= len(self.s):
raise StopIteration
for rule in self.lexer.ignore_rules:
match = rule.matches(self.s, self.idx)
if match:
self._update_pos(match)
return self.next()
...
CPython doesn't do tail recursion elimination, so if there's N consecutive ignorable tokens in the input, N stack frames will be consumed. If N is big enough (1000 in my reproducer), you get a recursion error. To fix this, use a while loop instead of recursion:
def next(self):
while True:
if self.idx >= len(self.s):
raise StopIteration
for rule in self.lexer.ignore_rules:
match = rule.matches(self.s, self.idx)
if match:
self._update_pos(match)
break
else:
break
...
(untested, sorry!)
Ugh, right, I forgot how I implemented ignores. Will try to fix this tonight.
On Wed, Feb 24, 2016 at 9:39 AM, Jakub Wilk notifications@github.com wrote:
The relevant code is:
def next(self): if self.idx >= len(self.s): raise StopIteration for rule in self.lexer.ignore_rules: match = rule.matches(self.s, self.idx) if match: self._update_pos(match) return self.next() ...
CPython doesn't do tail recursion elimination, so if there's N consecutive ignorable tokens in the input, N stack frames will be consumed. If N is big enough (1000 in my reproducer), you get a recursion error. To fix this, use a while loop instead of recursion:
def next(self): while True: if self.idx >= len(self.s): raise StopIteration for rule in self.lexer.ignore_rules: match = rule.matches(self.s, self.idx) if match: self._update_pos(match) break else: break ...
(untested, sorry!)
— Reply to this email directly or view it on GitHub https://github.com/alex/rply/issues/52#issuecomment-188282161.
"I disapprove of what you say, but I will defend to the death your right to say it." -- Evelyn Beatrice Hall (summarizing Voltaire) "The people's good is the highest law." -- Cicero GPG Key fingerprint: 125F 5C67 DFE9 4084
This test program
makes the Python interpreter sad: