@@ -995,12 +995,78 @@ func (p *ParserATNSimulator) closure(config *ATNConfig, configs *ATNConfigSet, c
995
995
fullCtx , initialDepth , treatEOFAsEpsilon )
996
996
}
997
997
998
- //goland:noinspection GoBoolExpressions
999
998
func (p * ParserATNSimulator ) closureCheckingStopState (config * ATNConfig , configs * ATNConfigSet , closureBusy * ClosureBusy , collectPredicates , fullCtx bool , depth int , treatEOFAsEpsilon bool ) {
1000
999
if runtimeConfig .parserATNSimulatorTraceATNSim {
1001
1000
fmt .Println ("closure(" + config .String () + ")" )
1002
1001
}
1003
1002
1003
+ var stack []* ATNConfig
1004
+ visited := make (map [* ATNConfig ]bool )
1005
+
1006
+ stack = append (stack , config )
1007
+
1008
+ for len (stack ) > 0 {
1009
+ currConfig := stack [len (stack )- 1 ]
1010
+ stack = stack [:len (stack )- 1 ]
1011
+
1012
+ if _ , ok := visited [currConfig ]; ok {
1013
+ continue
1014
+ }
1015
+ visited [currConfig ] = true
1016
+
1017
+ if _ , ok := currConfig .GetState ().(* RuleStopState ); ok {
1018
+ // We hit rule end. If we have context info, use it
1019
+ // run thru all possible stack tops in ctx
1020
+ if ! currConfig .GetContext ().isEmpty () {
1021
+ for i := 0 ; i < currConfig .GetContext ().length (); i ++ {
1022
+ if currConfig .GetContext ().getReturnState (i ) == BasePredictionContextEmptyReturnState {
1023
+ if fullCtx {
1024
+ nb := NewATNConfig1 (currConfig , currConfig .GetState (), BasePredictionContextEMPTY )
1025
+ configs .Add (nb , p .mergeCache )
1026
+ continue
1027
+ } else {
1028
+ // we have no context info, just chase follow links (if greedy)
1029
+ if runtimeConfig .parserATNSimulatorDebug {
1030
+ fmt .Println ("FALLING off rule " + p .getRuleName (currConfig .GetState ().GetRuleIndex ()))
1031
+ }
1032
+ p .closureWork (currConfig , configs , closureBusy , collectPredicates , fullCtx , depth , treatEOFAsEpsilon )
1033
+ }
1034
+ continue
1035
+ }
1036
+ returnState := p .atn .states [currConfig .GetContext ().getReturnState (i )]
1037
+ newContext := currConfig .GetContext ().GetParent (i ) // "pop" return state
1038
+
1039
+ c := NewATNConfig5 (returnState , currConfig .GetAlt (), newContext , currConfig .GetSemanticContext ())
1040
+ // While we have context to pop back from, we may have
1041
+ // gotten that context AFTER having falling off a rule.
1042
+ // Make sure we track that we are now out of context.
1043
+ c .SetReachesIntoOuterContext (currConfig .GetReachesIntoOuterContext ())
1044
+
1045
+ stack = append (stack , c )
1046
+ }
1047
+ continue
1048
+ } else if fullCtx {
1049
+ // reached end of start rule
1050
+ configs .Add (currConfig , p .mergeCache )
1051
+ continue
1052
+ } else {
1053
+ // else if we have no context info, just chase follow links (if greedy)
1054
+ if runtimeConfig .parserATNSimulatorDebug {
1055
+ fmt .Println ("FALLING off rule " + p .getRuleName (currConfig .GetState ().GetRuleIndex ()))
1056
+ }
1057
+ }
1058
+ }
1059
+
1060
+ p .closureWork (currConfig , configs , closureBusy , collectPredicates , fullCtx , depth , treatEOFAsEpsilon )
1061
+ }
1062
+ }
1063
+
1064
+ //goland:noinspection GoBoolExpressions
1065
+ func (p * ParserATNSimulator ) closureCheckingStopStateRecursive (config * ATNConfig , configs * ATNConfigSet , closureBusy * ClosureBusy , collectPredicates , fullCtx bool , depth int , treatEOFAsEpsilon bool ) {
1066
+ if runtimeConfig .parserATNSimulatorTraceATNSim {
1067
+ fmt .Println ("closure(" + config .String () + ")" )
1068
+ }
1069
+
1004
1070
if _ , ok := config .GetState ().(* RuleStopState ); ok {
1005
1071
// We hit rule end. If we have context info, use it
1006
1072
// run thru all possible stack tops in ctx
0 commit comments