fix #1955 for Python

This commit is contained in:
Eric Vergnaud 2018-11-18 19:41:47 +08:00
parent f6537bf4ac
commit 43e529ca73
2 changed files with 28 additions and 29 deletions

View File

@ -1145,11 +1145,6 @@ class ParserATNSimulator(ATNSimulator):
continueCollecting = collectPredicates and not isinstance(t, ActionTransition) continueCollecting = collectPredicates and not isinstance(t, ActionTransition)
c = self.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon) c = self.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon)
if c is not None: if c is not None:
if not t.isEpsilon:
if c in closureBusy:
# avoid infinite recursion for EOF* and EOF+
continue
closureBusy.add(c)
newDepth = depth newDepth = depth
if isinstance( config.state, RuleStopState): if isinstance( config.state, RuleStopState):
# target fell off end of rule; mark resulting c as having dipped into outer context # target fell off end of rule; mark resulting c as having dipped into outer context
@ -1158,23 +1153,28 @@ class ParserATNSimulator(ATNSimulator):
# come in handy and we avoid evaluating context dependent # come in handy and we avoid evaluating context dependent
# preds if this is > 0. # preds if this is > 0.
if c in closureBusy:
# avoid infinite recursion for right-recursive rules
continue
closureBusy.add(c)
if self._dfa is not None and self._dfa.precedenceDfa: if self._dfa is not None and self._dfa.precedenceDfa:
if t.outermostPrecedenceReturn == self._dfa.atnStartState.ruleIndex: if t.outermostPrecedenceReturn == self._dfa.atnStartState.ruleIndex:
c.precedenceFilterSuppressed = True c.precedenceFilterSuppressed = True
c.reachesIntoOuterContext += 1 c.reachesIntoOuterContext += 1
if c in closureBusy:
# avoid infinite recursion for right-recursive rules
continue
closureBusy.add(c)
configs.dipsIntoOuterContext = True # TODO: can remove? only care when we add to set per middle of this method configs.dipsIntoOuterContext = True # TODO: can remove? only care when we add to set per middle of this method
newDepth -= 1 newDepth -= 1
if ParserATNSimulator.debug: if ParserATNSimulator.debug:
print("dips into outer ctx: " + str(c)) print("dips into outer ctx: " + str(c))
elif isinstance(t, RuleTransition): else:
# latch when newDepth goes negative - once we step out of the entry context we can't return if not t.isEpsilon:
if newDepth >= 0: if c in closureBusy:
newDepth += 1 # avoid infinite recursion for EOF* and EOF+
continue
closureBusy.add(c)
if isinstance(t, RuleTransition):
# latch when newDepth goes negative - once we step out of the entry context we can't return
if newDepth >= 0:
newDepth += 1
self.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEofAsEpsilon) self.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEofAsEpsilon)

View File

@ -1150,11 +1150,6 @@ class ParserATNSimulator(ATNSimulator):
continueCollecting = collectPredicates and not isinstance(t, ActionTransition) continueCollecting = collectPredicates and not isinstance(t, ActionTransition)
c = self.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon) c = self.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon)
if c is not None: if c is not None:
if not t.isEpsilon:
if c in closureBusy:
# avoid infinite recursion for EOF* and EOF+
continue
closureBusy.add(c)
newDepth = depth newDepth = depth
if isinstance( config.state, RuleStopState): if isinstance( config.state, RuleStopState):
# target fell off end of rule; mark resulting c as having dipped into outer context # target fell off end of rule; mark resulting c as having dipped into outer context
@ -1162,24 +1157,28 @@ class ParserATNSimulator(ATNSimulator):
# track how far we dip into outer context. Might # track how far we dip into outer context. Might
# come in handy and we avoid evaluating context dependent # come in handy and we avoid evaluating context dependent
# preds if this is > 0. # preds if this is > 0.
if c in closureBusy:
# avoid infinite recursion for right-recursive rules
continue
closureBusy.add(c)
if self._dfa is not None and self._dfa.precedenceDfa: if self._dfa is not None and self._dfa.precedenceDfa:
if t.outermostPrecedenceReturn == self._dfa.atnStartState.ruleIndex: if t.outermostPrecedenceReturn == self._dfa.atnStartState.ruleIndex:
c.precedenceFilterSuppressed = True c.precedenceFilterSuppressed = True
c.reachesIntoOuterContext += 1 c.reachesIntoOuterContext += 1
if c in closureBusy:
# avoid infinite recursion for right-recursive rules
continue
closureBusy.add(c)
configs.dipsIntoOuterContext = True # TODO: can remove? only care when we add to set per middle of this method configs.dipsIntoOuterContext = True # TODO: can remove? only care when we add to set per middle of this method
newDepth -= 1 newDepth -= 1
if ParserATNSimulator.debug: if ParserATNSimulator.debug:
print("dips into outer ctx: " + str(c)) print("dips into outer ctx: " + str(c))
elif isinstance(t, RuleTransition): else:
# latch when newDepth goes negative - once we step out of the entry context we can't return if not t.isEpsilon:
if newDepth >= 0: if c in closureBusy:
newDepth += 1 # avoid infinite recursion for EOF* and EOF+
continue
closureBusy.add(c)
if isinstance(t, RuleTransition):
# latch when newDepth goes negative - once we step out of the entry context we can't return
if newDepth >= 0:
newDepth += 1
self.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEofAsEpsilon) self.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEofAsEpsilon)