Skip to content

Commit

Permalink
feat: Make closureCheckingStopState iterative rather than recursive
Browse files Browse the repository at this point in the history
  • Loading branch information
jimidle committed May 5, 2023
1 parent 2406774 commit a333aa0
Showing 1 changed file with 67 additions and 1 deletion.
68 changes: 67 additions & 1 deletion runtime/Go/antlr/v4/parser_atn_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -995,12 +995,78 @@ func (p *ParserATNSimulator) closure(config *ATNConfig, configs *ATNConfigSet, c
fullCtx, initialDepth, treatEOFAsEpsilon)
}

//goland:noinspection GoBoolExpressions
func (p *ParserATNSimulator) closureCheckingStopState(config *ATNConfig, configs *ATNConfigSet, closureBusy *ClosureBusy, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
if runtimeConfig.parserATNSimulatorTraceATNSim {
fmt.Println("closure(" + config.String() + ")")
}

var stack []*ATNConfig
visited := make(map[*ATNConfig]bool)

stack = append(stack, config)

for len(stack) > 0 {
currConfig := stack[len(stack)-1]
stack = stack[:len(stack)-1]

if _, ok := visited[currConfig]; ok {
continue
}
visited[currConfig] = true

if _, ok := currConfig.GetState().(*RuleStopState); ok {
// We hit rule end. If we have context info, use it
// run thru all possible stack tops in ctx
if !currConfig.GetContext().isEmpty() {
for i := 0; i < currConfig.GetContext().length(); i++ {
if currConfig.GetContext().getReturnState(i) == BasePredictionContextEmptyReturnState {
if fullCtx {
nb := NewATNConfig1(currConfig, currConfig.GetState(), BasePredictionContextEMPTY)
configs.Add(nb, p.mergeCache)
continue
} else {
// we have no context info, just chase follow links (if greedy)
if runtimeConfig.parserATNSimulatorDebug {
fmt.Println("FALLING off rule " + p.getRuleName(currConfig.GetState().GetRuleIndex()))
}
p.closureWork(currConfig, configs, closureBusy, collectPredicates, fullCtx, depth, treatEOFAsEpsilon)
}
continue
}
returnState := p.atn.states[currConfig.GetContext().getReturnState(i)]
newContext := currConfig.GetContext().GetParent(i) // "pop" return state

c := NewATNConfig5(returnState, currConfig.GetAlt(), newContext, currConfig.GetSemanticContext())
// While we have context to pop back from, we may have
// gotten that context AFTER having falling off a rule.
// Make sure we track that we are now out of context.
c.SetReachesIntoOuterContext(currConfig.GetReachesIntoOuterContext())

stack = append(stack, c)
}
continue
} else if fullCtx {
// reached end of start rule
configs.Add(currConfig, p.mergeCache)
continue
} else {
// else if we have no context info, just chase follow links (if greedy)
if runtimeConfig.parserATNSimulatorDebug {
fmt.Println("FALLING off rule " + p.getRuleName(currConfig.GetState().GetRuleIndex()))
}
}
}

p.closureWork(currConfig, configs, closureBusy, collectPredicates, fullCtx, depth, treatEOFAsEpsilon)
}
}

//goland:noinspection GoBoolExpressions
func (p *ParserATNSimulator) closureCheckingStopStateRecursive(config *ATNConfig, configs *ATNConfigSet, closureBusy *ClosureBusy, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
if runtimeConfig.parserATNSimulatorTraceATNSim {
fmt.Println("closure(" + config.String() + ")")
}

if _, ok := config.GetState().(*RuleStopState); ok {
// We hit rule end. If we have context info, use it
// run thru all possible stack tops in ctx
Expand Down

0 comments on commit a333aa0

Please sign in to comment.