diff --git a/runtime/Go/antlr/v4/array_prediction_context.go b/runtime/Go/antlr/v4/array_prediction_context.go new file mode 100644 index 0000000000..a24350200e --- /dev/null +++ b/runtime/Go/antlr/v4/array_prediction_context.go @@ -0,0 +1,115 @@ +package antlr + +import ( + "golang.org/x/exp/slices" + "strconv" +) + +type ArrayPredictionContext struct { + BasePredictionContext + parents []PredictionContext + returnStates []int +} + +func NewArrayPredictionContext(parents []PredictionContext, returnStates []int) *ArrayPredictionContext { + // Parent can be nil only if full ctx mode and we make an array + // from {@link //EMPTY} and non-empty. We merge {@link //EMPTY} by using + // nil parent and + // returnState == {@link //EmptyReturnState}. + hash := murmurInit(1) + for _, parent := range parents { + hash = murmurUpdate(hash, parent.Hash()) + } + for _, returnState := range returnStates { + hash = murmurUpdate(hash, returnState) + } + hash = murmurFinish(hash, len(parents)<<1) + + return &ArrayPredictionContext{ + BasePredictionContext: BasePredictionContext{ + cachedHash: hash, + pcType: PredictionContextArray, + }, + parents: parents, + returnStates: returnStates, + } +} + +func (a *ArrayPredictionContext) GetReturnStates() []int { + return a.returnStates +} + +func (a *ArrayPredictionContext) hasEmptyPath() bool { + return a.getReturnState(a.length()-1) == BasePredictionContextEmptyReturnState +} + +func (a *ArrayPredictionContext) isEmpty() bool { + // since EmptyReturnState can only appear in the last position, we + // don't need to verify that size==1 + return a.returnStates[0] == BasePredictionContextEmptyReturnState +} + +func (a *ArrayPredictionContext) length() int { + return len(a.returnStates) +} + +func (a *ArrayPredictionContext) GetParent(index int) PredictionContext { + return a.parents[index] +} + +func (a *ArrayPredictionContext) getReturnState(index int) int { + return a.returnStates[index] +} + +// Equals is the default comparison function for ArrayPredictionContext when no specialized +// implementation is needed for a collection +func (a *ArrayPredictionContext) Equals(o interface{}) bool { + if a == o { + return true + } + other, ok := o.(*ArrayPredictionContext) + if !ok { + return false + } + if a.cachedHash != other.Hash() { + return false // can't be same if hash is different + } + + // Must compare the actual array elements and not just the array address + // + return slices.Equal(a.returnStates, other.returnStates) && + slices.EqualFunc(a.parents, other.parents, func(x, y PredictionContext) bool { + return x.Equals(y) + }) +} + +// Hash is the default hash function for ArrayPredictionContext when no specialized +// implementation is needed for a collection +func (a *ArrayPredictionContext) Hash() int { + return a.BasePredictionContext.cachedHash +} + +func (a *ArrayPredictionContext) String() string { + if a.isEmpty() { + return "[]" + } + + s := "[" + for i := 0; i < len(a.returnStates); i++ { + if i > 0 { + s = s + ", " + } + if a.returnStates[i] == BasePredictionContextEmptyReturnState { + s = s + "$" + continue + } + s = s + strconv.Itoa(a.returnStates[i]) + if a.parents[i] != nil { + s = s + " " + a.parents[i].String() + } else { + s = s + "nil" + } + } + + return s + "]" +} diff --git a/runtime/Go/antlr/v4/atn_config.go b/runtime/Go/antlr/v4/atn_config.go index 9bdc99fc87..5dd1205675 100644 --- a/runtime/Go/antlr/v4/atn_config.go +++ b/runtime/Go/antlr/v4/atn_config.go @@ -106,17 +106,23 @@ func NewBaseATNConfig1(c ATNConfig, state ATNState, context PredictionContext) * // are just wrappers around this one. func NewBaseATNConfig(c ATNConfig, state ATNState, context PredictionContext, semanticContext SemanticContext) *BaseATNConfig { if semanticContext == nil { - panic("semanticContext cannot be nil") + panic("semanticContext cannot be nil") // TODO: Remove this - probably put here for some bug that is now fixed } - return &BaseATNConfig{ - state: state, - alt: c.GetAlt(), - context: context, - semanticContext: semanticContext, - reachesIntoOuterContext: c.GetReachesIntoOuterContext(), - precedenceFilterSuppressed: c.getPrecedenceFilterSuppressed(), - } + b := &BaseATNConfig{} + b.InitBaseATNConfig(c, state, c.GetAlt(), context, semanticContext) + + return b +} + +func (b *BaseATNConfig) InitBaseATNConfig(c ATNConfig, state ATNState, alt int, context PredictionContext, semanticContext SemanticContext) { + + b.state = state + b.alt = alt + b.context = context + b.semanticContext = semanticContext + b.reachesIntoOuterContext = c.GetReachesIntoOuterContext() + b.precedenceFilterSuppressed = c.getPrecedenceFilterSuppressed() } func (b *BaseATNConfig) getPrecedenceFilterSuppressed() bool { @@ -237,49 +243,74 @@ func (b *BaseATNConfig) String() string { // BaseATNConfig struct. // TODO: Stop using a pointer and embed the struct instead as this saves allocations. Same for the LexerATNConfig "constructors" type LexerATNConfig struct { - *BaseATNConfig + BaseATNConfig lexerActionExecutor *LexerActionExecutor passedThroughNonGreedyDecision bool } func NewLexerATNConfig6(state ATNState, alt int, context PredictionContext) *LexerATNConfig { - return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)} + + return &LexerATNConfig{ + BaseATNConfig: BaseATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: SemanticContextNone, + }, + } } func NewLexerATNConfig5(state ATNState, alt int, context PredictionContext, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig { return &LexerATNConfig{ - BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone), + BaseATNConfig: BaseATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: SemanticContextNone, + }, lexerActionExecutor: lexerActionExecutor, } } func NewLexerATNConfig4(c *LexerATNConfig, state ATNState) *LexerATNConfig { - return &LexerATNConfig{ - BaseATNConfig: NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()), + lac := &LexerATNConfig{ + lexerActionExecutor: c.lexerActionExecutor, passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), } + lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext()) + return lac } func NewLexerATNConfig3(c *LexerATNConfig, state ATNState, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig { - return &LexerATNConfig{ - BaseATNConfig: NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()), + lac := &LexerATNConfig{ lexerActionExecutor: lexerActionExecutor, passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), } + lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext()) + return lac } func NewLexerATNConfig2(c *LexerATNConfig, state ATNState, context PredictionContext) *LexerATNConfig { - return &LexerATNConfig{ - BaseATNConfig: NewBaseATNConfig(c, state, context, c.GetSemanticContext()), + lac := &LexerATNConfig{ lexerActionExecutor: c.lexerActionExecutor, passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), } + lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), context, c.GetSemanticContext()) + return lac } //goland:noinspection GoUnusedExportedFunction func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *LexerATNConfig { - return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)} + lac := &LexerATNConfig{ + BaseATNConfig: BaseATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: SemanticContextNone, + }, + } + return lac } // Hash is the default hash function for LexerATNConfig objects, it can be used directly or via @@ -330,7 +361,7 @@ func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool { return false } - return l.BaseATNConfig.Equals(otherT.BaseATNConfig) + return l.BaseATNConfig.Equals(&otherT.BaseATNConfig) } func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool { diff --git a/runtime/Go/antlr/v4/atn_deserializer.go b/runtime/Go/antlr/v4/atn_deserializer.go index 853df0870c..1e5f6249dd 100644 --- a/runtime/Go/antlr/v4/atn_deserializer.go +++ b/runtime/Go/antlr/v4/atn_deserializer.go @@ -31,7 +31,7 @@ func NewATNDeserializer(options *ATNDeserializationOptions) *ATNDeserializer { if options == nil { options = &defaultATNDeserializationOptions } - + return &ATNDeserializer{options: options} } @@ -42,7 +42,7 @@ func stringInSlice(a string, list []string) int { return i } } - + return -1 } @@ -50,34 +50,34 @@ func (a *ATNDeserializer) Deserialize(data []int32) *ATN { a.data = data a.pos = 0 a.checkVersion() - + atn := a.readATN() - + a.readStates(atn) a.readRules(atn) a.readModes(atn) - + sets := a.readSets(atn, nil) - + a.readEdges(atn, sets) a.readDecisions(atn) a.readLexerActions(atn) a.markPrecedenceDecisions(atn) a.verifyATN(atn) - + if a.options.GenerateRuleBypassTransitions() && atn.grammarType == ATNTypeParser { a.generateRuleBypassTransitions(atn) // Re-verify after modification a.verifyATN(atn) } - + return atn - + } func (a *ATNDeserializer) checkVersion() { version := a.readInt() - + if version != serializedVersion { panic("Could not deserialize ATN with version " + strconv.Itoa(version) + " (expected " + strconv.Itoa(serializedVersion) + ").") } @@ -86,95 +86,95 @@ func (a *ATNDeserializer) checkVersion() { func (a *ATNDeserializer) readATN() *ATN { grammarType := a.readInt() maxTokenType := a.readInt() - + return NewATN(grammarType, maxTokenType) } func (a *ATNDeserializer) readStates(atn *ATN) { nstates := a.readInt() - + // Allocate worst case size. loopBackStateNumbers := make([]loopEndStateIntPair, 0, nstates) endStateNumbers := make([]blockStartStateIntPair, 0, nstates) - + // Preallocate states slice. atn.states = make([]ATNState, 0, nstates) - + for i := 0; i < nstates; i++ { stype := a.readInt() - + // Ignore bad types of states if stype == ATNStateInvalidType { atn.addState(nil) continue } - + ruleIndex := a.readInt() - + s := a.stateFactory(stype, ruleIndex) - + if stype == ATNStateLoopEnd { loopBackStateNumber := a.readInt() - + loopBackStateNumbers = append(loopBackStateNumbers, loopEndStateIntPair{s.(*LoopEndState), loopBackStateNumber}) } else if s2, ok := s.(BlockStartState); ok { endStateNumber := a.readInt() - + endStateNumbers = append(endStateNumbers, blockStartStateIntPair{s2, endStateNumber}) } - + atn.addState(s) } - + // Delay the assignment of loop back and end states until we know all the state // instances have been initialized for _, pair := range loopBackStateNumbers { pair.item0.loopBackState = atn.states[pair.item1] } - + for _, pair := range endStateNumbers { pair.item0.setEndState(atn.states[pair.item1].(*BlockEndState)) } - + numNonGreedyStates := a.readInt() for j := 0; j < numNonGreedyStates; j++ { stateNumber := a.readInt() - + atn.states[stateNumber].(DecisionState).setNonGreedy(true) } - + numPrecedenceStates := a.readInt() for j := 0; j < numPrecedenceStates; j++ { stateNumber := a.readInt() - + atn.states[stateNumber].(*RuleStartState).isPrecedenceRule = true } } func (a *ATNDeserializer) readRules(atn *ATN) { nrules := a.readInt() - + if atn.grammarType == ATNTypeLexer { atn.ruleToTokenType = make([]int, nrules) } - + atn.ruleToStartState = make([]*RuleStartState, nrules) - + for i := range atn.ruleToStartState { s := a.readInt() startState := atn.states[s].(*RuleStartState) - + atn.ruleToStartState[i] = startState - + if atn.grammarType == ATNTypeLexer { tokenType := a.readInt() - + atn.ruleToTokenType[i] = tokenType } } - + atn.ruleToStopState = make([]*RuleStopState, nrules) - + for _, state := range atn.states { if s2, ok := state.(*RuleStopState); ok { atn.ruleToStopState[s2.ruleIndex] = s2 @@ -186,50 +186,50 @@ func (a *ATNDeserializer) readRules(atn *ATN) { func (a *ATNDeserializer) readModes(atn *ATN) { nmodes := a.readInt() atn.modeToStartState = make([]*TokensStartState, nmodes) - + for i := range atn.modeToStartState { s := a.readInt() - + atn.modeToStartState[i] = atn.states[s].(*TokensStartState) } } func (a *ATNDeserializer) readSets(_ *ATN, sets []*IntervalSet) []*IntervalSet { m := a.readInt() - + // Preallocate the needed capacity. if cap(sets)-len(sets) < m { isets := make([]*IntervalSet, len(sets), len(sets)+m) copy(isets, sets) sets = isets } - + for i := 0; i < m; i++ { iset := NewIntervalSet() - + sets = append(sets, iset) - + n := a.readInt() containsEOF := a.readInt() - + if containsEOF != 0 { iset.addOne(-1) } - + for j := 0; j < n; j++ { i1 := a.readInt() i2 := a.readInt() - + iset.addRange(i1, i2) } } - + return sets } func (a *ATNDeserializer) readEdges(atn *ATN, sets []*IntervalSet) { nedges := a.readInt() - + for i := 0; i < nedges; i++ { var ( src = a.readInt() @@ -241,48 +241,48 @@ func (a *ATNDeserializer) readEdges(atn *ATN, sets []*IntervalSet) { trans = a.edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets) srcState = atn.states[src] ) - + srcState.AddTransition(trans, -1) } - + // Edges for rule stop states can be derived, so they are not serialized for _, state := range atn.states { for _, t := range state.GetTransitions() { var rt, ok = t.(*RuleTransition) - + if !ok { continue } - + outermostPrecedenceReturn := -1 - + if atn.ruleToStartState[rt.getTarget().GetRuleIndex()].isPrecedenceRule { if rt.precedence == 0 { outermostPrecedenceReturn = rt.getTarget().GetRuleIndex() } } - + trans := NewEpsilonTransition(rt.followState, outermostPrecedenceReturn) - + atn.ruleToStopState[rt.getTarget().GetRuleIndex()].AddTransition(trans, -1) } } - + for _, state := range atn.states { if s2, ok := state.(BlockStartState); ok { // We need to know the end state to set its start state if s2.getEndState() == nil { panic("IllegalState") } - + // Block end states can only be associated to a single block start state if s2.getEndState().startState != nil { panic("IllegalState") } - + s2.getEndState().startState = state } - + if s2, ok := state.(*PlusLoopbackState); ok { for _, t := range s2.GetTransitions() { if t2, ok := t.getTarget().(*PlusBlockStartState); ok { @@ -301,11 +301,11 @@ func (a *ATNDeserializer) readEdges(atn *ATN, sets []*IntervalSet) { func (a *ATNDeserializer) readDecisions(atn *ATN) { ndecisions := a.readInt() - + for i := 0; i < ndecisions; i++ { s := a.readInt() decState := atn.states[s].(DecisionState) - + atn.DecisionToState = append(atn.DecisionToState, decState) decState.setDecision(i) } @@ -314,9 +314,9 @@ func (a *ATNDeserializer) readDecisions(atn *ATN) { func (a *ATNDeserializer) readLexerActions(atn *ATN) { if atn.grammarType == ATNTypeLexer { count := a.readInt() - + atn.lexerActions = make([]LexerAction, count) - + for i := range atn.lexerActions { actionType := a.readInt() data1 := a.readInt() @@ -328,11 +328,11 @@ func (a *ATNDeserializer) readLexerActions(atn *ATN) { func (a *ATNDeserializer) generateRuleBypassTransitions(atn *ATN) { count := len(atn.ruleToStartState) - + for i := 0; i < count; i++ { atn.ruleToTokenType[i] = atn.maxTokenType + i + 1 } - + for i := 0; i < count; i++ { a.generateRuleBypassTransition(atn, i) } @@ -340,79 +340,79 @@ func (a *ATNDeserializer) generateRuleBypassTransitions(atn *ATN) { func (a *ATNDeserializer) generateRuleBypassTransition(atn *ATN, idx int) { bypassStart := NewBasicBlockStartState() - + bypassStart.ruleIndex = idx atn.addState(bypassStart) - + bypassStop := NewBlockEndState() - + bypassStop.ruleIndex = idx atn.addState(bypassStop) - + bypassStart.endState = bypassStop - - atn.defineDecisionState(bypassStart.BaseDecisionState) - + + atn.defineDecisionState(&bypassStart.BaseDecisionState) + bypassStop.startState = bypassStart - + var excludeTransition Transition var endState ATNState - + if atn.ruleToStartState[idx].isPrecedenceRule { // Wrap from the beginning of the rule to the StarLoopEntryState endState = nil - + for i := 0; i < len(atn.states); i++ { state := atn.states[i] - + if a.stateIsEndStateFor(state, idx) != nil { endState = state excludeTransition = state.(*StarLoopEntryState).loopBackState.GetTransitions()[0] - + break } } - + if excludeTransition == nil { panic("Couldn't identify final state of the precedence rule prefix section.") } } else { endState = atn.ruleToStopState[idx] } - + // All non-excluded transitions that currently target end state need to target // blockEnd instead for i := 0; i < len(atn.states); i++ { state := atn.states[i] - + for j := 0; j < len(state.GetTransitions()); j++ { transition := state.GetTransitions()[j] - + if transition == excludeTransition { continue } - + if transition.getTarget() == endState { transition.setTarget(bypassStop) } } } - + // All transitions leaving the rule start state need to leave blockStart instead ruleToStartState := atn.ruleToStartState[idx] count := len(ruleToStartState.GetTransitions()) - + for count > 0 { bypassStart.AddTransition(ruleToStartState.GetTransitions()[count-1], -1) ruleToStartState.SetTransitions([]Transition{ruleToStartState.GetTransitions()[len(ruleToStartState.GetTransitions())-1]}) } - + // Link the new states atn.ruleToStartState[idx].AddTransition(NewEpsilonTransition(bypassStart, -1), -1) bypassStop.AddTransition(NewEpsilonTransition(endState, -1), -1) - + MatchState := NewBasicState() - + atn.addState(MatchState) MatchState.AddTransition(NewAtomTransition(bypassStop, atn.ruleToTokenType[idx]), -1) bypassStart.AddTransition(NewEpsilonTransition(MatchState, -1), -1) @@ -422,23 +422,23 @@ func (a *ATNDeserializer) stateIsEndStateFor(state ATNState, idx int) ATNState { if state.GetRuleIndex() != idx { return nil } - + if _, ok := state.(*StarLoopEntryState); !ok { return nil } - + maybeLoopEndState := state.GetTransitions()[len(state.GetTransitions())-1].getTarget() - + if _, ok := maybeLoopEndState.(*LoopEndState); !ok { return nil } - + var _, ok = maybeLoopEndState.GetTransitions()[0].getTarget().(*RuleStopState) - + if maybeLoopEndState.(*LoopEndState).epsilonOnlyTransitions && ok { return state } - + return nil } @@ -456,10 +456,10 @@ func (a *ATNDeserializer) markPrecedenceDecisions(atn *ATN) { // precedence rule should continue or complete. if atn.ruleToStartState[state.GetRuleIndex()].isPrecedenceRule { maybeLoopEndState := state.GetTransitions()[len(state.GetTransitions())-1].getTarget() - + if s3, ok := maybeLoopEndState.(*LoopEndState); ok { var _, ok2 = maybeLoopEndState.GetTransitions()[0].getTarget().(*RuleStopState) - + if s3.epsilonOnlyTransitions && ok2 { state.(*StarLoopEntryState).precedenceRuleDecision = true } @@ -472,65 +472,65 @@ func (a *ATNDeserializer) verifyATN(atn *ATN) { if !a.options.VerifyATN() { return } - + // Verify assumptions for _, state := range atn.states { if state == nil { continue } - + a.checkCondition(state.GetEpsilonOnlyTransitions() || len(state.GetTransitions()) <= 1, "") - + switch s2 := state.(type) { case *PlusBlockStartState: a.checkCondition(s2.loopBackState != nil, "") - + case *StarLoopEntryState: a.checkCondition(s2.loopBackState != nil, "") a.checkCondition(len(s2.GetTransitions()) == 2, "") - + switch s2.transitions[0].getTarget().(type) { case *StarBlockStartState: _, ok := s2.transitions[1].getTarget().(*LoopEndState) - + a.checkCondition(ok, "") a.checkCondition(!s2.nonGreedy, "") - + case *LoopEndState: var _, ok = s2.transitions[1].getTarget().(*StarBlockStartState) - + a.checkCondition(ok, "") a.checkCondition(s2.nonGreedy, "") - + default: panic("IllegalState") } - + case *StarLoopbackState: a.checkCondition(len(state.GetTransitions()) == 1, "") - + var _, ok = state.GetTransitions()[0].getTarget().(*StarLoopEntryState) - + a.checkCondition(ok, "") - + case *LoopEndState: a.checkCondition(s2.loopBackState != nil, "") - + case *RuleStartState: a.checkCondition(s2.stopState != nil, "") - + case BlockStartState: a.checkCondition(s2.getEndState() != nil, "") - + case *BlockEndState: a.checkCondition(s2.startState != nil, "") - + case DecisionState: a.checkCondition(len(s2.GetTransitions()) <= 1 || s2.getDecision() >= 0, "") - + default: var _, ok = s2.(*RuleStopState) - + a.checkCondition(len(s2.GetTransitions()) <= 1 || ok, "") } } @@ -541,114 +541,114 @@ func (a *ATNDeserializer) checkCondition(condition bool, message string) { if message == "" { message = "IllegalState" } - + panic(message) } } func (a *ATNDeserializer) readInt() int { v := a.data[a.pos] - + a.pos++ - + return int(v) // data is 32 bits but int is at least that big } func (a *ATNDeserializer) edgeFactory(atn *ATN, typeIndex, _, trg, arg1, arg2, arg3 int, sets []*IntervalSet) Transition { target := atn.states[trg] - + switch typeIndex { case TransitionEPSILON: return NewEpsilonTransition(target, -1) - + case TransitionRANGE: if arg3 != 0 { return NewRangeTransition(target, TokenEOF, arg2) } - + return NewRangeTransition(target, arg1, arg2) - + case TransitionRULE: return NewRuleTransition(atn.states[arg1], arg2, arg3, target) - + case TransitionPREDICATE: return NewPredicateTransition(target, arg1, arg2, arg3 != 0) - + case TransitionPRECEDENCE: return NewPrecedencePredicateTransition(target, arg1) - + case TransitionATOM: if arg3 != 0 { return NewAtomTransition(target, TokenEOF) } - + return NewAtomTransition(target, arg1) - + case TransitionACTION: return NewActionTransition(target, arg1, arg2, arg3 != 0) - + case TransitionSET: return NewSetTransition(target, sets[arg1]) - + case TransitionNOTSET: return NewNotSetTransition(target, sets[arg1]) - + case TransitionWILDCARD: return NewWildcardTransition(target) } - + panic("The specified transition type is not valid.") } func (a *ATNDeserializer) stateFactory(typeIndex, ruleIndex int) ATNState { var s ATNState - + switch typeIndex { case ATNStateInvalidType: return nil - + case ATNStateBasic: s = NewBasicState() - + case ATNStateRuleStart: s = NewRuleStartState() - + case ATNStateBlockStart: s = NewBasicBlockStartState() - + case ATNStatePlusBlockStart: s = NewPlusBlockStartState() - + case ATNStateStarBlockStart: s = NewStarBlockStartState() - + case ATNStateTokenStart: s = NewTokensStartState() - + case ATNStateRuleStop: s = NewRuleStopState() - + case ATNStateBlockEnd: s = NewBlockEndState() - + case ATNStateStarLoopBack: s = NewStarLoopbackState() - + case ATNStateStarLoopEntry: s = NewStarLoopEntryState() - + case ATNStatePlusLoopBack: s = NewPlusLoopbackState() - + case ATNStateLoopEnd: s = NewLoopEndState() - + default: panic(fmt.Sprintf("state type %d is invalid", typeIndex)) } - + s.SetRuleIndex(ruleIndex) - + return s } @@ -656,28 +656,28 @@ func (a *ATNDeserializer) lexerActionFactory(typeIndex, data1, data2 int) LexerA switch typeIndex { case LexerActionTypeChannel: return NewLexerChannelAction(data1) - + case LexerActionTypeCustom: return NewLexerCustomAction(data1, data2) - + case LexerActionTypeMode: return NewLexerModeAction(data1) - + case LexerActionTypeMore: return LexerMoreActionINSTANCE - + case LexerActionTypePopMode: return LexerPopModeActionINSTANCE - + case LexerActionTypePushMode: return NewLexerPushModeAction(data1) - + case LexerActionTypeSkip: return LexerSkipActionINSTANCE - + case LexerActionTypeType: return NewLexerTypeAction(data1) - + default: panic(fmt.Sprintf("lexer action %d is invalid", typeIndex)) } diff --git a/runtime/Go/antlr/v4/atn_simulator.go b/runtime/Go/antlr/v4/atn_simulator.go index 41529115fa..dbb60ed1e4 100644 --- a/runtime/Go/antlr/v4/atn_simulator.go +++ b/runtime/Go/antlr/v4/atn_simulator.go @@ -18,22 +18,13 @@ type BaseATNSimulator struct { decisionToDFA []*DFA } -func NewBaseATNSimulator(atn *ATN, sharedContextCache *PredictionContextCache) *BaseATNSimulator { - b := new(BaseATNSimulator) - - b.atn = atn - b.sharedContextCache = sharedContextCache - - return b -} - func (b *BaseATNSimulator) getCachedContext(context PredictionContext) PredictionContext { if b.sharedContextCache == nil { return context } - + visited := make(map[PredictionContext]PredictionContext) - + return getCachedBasePredictionContext(context, b.sharedContextCache, visited) } diff --git a/runtime/Go/antlr/v4/atn_state.go b/runtime/Go/antlr/v4/atn_state.go index 5b69c476cb..58dec925cd 100644 --- a/runtime/Go/antlr/v4/atn_state.go +++ b/runtime/Go/antlr/v4/atn_state.go @@ -4,7 +4,11 @@ package antlr -import "strconv" +import ( + "fmt" + "os" + "strconv" +) // Constants for serialization. const ( @@ -21,7 +25,7 @@ const ( ATNStateStarLoopEntry = 10 ATNStatePlusLoopBack = 11 ATNStateLoopEnd = 12 - + ATNStateInvalidStateNumber = -1 ) @@ -30,25 +34,25 @@ var ATNStateInitialNumTransitions = 4 type ATNState interface { GetEpsilonOnlyTransitions() bool - + GetRuleIndex() int SetRuleIndex(int) - + GetNextTokenWithinRule() *IntervalSet SetNextTokenWithinRule(*IntervalSet) - + GetATN() *ATN SetATN(*ATN) - + GetStateType() int - + GetStateNumber() int SetStateNumber(int) - + GetTransitions() []Transition SetTransitions([]Transition) AddTransition(Transition, int) - + String() string Hash() int Equals(Collectable[ATNState]) bool @@ -57,26 +61,26 @@ type ATNState interface { type BaseATNState struct { // NextTokenWithinRule caches lookahead during parsing. Not used during construction. NextTokenWithinRule *IntervalSet - + // atn is the current ATN. atn *ATN - + epsilonOnlyTransitions bool - + // ruleIndex tracks the Rule index because there are no Rule objects at runtime. ruleIndex int - + stateNumber int - + stateType int - + // Track the transitions emanating from this ATN state. transitions []Transition } -func NewBaseATNState() *BaseATNState { - return &BaseATNState{stateNumber: ATNStateInvalidStateNumber, stateType: ATNStateInvalidType} -} +//func NewBaseATNState() *BaseATNState { +// return &BaseATNState{stateNumber: ATNStateInvalidStateNumber, stateType: ATNStateInvalidType} +//} func (as *BaseATNState) GetRuleIndex() int { return as.ruleIndex @@ -137,7 +141,7 @@ func (as *BaseATNState) Equals(other Collectable[ATNState]) bool { if ot, ok := other.(ATNState); ok { return as.stateNumber == ot.GetStateNumber() } - + return false } @@ -149,47 +153,72 @@ func (as *BaseATNState) AddTransition(trans Transition, index int) { if len(as.transitions) == 0 { as.epsilonOnlyTransitions = trans.getIsEpsilon() } else if as.epsilonOnlyTransitions != trans.getIsEpsilon() { + _, _ = fmt.Fprintf(os.Stdin, "ATN state %d has both epsilon and non-epsilon transitions.\n", as.stateNumber) as.epsilonOnlyTransitions = false } - + + // TODO: Check code for already present compared to the Java equivalent + //alreadyPresent := false + //for _, t := range as.transitions { + // if t.getTarget().GetStateNumber() == trans.getTarget().GetStateNumber() { + // if t.getLabel() != nil && trans.getLabel() != nil && trans.getLabel().Equals(t.getLabel()) { + // alreadyPresent = true + // break + // } + // } else if t.getIsEpsilon() && trans.getIsEpsilon() { + // alreadyPresent = true + // break + // } + //} + //if !alreadyPresent { if index == -1 { as.transitions = append(as.transitions, trans) } else { as.transitions = append(as.transitions[:index], append([]Transition{trans}, as.transitions[index:]...)...) // TODO: as.transitions.splice(index, 1, trans) } + //} else { + // _, _ = fmt.Fprintf(os.Stderr, "Transition already present in state %d\n", as.stateNumber) + //} } type BasicState struct { - *BaseATNState + BaseATNState } func NewBasicState() *BasicState { - b := NewBaseATNState() - - b.stateType = ATNStateBasic - - return &BasicState{BaseATNState: b} + return &BasicState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateBasic, + }, + } } type DecisionState interface { ATNState - + getDecision() int setDecision(int) - + getNonGreedy() bool setNonGreedy(bool) } type BaseDecisionState struct { - *BaseATNState + BaseATNState decision int nonGreedy bool } func NewBaseDecisionState() *BaseDecisionState { - return &BaseDecisionState{BaseATNState: NewBaseATNState(), decision: -1} + return &BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateBasic, + }, + decision: -1, + } } func (s *BaseDecisionState) getDecision() int { @@ -210,19 +239,27 @@ func (s *BaseDecisionState) setNonGreedy(b bool) { type BlockStartState interface { DecisionState - + getEndState() *BlockEndState setEndState(*BlockEndState) } // BaseBlockStartState is the start of a regular (...) block. type BaseBlockStartState struct { - *BaseDecisionState + BaseDecisionState endState *BlockEndState } func NewBlockStartState() *BaseBlockStartState { - return &BaseBlockStartState{BaseDecisionState: NewBaseDecisionState()} + return &BaseBlockStartState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateBasic, + }, + decision: -1, + }, + } } func (s *BaseBlockStartState) getEndState() *BlockEndState { @@ -234,31 +271,38 @@ func (s *BaseBlockStartState) setEndState(b *BlockEndState) { } type BasicBlockStartState struct { - *BaseBlockStartState + BaseBlockStartState } func NewBasicBlockStartState() *BasicBlockStartState { - b := NewBlockStartState() - - b.stateType = ATNStateBlockStart - - return &BasicBlockStartState{BaseBlockStartState: b} + return &BasicBlockStartState{ + BaseBlockStartState: BaseBlockStartState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateBlockStart, + }, + }, + }, + } } var _ BlockStartState = &BasicBlockStartState{} // BlockEndState is a terminal node of a simple (a|b|c) block. type BlockEndState struct { - *BaseATNState + BaseATNState startState ATNState } func NewBlockEndState() *BlockEndState { - b := NewBaseATNState() - - b.stateType = ATNStateBlockEnd - - return &BlockEndState{BaseATNState: b} + return &BlockEndState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateBlockEnd, + }, + startState: nil, + } } // RuleStopState is the last node in the ATN for a rule, unless that rule is the @@ -266,43 +310,48 @@ func NewBlockEndState() *BlockEndState { // encode references to all calls to this rule to compute FOLLOW sets for error // handling. type RuleStopState struct { - *BaseATNState + BaseATNState } func NewRuleStopState() *RuleStopState { - b := NewBaseATNState() - - b.stateType = ATNStateRuleStop - - return &RuleStopState{BaseATNState: b} + return &RuleStopState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateRuleStop, + }, + } } type RuleStartState struct { - *BaseATNState + BaseATNState stopState ATNState isPrecedenceRule bool } func NewRuleStartState() *RuleStartState { - b := NewBaseATNState() - - b.stateType = ATNStateRuleStart - - return &RuleStartState{BaseATNState: b} + return &RuleStartState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateRuleStart, + }, + } } // PlusLoopbackState is a decision state for A+ and (A|B)+. It has two // transitions: one to the loop back to start of the block, and one to exit. type PlusLoopbackState struct { - *BaseDecisionState + BaseDecisionState } func NewPlusLoopbackState() *PlusLoopbackState { - b := NewBaseDecisionState() - - b.stateType = ATNStatePlusLoopBack - - return &PlusLoopbackState{BaseDecisionState: b} + return &PlusLoopbackState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStatePlusLoopBack, + }, + }, + } } // PlusBlockStartState is the start of a (A|B|...)+ loop. Technically it is a @@ -310,85 +359,103 @@ func NewPlusLoopbackState() *PlusLoopbackState { // it is included for completeness. In reality, PlusLoopbackState is the real // decision-making node for A+. type PlusBlockStartState struct { - *BaseBlockStartState + BaseBlockStartState loopBackState ATNState } func NewPlusBlockStartState() *PlusBlockStartState { - b := NewBlockStartState() - - b.stateType = ATNStatePlusBlockStart - - return &PlusBlockStartState{BaseBlockStartState: b} + return &PlusBlockStartState{ + BaseBlockStartState: BaseBlockStartState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStatePlusBlockStart, + }, + }, + }, + } } var _ BlockStartState = &PlusBlockStartState{} // StarBlockStartState is the block that begins a closure loop. type StarBlockStartState struct { - *BaseBlockStartState + BaseBlockStartState } func NewStarBlockStartState() *StarBlockStartState { - b := NewBlockStartState() - - b.stateType = ATNStateStarBlockStart - - return &StarBlockStartState{BaseBlockStartState: b} + return &StarBlockStartState{ + BaseBlockStartState: BaseBlockStartState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateStarBlockStart, + }, + }, + }, + } } var _ BlockStartState = &StarBlockStartState{} type StarLoopbackState struct { - *BaseATNState + BaseATNState } func NewStarLoopbackState() *StarLoopbackState { - b := NewBaseATNState() - - b.stateType = ATNStateStarLoopBack - - return &StarLoopbackState{BaseATNState: b} + return &StarLoopbackState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateStarLoopBack, + }, + } } type StarLoopEntryState struct { - *BaseDecisionState + BaseDecisionState loopBackState ATNState precedenceRuleDecision bool } func NewStarLoopEntryState() *StarLoopEntryState { - b := NewBaseDecisionState() - - b.stateType = ATNStateStarLoopEntry - - // False precedenceRuleDecision indicates whether this state can benefit from a precedence [DFA] during SLL decision-making. - return &StarLoopEntryState{BaseDecisionState: b} + // False precedenceRuleDecision indicates whether s state can benefit from a precedence DFA during SLL decision making. + return &StarLoopEntryState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateStarLoopEntry, + }, + }, + } } // LoopEndState marks the end of a * or + loop. type LoopEndState struct { - *BaseATNState + BaseATNState loopBackState ATNState } func NewLoopEndState() *LoopEndState { - b := NewBaseATNState() - - b.stateType = ATNStateLoopEnd - - return &LoopEndState{BaseATNState: b} + return &LoopEndState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateLoopEnd, + }, + } } // TokensStartState is the Tokens rule start state linking to each lexer rule start state. type TokensStartState struct { - *BaseDecisionState + BaseDecisionState } func NewTokensStartState() *TokensStartState { - b := NewBaseDecisionState() - - b.stateType = ATNStateTokenStart - - return &TokensStartState{BaseDecisionState: b} + return &TokensStartState{ + BaseDecisionState: BaseDecisionState{ + BaseATNState: BaseATNState{ + stateNumber: ATNStateInvalidStateNumber, + stateType: ATNStateTokenStart, + }, + }, + } } diff --git a/runtime/Go/antlr/v4/base_prediction_context.go b/runtime/Go/antlr/v4/base_prediction_context.go new file mode 100644 index 0000000000..58c19de28f --- /dev/null +++ b/runtime/Go/antlr/v4/base_prediction_context.go @@ -0,0 +1,45 @@ +package antlr + +// BasePredictionContext is the 'abstract class' for all prediction contexts and does not exist +// in its own right. All actual [PredictionContext] structs embed this and then provide their +// own methods to implement functionality. +type BasePredictionContext struct { + cachedHash int + pcType int +} + +func (b *BasePredictionContext) Hash() int { + return b.cachedHash +} + +func (b *BasePredictionContext) Equals(i interface{}) bool { + return false +} + +func (b *BasePredictionContext) GetParent(i int) PredictionContext { + return nil +} + +func (b *BasePredictionContext) getReturnState(i int) int { + return 0 +} + +func (b *BasePredictionContext) length() int { + return 0 +} + +func (b *BasePredictionContext) hasEmptyPath() bool { + return b.getReturnState(b.length()-1) == BasePredictionContextEmptyReturnState +} + +func (b *BasePredictionContext) String() string { + return "empty prediction context" +} + +func (b *BasePredictionContext) isEmpty() bool { + return false +} + +func (b *BasePredictionContext) Type() int { + return b.pcType +} diff --git a/runtime/Go/antlr/v4/common_token_stream.go b/runtime/Go/antlr/v4/common_token_stream.go index 665e258195..2e85776fd8 100644 --- a/runtime/Go/antlr/v4/common_token_stream.go +++ b/runtime/Go/antlr/v4/common_token_stream.go @@ -16,7 +16,7 @@ import ( // Token.HIDDEN_CHANNEL, use a filtering token stream such a CommonTokenStream. type CommonTokenStream struct { channel int - + // fetchedEOF indicates whether the Token.EOF token has been fetched from // tokenSource and added to tokens. This field improves performance for the // following cases: @@ -38,7 +38,7 @@ type CommonTokenStream struct { // tokenSource is the [TokenSource] from which tokens for the bt stream are // fetched. tokenSource TokenSource - + // tokens contains all tokens fetched from the token source. The list is considered a // complete view of the input once fetchedEOF is set to true. tokens []Token @@ -77,13 +77,13 @@ func (c *CommonTokenStream) Seek(index int) { func (c *CommonTokenStream) Get(index int) Token { c.lazyInit() - + return c.tokens[index] } func (c *CommonTokenStream) Consume() { SkipEOFCheck := false - + if c.index >= 0 { if c.fetchedEOF { // The last token in tokens is EOF. Skip the check if p indexes any fetched. @@ -97,11 +97,11 @@ func (c *CommonTokenStream) Consume() { // Not yet initialized SkipEOFCheck = false } - + if !SkipEOFCheck && c.LA(1) == TokenEOF { panic("cannot consume EOF") } - + if c.Sync(c.index + 1) { c.index = c.adjustSeekIndex(c.index + 1) } @@ -110,13 +110,13 @@ func (c *CommonTokenStream) Consume() { // Sync makes sure index i in tokens has a token and returns true if a token is // located at index i and otherwise false. func (c *CommonTokenStream) Sync(i int) bool { - n := i - len(c.tokens) + 1 // TODO: How many more elements do we need? - + n := i - len(c.tokens) + 1 // How many more elements do we need? + if n > 0 { fetched := c.fetch(n) return fetched >= n } - + return true } @@ -126,20 +126,20 @@ func (c *CommonTokenStream) fetch(n int) int { if c.fetchedEOF { return 0 } - + for i := 0; i < n; i++ { t := c.tokenSource.NextToken() - + t.SetTokenIndex(len(c.tokens)) c.tokens = append(c.tokens, t) - + if t.GetTokenType() == TokenEOF { c.fetchedEOF = true - + return i + 1 } } - + return n } @@ -148,27 +148,27 @@ func (c *CommonTokenStream) GetTokens(start int, stop int, types *IntervalSet) [ if start < 0 || stop < 0 { return nil } - + c.lazyInit() - + subset := make([]Token, 0) - + if stop >= len(c.tokens) { stop = len(c.tokens) - 1 } - + for i := start; i < stop; i++ { t := c.tokens[i] - + if t.GetTokenType() == TokenEOF { break } - + if types == nil || types.contains(t.GetTokenType()) { subset = append(subset, t) } } - + return subset } @@ -203,23 +203,23 @@ func (c *CommonTokenStream) SetTokenSource(tokenSource TokenSource) { // no tokens on channel between 'i' and [TokenEOF]. func (c *CommonTokenStream) NextTokenOnChannel(i, _ int) int { c.Sync(i) - + if i >= len(c.tokens) { return -1 } - + token := c.tokens[i] - + for token.GetChannel() != c.channel { if token.GetTokenType() == TokenEOF { return -1 } - + i++ c.Sync(i) token = c.tokens[i] } - + return i } @@ -230,7 +230,7 @@ func (c *CommonTokenStream) previousTokenOnChannel(i, channel int) int { for i >= 0 && c.tokens[i].GetChannel() != channel { i-- } - + return i } @@ -239,23 +239,23 @@ func (c *CommonTokenStream) previousTokenOnChannel(i, channel int) int { // or EOF. If channel is -1, it finds any non-default channel token. func (c *CommonTokenStream) GetHiddenTokensToRight(tokenIndex, channel int) []Token { c.lazyInit() - + if tokenIndex < 0 || tokenIndex >= len(c.tokens) { panic(strconv.Itoa(tokenIndex) + " not in 0.." + strconv.Itoa(len(c.tokens)-1)) } - + nextOnChannel := c.NextTokenOnChannel(tokenIndex+1, LexerDefaultTokenChannel) from := tokenIndex + 1 - // If no onChannel to the right, then nextOnChannel == -1, so set 'to' to the last token +// If no onChannel to the right, then nextOnChannel == -1, so set 'to' to the last token var to int - + if nextOnChannel == -1 { to = len(c.tokens) - 1 } else { to = nextOnChannel } - + return c.filterForChannel(from, to, channel) } @@ -264,30 +264,30 @@ func (c *CommonTokenStream) GetHiddenTokensToRight(tokenIndex, channel int) []To // -1, it finds any non default channel token. func (c *CommonTokenStream) GetHiddenTokensToLeft(tokenIndex, channel int) []Token { c.lazyInit() - + if tokenIndex < 0 || tokenIndex >= len(c.tokens) { panic(strconv.Itoa(tokenIndex) + " not in 0.." + strconv.Itoa(len(c.tokens)-1)) } - + prevOnChannel := c.previousTokenOnChannel(tokenIndex-1, LexerDefaultTokenChannel) - + if prevOnChannel == tokenIndex-1 { return nil } - + // If there are none on channel to the left and prevOnChannel == -1 then from = 0 from := prevOnChannel + 1 to := tokenIndex - 1 - + return c.filterForChannel(from, to, channel) } func (c *CommonTokenStream) filterForChannel(left, right, channel int) []Token { hidden := make([]Token, 0) - + for i := left; i < right+1; i++ { t := c.tokens[i] - + if channel == -1 { if t.GetChannel() != LexerDefaultTokenChannel { hidden = append(hidden, t) @@ -296,11 +296,11 @@ func (c *CommonTokenStream) filterForChannel(left, right, channel int) []Token { hidden = append(hidden, t) } } - + if len(hidden) == 0 { return nil } - + return hidden } @@ -324,7 +324,7 @@ func (c *CommonTokenStream) GetTextFromTokens(start, end Token) string { if start == nil || end == nil { return "" } - + return c.GetTextFromInterval(NewInterval(start.GetTokenIndex(), end.GetTokenIndex())) } @@ -334,44 +334,44 @@ func (c *CommonTokenStream) GetTextFromRuleContext(interval RuleContext) string func (c *CommonTokenStream) GetTextFromInterval(interval *Interval) string { c.lazyInit() - + if interval == nil { c.Fill() interval = NewInterval(0, len(c.tokens)-1) } else { c.Sync(interval.Stop) } - + start := interval.Start stop := interval.Stop - + if start < 0 || stop < 0 { return "" } - + if stop >= len(c.tokens) { stop = len(c.tokens) - 1 } - + s := "" - + for i := start; i < stop+1; i++ { t := c.tokens[i] - + if t.GetTokenType() == TokenEOF { break } - + s += t.GetText() } - + return s } // Fill gets all tokens from the lexer until EOF. func (c *CommonTokenStream) Fill() { c.lazyInit() - + for c.fetch(1000) == 1000 { continue } @@ -385,68 +385,68 @@ func (c *CommonTokenStream) LB(k int) Token { if k == 0 || c.index-k < 0 { return nil } - + i := c.index n := 1 - + // Find k good tokens looking backward for n <= k { // Skip off-channel tokens i = c.previousTokenOnChannel(i-1, c.channel) n++ } - + if i < 0 { return nil } - + return c.tokens[i] } func (c *CommonTokenStream) LT(k int) Token { c.lazyInit() - + if k == 0 { return nil } - + if k < 0 { return c.LB(-k) } - + i := c.index n := 1 // We know tokens[n] is valid - + // Find k good tokens for n < k { // Skip off-channel tokens, but make sure to not look past EOF if c.Sync(i + 1) { i = c.NextTokenOnChannel(i+1, c.channel) } - + n++ } - + return c.tokens[i] } // getNumberOfOnChannelTokens counts EOF once. func (c *CommonTokenStream) getNumberOfOnChannelTokens() int { var n int - + c.Fill() - + for i := 0; i < len(c.tokens); i++ { t := c.tokens[i] - + if t.GetChannel() == c.channel { n++ } - + if t.GetTokenType() == TokenEOF { break } } - + return n } diff --git a/runtime/Go/antlr/v4/comparators.go b/runtime/Go/antlr/v4/comparators.go index bb9e8f7ee3..867cbf4e6d 100644 --- a/runtime/Go/antlr/v4/comparators.go +++ b/runtime/Go/antlr/v4/comparators.go @@ -38,7 +38,7 @@ func (c *ObjEqComparator[T]) Equals2(o1, o2 T) bool { // Hash1 delegates to the Hash() method of type T func (c *ObjEqComparator[T]) Hash1(o T) int { - + return o.Hash() } @@ -52,20 +52,20 @@ type ATNConfigComparator[T Collectable[T]] struct { // Equals2 is a custom comparator for ATNConfigs specifically for configLookup func (c *ATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { - + // Same pointer, must be equal, even if both nil // if o1 == o2 { return true - + } - + // If either are nil, but not both, then the result is false // if o1 == nil || o2 == nil { return false } - + return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && o1.GetAlt() == o2.GetAlt() && o1.GetSemanticContext().Equals(o2.GetSemanticContext()) @@ -86,20 +86,20 @@ type ATNAltConfigComparator[T Collectable[T]] struct { // Equals2 is a custom comparator for ATNConfigs specifically for configLookup func (c *ATNAltConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { - + // Same pointer, must be equal, even if both nil // if o1 == o2 { return true - + } - + // If either are nil, but not both, then the result is false // if o1 == nil || o2 == nil { return false } - + return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && o1.GetContext().Equals(o2.GetContext()) } @@ -120,20 +120,20 @@ type BaseATNConfigComparator[T Collectable[T]] struct { // Equals2 is a custom comparator for ATNConfigs specifically for baseATNConfigSet func (c *BaseATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { - + // Same pointer, must be equal, even if both nil // if o1 == o2 { return true - + } - + // If either are nil, but not both, then the result is false // if o1 == nil || o2 == nil { return false } - + return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && o1.GetAlt() == o2.GetAlt() && o1.GetSemanticContext().Equals(o2.GetSemanticContext()) @@ -142,6 +142,6 @@ func (c *BaseATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { // Hash1 is custom hash implementation for ATNConfigs specifically for configLookup, but in fact just // delegates to the standard Hash() method of the ATNConfig type. func (c *BaseATNConfigComparator[T]) Hash1(o ATNConfig) int { - + return o.Hash() } diff --git a/runtime/Go/antlr/v4/dfa.go b/runtime/Go/antlr/v4/dfa.go index 61d70f6325..74a06d4757 100644 --- a/runtime/Go/antlr/v4/dfa.go +++ b/runtime/Go/antlr/v4/dfa.go @@ -9,22 +9,21 @@ package antlr type DFA struct { // atnStartState is the ATN state in which this was created atnStartState DecisionState - + decision int - + // states is all the DFA states. Use Map to get the old state back; Set can only // indicate whether it is there. Go maps implement key hash collisions and so on and are very - // good, but the DFAState is an object and can't be used directly as the key as it can in say JAva + // good, but the DFAState is an object and can't be used directly as the key as it can in say Java // amd C#, whereby if the hashcode is the same for two objects, then Equals() is called against them - // to see if they really are the same object. - // + // to see if they really are the same object. Hence, we have our own map storage. // states *JStore[*DFAState, *ObjEqComparator[*DFAState]] - + numstates int - + s0 *DFAState - + // precedenceDfa is the backing field for isPrecedenceDfa and setPrecedenceDfa. // True if the DFA is for a precedence decision and false otherwise. precedenceDfa bool @@ -53,12 +52,12 @@ func (d *DFA) getPrecedenceStartState(precedence int) *DFAState { if !d.getPrecedenceDfa() { panic("only precedence DFAs may contain a precedence start state") } - + // s0.edges is never nil for a precedence DFA if precedence < 0 || precedence >= len(d.getS0().getEdges()) { return nil } - + return d.getS0().getIthEdge(precedence) } @@ -68,11 +67,11 @@ func (d *DFA) setPrecedenceStartState(precedence int, startState *DFAState) { if !d.getPrecedenceDfa() { panic("only precedence DFAs may contain a precedence start state") } - + if precedence < 0 { return } - + // Synchronization on s0 here is ok. When the DFA is turned into a // precedence DFA, s0 will be initialized once and not updated again. s0.edges // is never nil for a precedence DFA. @@ -82,7 +81,7 @@ func (d *DFA) setPrecedenceStartState(precedence int, startState *DFAState) { s0.setEdges(edges) d.setS0(s0) } - + s0.setIthEdge(precedence, startState) } @@ -99,10 +98,10 @@ func (d *DFA) setPrecedenceDfa(precedenceDfa bool) { if d.getPrecedenceDfa() != precedenceDfa { d.states = NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst) d.numstates = 0 - + if precedenceDfa { precedenceState := NewDFAState(-1, NewBaseATNConfigSet(false)) - + precedenceState.setEdges(make([]*DFAState, 0)) precedenceState.isAcceptState = false precedenceState.requiresFullContext = false @@ -110,7 +109,7 @@ func (d *DFA) setPrecedenceDfa(precedenceDfa bool) { } else { d.setS0(nil) } - + d.precedenceDfa = precedenceDfa } } @@ -125,11 +124,11 @@ func (d *DFA) setS0(s *DFAState) { // sortedStates returns the states in d sorted by their state number. func (d *DFA) sortedStates() []*DFAState { - + vs := d.states.SortedSlice(func(i, j *DFAState) bool { return i.stateNumber < j.stateNumber }) - + return vs } @@ -137,7 +136,7 @@ func (d *DFA) String(literalNames []string, symbolicNames []string) string { if d.getS0() == nil { return "" } - + return NewDFASerializer(d, literalNames, symbolicNames).String() } @@ -145,6 +144,6 @@ func (d *DFA) ToLexerString() string { if d.getS0() == nil { return "" } - + return NewLexerDFASerializer(d).String() } diff --git a/runtime/Go/antlr/v4/empty_prediction_context.go b/runtime/Go/antlr/v4/empty_prediction_context.go new file mode 100644 index 0000000000..58ab8ba487 --- /dev/null +++ b/runtime/Go/antlr/v4/empty_prediction_context.go @@ -0,0 +1,56 @@ +package antlr + +var _emptyPredictionContextHash int + +func init() { + _emptyPredictionContextHash = murmurInit(1) + _emptyPredictionContextHash = murmurFinish(_emptyPredictionContextHash, 0) +} + +func calculateEmptyHash() int { + return _emptyPredictionContextHash +} + +type EmptyPredictionContext struct { + BaseSingletonPredictionContext +} + +func NewEmptyPredictionContext() *EmptyPredictionContext { + return &EmptyPredictionContext{ + BaseSingletonPredictionContext: BaseSingletonPredictionContext{ + BasePredictionContext: BasePredictionContext{ + cachedHash: calculateEmptyHash(), + pcType: PredictionContextEmpty, + }, + parentCtx: nil, + returnState: BasePredictionContextEmptyReturnState, + }, + } +} +func (e *EmptyPredictionContext) length() int { + return 1 +} + +func (e *EmptyPredictionContext) isEmpty() bool { + return true +} + +func (e *EmptyPredictionContext) GetParent(_ int) PredictionContext { + return nil +} + +func (e *EmptyPredictionContext) getReturnState(_ int) int { + return e.returnState +} + +func (e *EmptyPredictionContext) Hash() int { + return e.cachedHash +} + +func (e *EmptyPredictionContext) Equals(other interface{}) bool { + return e == other +} + +func (e *EmptyPredictionContext) String() string { + return "$" +} diff --git a/runtime/Go/antlr/v4/error_strategy.go b/runtime/Go/antlr/v4/error_strategy.go index f6fd9afc76..102dca2942 100644 --- a/runtime/Go/antlr/v4/error_strategy.go +++ b/runtime/Go/antlr/v4/error_strategy.go @@ -32,9 +32,9 @@ type DefaultErrorStrategy struct { var _ ErrorStrategy = &DefaultErrorStrategy{} func NewDefaultErrorStrategy() *DefaultErrorStrategy { - + d := new(DefaultErrorStrategy) - + // Indicates whether the error strategy is currently "recovering from an // error". This is used to suppress Reporting multiple error messages while // attempting to recover from a detected syntax error. @@ -42,7 +42,7 @@ func NewDefaultErrorStrategy() *DefaultErrorStrategy { // @see //InErrorRecoveryMode // d.errorRecoveryMode = false - + // The index into the input stream where the last error occurred. // This is used to prevent infinite loops where an error is found // but no token is consumed during recovery...another error is found, @@ -100,7 +100,7 @@ func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionExcep return // don't Report spurious errors } d.beginErrorCondition(recognizer) - + switch t := e.(type) { default: fmt.Println("unknown recognition error type: " + reflect.TypeOf(e).Name()) @@ -190,16 +190,16 @@ func (d *DefaultErrorStrategy) Sync(recognizer Parser) { if d.InErrorRecoveryMode(recognizer) { return } - + s := recognizer.GetInterpreter().atn.states[recognizer.GetState()] la := recognizer.GetTokenStream().LA(1) - + // try cheaper subset first might get lucky. seems to shave a wee bit off nextTokens := recognizer.GetATN().NextTokens(s, nil) if nextTokens.contains(TokenEpsilon) || nextTokens.contains(la) { return } - + switch s.GetStateType() { case ATNStateBlockStart, ATNStateStarBlockStart, ATNStatePlusBlockStart, ATNStateStarLoopEntry: // Report error and recover if possible @@ -392,7 +392,7 @@ func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool { d.ReportMissingToken(recognizer) return true } - + return false } @@ -426,7 +426,7 @@ func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token { d.ReportMatch(recognizer) // we know current token is correct return MatchedSymbol } - + return nil } @@ -457,7 +457,7 @@ func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token { expecting := d.GetExpectedTokens(recognizer) expectedTokenType := expecting.first() var tokenText string - + if expectedTokenType == TokenEOF { tokenText = "" } else { @@ -465,7 +465,7 @@ func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token { if expectedTokenType > 0 && expectedTokenType < len(ln) { tokenText = "" } else { - tokenText = "" // TODO matches the JS impl + tokenText = "" // TODO: matches the JS impl } } current := currentSymbol @@ -473,9 +473,9 @@ func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token { if current.GetTokenType() == TokenEOF && lookback != nil { current = lookback } - + tf := recognizer.GetTokenFactory() - + return tf.Create(current.GetSource(), expectedTokenType, tokenText, TokenDefaultChannel, -1, -1, current.GetLine(), current.GetColumn()) } @@ -663,11 +663,11 @@ var _ ErrorStrategy = &BailErrorStrategy{} //goland:noinspection GoUnusedExportedFunction func NewBailErrorStrategy() *BailErrorStrategy { - + b := new(BailErrorStrategy) - + b.DefaultErrorStrategy = NewDefaultErrorStrategy() - + return b } @@ -685,14 +685,14 @@ func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) { context = nil } } - panic(NewParseCancellationException()) // TODO we don't emit e properly + panic(NewParseCancellationException()) // TODO: we don't emit e properly } // RecoverInline makes sure we don't attempt to recover inline if the parser // successfully recovers, it won't panic an exception. func (b *BailErrorStrategy) RecoverInline(recognizer Parser) Token { b.Recover(recognizer, NewInputMisMatchException(recognizer)) - + return nil } diff --git a/runtime/Go/antlr/v4/errors.go b/runtime/Go/antlr/v4/errors.go index df2fc1c73a..74ae1b1919 100644 --- a/runtime/Go/antlr/v4/errors.go +++ b/runtime/Go/antlr/v4/errors.go @@ -26,7 +26,7 @@ type BaseRecognitionException struct { } func NewBaseRecognitionException(message string, recognizer Recognizer, input IntStream, ctx RuleContext) *BaseRecognitionException { - + // todo // Error.call(this) // @@ -35,10 +35,10 @@ func NewBaseRecognitionException(message string, recognizer Recognizer, input In // } else { // stack := NewError().stack // } - // TODO may be able to use - "runtime" func Stack(buf []byte, all bool) int - + // TODO: may be able to use - "runtime" func Stack(buf []byte, all bool) int + t := new(BaseRecognitionException) - + t.message = message t.recognizer = recognizer t.input = input @@ -58,7 +58,7 @@ func NewBaseRecognitionException(message string, recognizer Recognizer, input In if t.recognizer != nil { t.offendingState = t.recognizer.GetState() } - + return t } @@ -88,7 +88,7 @@ func (b *BaseRecognitionException) getExpectedTokens() *IntervalSet { if b.recognizer != nil { return b.recognizer.GetATN().getExpectedTokens(b.offendingState, b.ctx) } - + return nil } @@ -98,20 +98,20 @@ func (b *BaseRecognitionException) String() string { type LexerNoViableAltException struct { *BaseRecognitionException - + startIndex int deadEndConfigs ATNConfigSet } func NewLexerNoViableAltException(lexer Lexer, input CharStream, startIndex int, deadEndConfigs ATNConfigSet) *LexerNoViableAltException { - + l := new(LexerNoViableAltException) - + l.BaseRecognitionException = NewBaseRecognitionException("", lexer, input, nil) - + l.startIndex = startIndex l.deadEndConfigs = deadEndConfigs - + return l } @@ -125,7 +125,7 @@ func (l *LexerNoViableAltException) String() string { type NoViableAltException struct { *BaseRecognitionException - + startToken Token offendingToken Token ctx ParserRuleContext @@ -139,26 +139,26 @@ type NoViableAltException struct { // // Reported by [ReportNoViableAlternative] func NewNoViableAltException(recognizer Parser, input TokenStream, startToken Token, offendingToken Token, deadEndConfigs ATNConfigSet, ctx ParserRuleContext) *NoViableAltException { - + if ctx == nil { ctx = recognizer.GetParserRuleContext() } - + if offendingToken == nil { offendingToken = recognizer.GetCurrentToken() } - + if startToken == nil { startToken = recognizer.GetCurrentToken() } - + if input == nil { input = recognizer.GetInputStream().(TokenStream) } - + n := new(NoViableAltException) n.BaseRecognitionException = NewBaseRecognitionException("", recognizer, input, ctx) - + // Which configurations did we try at input.Index() that couldn't Match // input.LT(1) n.deadEndConfigs = deadEndConfigs @@ -170,7 +170,7 @@ func NewNoViableAltException(recognizer Parser, input TokenStream, startToken To // buffer of all the tokens, but later we might not have access to those. n.startToken = startToken n.offendingToken = offendingToken - + return n } @@ -181,14 +181,14 @@ type InputMisMatchException struct { // NewInputMisMatchException creates an exception that signifies any kind of mismatched input exceptions such as // when the current input does not Match the expected token. func NewInputMisMatchException(recognizer Parser) *InputMisMatchException { - + i := new(InputMisMatchException) i.BaseRecognitionException = NewBaseRecognitionException("", recognizer, recognizer.GetInputStream(), recognizer.GetParserRuleContext()) - + i.offendingToken = recognizer.GetCurrentToken() - + return i - + } // FailedPredicateException indicates that a semantic predicate failed during validation. Validation of predicates @@ -197,7 +197,7 @@ func NewInputMisMatchException(recognizer Parser) *InputMisMatchException { // prediction. type FailedPredicateException struct { *BaseRecognitionException - + ruleIndex int predicateIndex int predicate string @@ -205,11 +205,11 @@ type FailedPredicateException struct { //goland:noinspection GoUnusedExportedFunction func NewFailedPredicateException(recognizer Parser, predicate string, message string) *FailedPredicateException { - + f := new(FailedPredicateException) - + f.BaseRecognitionException = NewBaseRecognitionException(f.formatMessage(predicate, message), recognizer, recognizer.GetInputStream(), recognizer.GetParserRuleContext()) - + s := recognizer.GetInterpreter().atn.states[recognizer.GetState()] trans := s.GetTransitions()[0] if trans2, ok := trans.(*PredicateTransition); ok { @@ -221,7 +221,7 @@ func NewFailedPredicateException(recognizer Parser, predicate string, message st } f.predicate = predicate f.offendingToken = recognizer.GetCurrentToken() - + return f } @@ -229,7 +229,7 @@ func (f *FailedPredicateException) formatMessage(predicate, message string) stri if message != "" { return message } - + return "failed predicate: {" + predicate + "}?" } diff --git a/runtime/Go/antlr/v4/interval_set.go b/runtime/Go/antlr/v4/interval_set.go index c83daff75b..96f1a8b15e 100644 --- a/runtime/Go/antlr/v4/interval_set.go +++ b/runtime/Go/antlr/v4/interval_set.go @@ -17,7 +17,7 @@ type Interval struct { // NewInterval creates a new interval with the given start and stop values. func NewInterval(start, stop int) *Interval { i := new(Interval) - + i.Start = start i.Stop = stop return i @@ -33,7 +33,7 @@ func (i *Interval) String() string { if i.Start == i.Stop-1 { return strconv.Itoa(i.Start) } - + return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop-1) } @@ -50,20 +50,34 @@ type IntervalSet struct { // NewIntervalSet creates a new empty, writable, interval set. func NewIntervalSet() *IntervalSet { - + i := new(IntervalSet) - + i.intervals = nil i.readOnly = false - + return i } +func (i *IntervalSet) Equals(other *IntervalSet) bool { + if len(i.intervals) != len(other.intervals) { + return false + } + + for k, v := range i.intervals { + if v.Start != other.intervals[k].Start || v.Stop != other.intervals[k].Stop { + return false + } + } + + return true +} + func (i *IntervalSet) first() int { if len(i.intervals) == 0 { return TokenInvalidType } - + return i.intervals[0].Start } @@ -91,7 +105,7 @@ func (i *IntervalSet) addInterval(v *Interval) { return } else if v.Start <= interval.Stop { i.intervals[k] = NewInterval(intMin(interval.Start, v.Start), intMax(interval.Stop, v.Stop)) - + // if not applying to end, merge potential overlaps if k < len(i.intervals)-1 { l := i.intervals[k] @@ -216,7 +230,7 @@ func (i *IntervalSet) String() string { } func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []string, elemsAreChar bool) string { - + if i.intervals == nil { return "{}" } else if literalNames != nil || symbolicNames != nil { @@ -224,7 +238,7 @@ func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []strin } else if elemsAreChar { return i.toCharString() } - + return i.toIndexString() } @@ -234,9 +248,9 @@ func (i *IntervalSet) GetIntervals() []*Interval { func (i *IntervalSet) toCharString() string { names := make([]string, len(i.intervals)) - + var sb strings.Builder - + for j := 0; j < len(i.intervals); j++ { v := i.intervals[j] if v.Stop == v.Start+1 { @@ -262,12 +276,12 @@ func (i *IntervalSet) toCharString() string { if len(names) > 1 { return "{" + strings.Join(names, ", ") + "}" } - + return names[0] } func (i *IntervalSet) toIndexString() string { - + names := make([]string, 0) for j := 0; j < len(i.intervals); j++ { v := i.intervals[j] @@ -284,7 +298,7 @@ func (i *IntervalSet) toIndexString() string { if len(names) > 1 { return "{" + strings.Join(names, ", ") + "}" } - + return names[0] } @@ -298,7 +312,7 @@ func (i *IntervalSet) toTokenString(literalNames []string, symbolicNames []strin if len(names) > 1 { return "{" + strings.Join(names, ", ") + "}" } - + return names[0] } @@ -311,7 +325,7 @@ func (i *IntervalSet) elementName(literalNames []string, symbolicNames []string, if a < len(literalNames) && literalNames[a] != "" { return literalNames[a] } - + return symbolicNames[a] } } diff --git a/runtime/Go/antlr/v4/lexer_atn_simulator.go b/runtime/Go/antlr/v4/lexer_atn_simulator.go index 98cbb96814..2a16341999 100644 --- a/runtime/Go/antlr/v4/lexer_atn_simulator.go +++ b/runtime/Go/antlr/v4/lexer_atn_simulator.go @@ -14,16 +14,16 @@ import ( var ( LexerATNSimulatorDebug = false LexerATNSimulatorDFADebug = false - + LexerATNSimulatorMinDFAEdge = 0 LexerATNSimulatorMaxDFAEdge = 127 // forces unicode to stay in ATN - + LexerATNSimulatorMatchCalls = 0 ) type ILexerATNSimulator interface { IATNSimulator - + reset() Match(input CharStream, mode int) int GetCharPositionInLine() int @@ -33,8 +33,8 @@ type ILexerATNSimulator interface { } type LexerATNSimulator struct { - *BaseATNSimulator - + BaseATNSimulator + recog Lexer predictionMode int mergeCache DoubleDict @@ -47,27 +47,35 @@ type LexerATNSimulator struct { } func NewLexerATNSimulator(recog Lexer, atn *ATN, decisionToDFA []*DFA, sharedContextCache *PredictionContextCache) *LexerATNSimulator { - l := new(LexerATNSimulator) - - l.BaseATNSimulator = NewBaseATNSimulator(atn, sharedContextCache) - + l := &LexerATNSimulator{ + BaseATNSimulator: BaseATNSimulator{ + atn: atn, + sharedContextCache: sharedContextCache, + }, + } + l.decisionToDFA = decisionToDFA l.recog = recog + // The current token's starting index into the character stream. // Shared across DFA to ATN simulation in case the ATN fails and the // DFA did not have a previous accept state. In l case, we use the // ATN-generated exception object. l.startIndex = -1 - // line number 1..n within the input/// + + // line number 1..n within the input l.Line = 1 + // The index of the character relative to the beginning of the line - // 0..n-1/// + // 0..n-1 l.CharPositionInLine = 0 + l.mode = LexerDefaultMode + // Used during DFA/ATN exec to record the most recent accept configuration // info l.prevAccept = NewSimState() - // done + return l } @@ -82,25 +90,25 @@ func (l *LexerATNSimulator) Match(input CharStream, mode int) int { l.MatchCalls++ l.mode = mode mark := input.Mark() - + defer func() { input.Release(mark) }() - + l.startIndex = input.Index() l.prevAccept.reset() - + dfa := l.decisionToDFA[mode] - + var s0 *DFAState l.atn.stateMu.RLock() s0 = dfa.getS0() l.atn.stateMu.RUnlock() - + if s0 == nil { return l.MatchATN(input) } - + return l.execATN(input, s0) } @@ -123,9 +131,9 @@ func (l *LexerATNSimulator) MatchATN(input CharStream) int { s0Closure := l.computeStartState(input, startState) suppressEdge := s0Closure.hasSemanticContext s0Closure.hasSemanticContext = false - + next := l.addDFAState(s0Closure, suppressEdge) - + predict := l.execATN(input, next) if //goland:noinspection GoBoolExpressions @@ -147,13 +155,13 @@ func (l *LexerATNSimulator) execATN(input CharStream, ds0 *DFAState) int { } t := input.LA(1) s := ds0 // s is current/from DFA state - + for { // while more work if //goland:noinspection GoBoolExpressions LexerATNSimulatorDebug { fmt.Println("execATN loop starting closure: " + s.configs.String()) } - + // As we move src->trg, src->trg, we keep track of the previous trg to // avoid looking up the DFA state again, which is expensive. // If the previous target was already part of the DFA, we might @@ -195,7 +203,7 @@ func (l *LexerATNSimulator) execATN(input CharStream, ds0 *DFAState) int { t = input.LA(1) s = target // flip current DFA target becomes new src/from state } - + return l.failOrAccept(l.prevAccept, input, s.configs, t) } @@ -212,7 +220,7 @@ func (l *LexerATNSimulator) getExistingTargetState(s *DFAState, t int) *DFAState if t < LexerATNSimulatorMinDFAEdge || t > LexerATNSimulatorMaxDFAEdge { return nil } - + l.atn.edgeMu.RLock() defer l.atn.edgeMu.RUnlock() if s.getEdges() == nil { @@ -234,11 +242,11 @@ func (l *LexerATNSimulator) getExistingTargetState(s *DFAState, t int) *DFAState // returns ATNSimulatorError. func (l *LexerATNSimulator) computeTargetState(input CharStream, s *DFAState, t int) *DFAState { reach := NewOrderedATNConfigSet() - + // if we don't find an existing DFA state // Fill reach starting from closure, following t transitions l.getReachableConfigSet(input, s.configs, reach.BaseATNConfigSet, t) - + if len(reach.configs) == 0 { // we got nowhere on t from s if !reach.hasSemanticContext { // we got nowhere on t, don't panic out l knowledge it'd @@ -258,12 +266,12 @@ func (l *LexerATNSimulator) failOrAccept(prevAccept *SimState, input CharStream, l.accept(input, lexerActionExecutor, l.startIndex, prevAccept.index, prevAccept.line, prevAccept.column) return prevAccept.dfaState.prediction } - + // if no accept and EOF is first char, return EOF if t == TokenEOF && input.Index() == l.startIndex { return TokenEOF } - + panic(NewLexerNoViableAltException(l.recog, input, l.startIndex, reach)) } @@ -275,7 +283,7 @@ func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNC // l is used to Skip processing for configs which have a lower priority // than a config that already reached an accept state for the same rule SkipAlt := ATNInvalidAltNumber - + for _, cfg := range closure.GetItems() { currentAltReachedAcceptState := cfg.GetAlt() == SkipAlt if currentAltReachedAcceptState && cfg.(*LexerATNConfig).passedThroughNonGreedyDecision { @@ -287,7 +295,7 @@ func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNC fmt.Printf("testing %s at %s\n", l.GetTokenName(t), cfg.String()) } - + for _, trans := range cfg.GetState().GetTransitions() { target := l.getReachableTarget(trans, t) if target != nil { @@ -326,7 +334,7 @@ func (l *LexerATNSimulator) getReachableTarget(trans Transition, t int) ATNState if trans.Matches(t, 0, LexerMaxCharValue) { return trans.getTarget() } - + return nil } @@ -337,7 +345,7 @@ func (l *LexerATNSimulator) computeStartState(input CharStream, p ATNState) *Ord cfg := NewLexerATNConfig6(target, i+1, BasePredictionContextEMPTY) l.closure(input, cfg, configs, false, false, false) } - + return configs } @@ -355,7 +363,7 @@ func (l *LexerATNSimulator) closure(input CharStream, config *LexerATNConfig, co LexerATNSimulatorDebug { fmt.Println("closure(" + config.String() + ")") } - + _, ok := config.state.(*RuleStopState) if ok { @@ -367,13 +375,13 @@ func (l *LexerATNSimulator) closure(input CharStream, config *LexerATNConfig, co fmt.Printf("closure at rule stop %s\n", config) } } - + if config.context == nil || config.context.hasEmptyPath() { if config.context == nil || config.context.isEmpty() { configs.Add(config, nil) return true } - + configs.Add(NewLexerATNConfig2(config, config.state, BasePredictionContextEMPTY), nil) currentAltReachedAcceptState = true } @@ -409,15 +417,15 @@ func (l *LexerATNSimulator) closure(input CharStream, config *LexerATNConfig, co // side-effect: can alter configs.hasSemanticContext func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNConfig, trans Transition, configs ATNConfigSet, speculative, treatEOFAsEpsilon bool) *LexerATNConfig { - + var cfg *LexerATNConfig - + if trans.getSerializationType() == TransitionRULE { - + rt := trans.(*RuleTransition) newContext := SingletonBasePredictionContextCreate(config.context, rt.followState.GetStateNumber()) cfg = NewLexerATNConfig2(config, trans.getTarget(), newContext) - + } else if trans.getSerializationType() == TransitionPRECEDENCE { panic("Precedence predicates are not supported in lexers.") } else if trans.getSerializationType() == TransitionPREDICATE { @@ -430,15 +438,15 @@ func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNC // semantically it's not used that often. One of the key elements to // l predicate mechanism is not adding DFA states that see // predicates immediately afterwards in the ATN. For example, - + // a : ID {p1}? | ID {p2}? - + // should create the start state for rule 'a' (to save start state // competition), but should not create target of ID state. The // collection of ATN states the following ID references includes // states reached by traversing predicates. Since l is when we // test them, we cannot cash the DFA state target of ID. - + pt := trans.(*PredicateTransition) if //goland:noinspection GoBoolExpressions @@ -456,7 +464,7 @@ func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNC // TODO: if the entry rule is invoked recursively, some // actions may be executed during the recursive call. The // problem can appear when hasEmptyPath() is true but - // isEmpty() is false. In l case, the config needs to be + // isEmpty() is false. In this case, the config needs to be // split into two contexts - one with just the empty path // and another with everything but the empty path. // Unfortunately, the current algorithm does not allow @@ -507,14 +515,14 @@ func (l *LexerATNSimulator) evaluatePredicate(input CharStream, ruleIndex, predI savedLine := l.Line index := input.Index() marker := input.Mark() - + defer func() { l.CharPositionInLine = savedcolumn l.Line = savedLine input.Seek(index) input.Release(marker) }() - + l.Consume(input) return l.recog.Sempred(nil, ruleIndex, predIndex) } @@ -541,9 +549,9 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg // / suppressEdge := cfgs.HasSemanticContext() cfgs.SetHasSemanticContext(false) - + to = l.addDFAState(cfgs, true) - + if suppressEdge { return to } @@ -564,7 +572,7 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg from.setEdges(make([]*DFAState, LexerATNSimulatorMaxDFAEdge-LexerATNSimulatorMinDFAEdge+1)) } from.setIthEdge(tk-LexerATNSimulatorMinDFAEdge, to) // connect - + return to } @@ -573,14 +581,14 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg // configuration containing an ATN rule stop state. Later, when // traversing the DFA, we will know which rule to accept. func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool) *DFAState { - + proposed := NewDFAState(-1, configs) var firstConfigWithRuleStopState ATNConfig - + for _, cfg := range configs.GetItems() { - + _, ok := cfg.GetState().(*RuleStopState) - + if ok { firstConfigWithRuleStopState = cfg break @@ -592,17 +600,17 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool) proposed.setPrediction(l.atn.ruleToTokenType[firstConfigWithRuleStopState.GetState().GetRuleIndex()]) } dfa := l.decisionToDFA[l.mode] - + l.atn.stateMu.Lock() defer l.atn.stateMu.Unlock() existing, present := dfa.states.Get(proposed) if present { - + // This state was already present, so just return it. // proposed = existing } else { - + // We need to add the new state // proposed.stateNumber = dfa.states.Len() @@ -649,13 +657,13 @@ func (l *LexerATNSimulator) GetTokenName(tt int) string { if tt == -1 { return "EOF" } - + var sb strings.Builder sb.Grow(6) sb.WriteByte('\'') sb.WriteRune(rune(tt)) sb.WriteByte('\'') - + return sb.String() } diff --git a/runtime/Go/antlr/v4/parser_atn_simulator.go b/runtime/Go/antlr/v4/parser_atn_simulator.go index 0aea7c3eab..d143cbb2c5 100644 --- a/runtime/Go/antlr/v4/parser_atn_simulator.go +++ b/runtime/Go/antlr/v4/parser_atn_simulator.go @@ -19,8 +19,8 @@ var ( ) type ParserATNSimulator struct { - *BaseATNSimulator - + BaseATNSimulator + parser Parser predictionMode int input TokenStream @@ -32,11 +32,14 @@ type ParserATNSimulator struct { //goland:noinspection GoUnusedExportedFunction func NewParserATNSimulator(parser Parser, atn *ATN, decisionToDFA []*DFA, sharedContextCache *PredictionContextCache) *ParserATNSimulator { - - p := new(ParserATNSimulator) - - p.BaseATNSimulator = NewBaseATNSimulator(atn, sharedContextCache) - + + p := &ParserATNSimulator{ + BaseATNSimulator: BaseATNSimulator{ + atn: atn, + sharedContextCache: sharedContextCache, + }, + } + p.parser = parser p.decisionToDFA = decisionToDFA // SLL, LL, or LL + exact ambig detection?// @@ -55,7 +58,7 @@ func NewParserATNSimulator(parser Parser, atn *ATN, decisionToDFA []*DFA, shared // also be examined during cache lookup. // p.mergeCache = nil - + return p } @@ -78,23 +81,23 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn())) } - + p.input = input p.startIndex = input.Index() p.outerContext = outerContext - + dfa := p.decisionToDFA[decision] p.dfa = dfa m := input.Mark() index := input.Index() - + defer func() { p.dfa = nil p.mergeCache = nil // wack cache after each prediction input.Seek(index) input.Release(m) }() - + // Now we are certain to have a specific decision's DFA // But, do we still need an initial state? var s0 *DFAState @@ -110,7 +113,7 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou s0 = dfa.getS0() } p.atn.stateMu.RUnlock() - + if s0 == nil { if outerContext == nil { outerContext = ParserRuleContextEmpty @@ -122,7 +125,7 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou } fullCtx := false s0Closure := p.computeStartState(dfa.atnStartState, ParserRuleContextEmpty, fullCtx) - + p.atn.stateMu.Lock() if dfa.getPrecedenceDfa() { // If p is a precedence DFA, we use applyPrecedenceFilter @@ -143,13 +146,13 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou } p.atn.stateMu.Unlock() } - + alt := p.execATN(dfa, s0, input, index, outerContext) if ParserATNSimulatorDebug { fmt.Println("DFA after predictATN: " + dfa.String(p.parser.GetLiteralNames(), nil)) } return alt - + } // execATN performs ATN simulation to compute a predicted alternative based @@ -187,16 +190,16 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou // //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, startIndex int, outerContext ParserRuleContext) int { - + if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("execATN decision " + strconv.Itoa(dfa.decision) + ", DFA state " + s0.String() + ", LA(1)==" + p.getLookaheadName(input) + " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn())) } - + previousD := s0 - + if ParserATNSimulatorDebug { fmt.Println("s0 = " + s0.String()) } @@ -222,7 +225,7 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, if alt != ATNInvalidAltNumber { return alt } - + panic(e) } if D.requiresFullContext && p.predictionMode != PredictionModeSLL { @@ -265,7 +268,7 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, stopIndex := input.Index() input.Seek(startIndex) alts := p.evalSemanticContext(D.predicates, outerContext, true) - + switch alts.length() { case 0: panic(p.noViableAlt(input, outerContext, D.configs, startIndex)) @@ -278,7 +281,7 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, } } previousD = D - + if t != TokenEOF { input.Consume() t = input.LA(1) @@ -300,7 +303,7 @@ func (p *ParserATNSimulator) getExistingTargetState(previousD *DFAState, t int) if t+1 < 0 { return nil } - + p.atn.edgeMu.RLock() defer p.atn.edgeMu.RUnlock() edges := previousD.getEdges() @@ -324,16 +327,16 @@ func (p *ParserATNSimulator) getExistingTargetState(previousD *DFAState, t int) //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) computeTargetState(dfa *DFA, previousD *DFAState, t int) *DFAState { reach := p.computeReachSet(previousD.configs, t, false) - + if reach == nil { p.addDFAEdge(dfa, previousD, t, ATNSimulatorError) return ATNSimulatorError } // create new target state we'll add to DFA after it's complete D := NewDFAState(-1, reach) - + predictedAlt := p.getUniqueAlt(reach) - + if ParserATNSimulatorDebug { altSubSets := PredictionModegetConflictingAltSubsets(reach) fmt.Println("SLL altSubSets=" + fmt.Sprint(altSubSets) + @@ -391,11 +394,11 @@ func (p *ParserATNSimulator) predicateDFAState(dfaState *DFAState, decisionState // //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 ATNConfigSet, input TokenStream, startIndex int, outerContext ParserRuleContext) int { - + if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("execATNWithFullContext " + s0.String()) } - + fullCtx := true foundExactAmbig := false var reach ATNConfigSet @@ -403,7 +406,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT input.Seek(startIndex) t := input.LA(1) predictedAlt := -1 - + for { // for more work reach = p.computeReachSet(previous, t, fullCtx) if reach == nil { @@ -422,7 +425,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT if alt != ATNInvalidAltNumber { return alt } - + panic(e) } altSubSets := PredictionModegetConflictingAltSubsets(reach) @@ -469,7 +472,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT } // We do not check predicates here because we have checked them // on-the-fly when doing full context prediction. - + // // In non-exact ambiguity detection mode, we might actually be able to // detect an exact ambiguity, but I'm not going to spend the cycles @@ -479,9 +482,9 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT // For example, we might know that we have conflicting configurations. // But, that does not mean that there is no way forward without a // conflict. It's possible to have non-conflicting alt subsets as in: - + // // altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}] - + // // from // // [(17,1,[5 $]), (13,1,[5 10 $]), (21,1,[5 10 $]), (11,1,[$]), @@ -493,9 +496,9 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT // looking for input because no amount of further lookahead will alter // the fact that we should predict alternative 1. We just can't say for // sure that there is an ambiguity without looking further. - + p.ReportAmbiguity(dfa, D, startIndex, input.Index(), foundExactAmbig, reach.Alts(), reach) - + return predictedAlt } @@ -505,7 +508,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt p.mergeCache = NewDoubleDict() } intermediate := NewBaseATNConfigSet(fullCtx) - + // Configurations already in a rule stop state indicate reaching the end // of the decision rule (local context) or end of the start rule (full // context). Once reached, these configurations are never updated by a @@ -515,15 +518,15 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // For full-context reach operations, separate handling is required to // ensure that the alternative Matching the longest overall sequence is // chosen when multiple such configurations can Match the input. - + var skippedStopStates []*BaseATNConfig - + // First figure out where we can reach on input t for _, c := range closure.GetItems() { if ParserATNSimulatorDebug { fmt.Println("testing " + p.GetTokenName(t) + " at " + c.String()) } - + if _, ok := c.GetState().(*RuleStopState); ok { if fullCtx || t == TokenEOF { skippedStopStates = append(skippedStopStates, c.(*BaseATNConfig)) @@ -533,7 +536,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt } continue } - + for _, trans := range c.GetState().GetTransitions() { target := p.getReachableTarget(trans, t) if target != nil { @@ -545,10 +548,10 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt } } } - + // Now figure out where the reach operation can take us... var reach ATNConfigSet - + // This block optimizes the reach operation for intermediate sets which // trivially indicate a termination state for the overall // AdaptivePredict operation. @@ -616,15 +619,15 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt reach.Add(skippedStopStates[l], p.mergeCache) } } - + if ParserATNSimulatorTraceATNSim { fmt.Println("computeReachSet " + closure.String() + " -> " + reach.String()) } - + if len(reach.GetItems()) == 0 { return nil } - + return reach } @@ -675,7 +678,7 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full fmt.Println("computeStartState from ATN state " + a.String() + " initialContext=" + initialContext.String()) } - + for i := 0; i < len(a.GetTransitions()); i++ { target := a.GetTransitions()[i].getTarget() c := NewBaseATNConfig6(target, i+1, initialContext) @@ -729,10 +732,10 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full // for a precedence [DFA] at a particular precedence level (determined by // calling [Parser].getPrecedence). func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConfigSet { - + statesFromAlt1 := make(map[int]PredictionContext) configSet := NewBaseATNConfigSet(configs.FullContext()) - + for _, config := range configs.GetItems() { // handle alt 1 first if config.GetAlt() != 1 { @@ -751,7 +754,7 @@ func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConf } } for _, config := range configs.GetItems() { - + if config.GetAlt() == 1 { // already handled continue @@ -775,13 +778,13 @@ func (p *ParserATNSimulator) getReachableTarget(trans Transition, ttype int) ATN if trans.Matches(ttype, 0, p.atn.maxTokenType) { return trans.getTarget() } - + return nil } //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs ATNConfigSet, nalts int) []SemanticContext { - + altToPred := make([]SemanticContext, nalts+1) for _, c := range configs.GetItems() { if ambigAlts.contains(c.GetAlt()) { @@ -881,10 +884,10 @@ func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntry func (p *ParserATNSimulator) GetAltThatFinishedDecisionEntryRule(configs ATNConfigSet) int { alts := NewIntervalSet() - + for _, c := range configs.GetItems() { _, ok := c.GetState().(*RuleStopState) - + if c.GetReachesIntoOuterContext() > 0 || (ok && c.GetContext().hasEmptyPath()) { alts.addOne(c.GetAlt()) } @@ -892,7 +895,7 @@ func (p *ParserATNSimulator) GetAltThatFinishedDecisionEntryRule(configs ATNConf if alts.length() == 0 { return ATNInvalidAltNumber } - + return alts.first() } @@ -912,7 +915,7 @@ type ATNConfigSetPair struct { func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigSet, outerContext ParserRuleContext) []ATNConfigSet { succeeded := NewBaseATNConfigSet(configs.FullContext()) failed := NewBaseATNConfigSet(configs.FullContext()) - + for _, c := range configs.GetItems() { if c.GetSemanticContext() != SemanticContextNone { predicateEvaluationResult := c.GetSemanticContext().evaluate(p.parser, outerContext) @@ -946,7 +949,7 @@ func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPredicti } continue } - + predicateEvaluationResult := pair.pred.evaluate(p.parser, outerContext) if ParserATNSimulatorDebug || ParserATNSimulatorDFADebug { fmt.Println("eval pred " + pair.String() + "=" + fmt.Sprint(predicateEvaluationResult)) @@ -974,12 +977,8 @@ func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, clo func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { if ParserATNSimulatorTraceATNSim { fmt.Println("closure(" + config.String() + ")") - //fmt.Println("configs(" + configs.String() + ")") - if config.GetReachesIntoOuterContext() > 50 { - panic("problem") - } } - + 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 @@ -1000,7 +999,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs } returnState := p.atn.states[config.GetContext().getReturnState(i)] newContext := config.GetContext().GetParent(i) // "pop" return state - + c := NewBaseATNConfig5(returnState, config.GetAlt(), newContext, config.GetSemanticContext()) // While we have context to pop back from, we may have // gotten that context AFTER having falling off a rule. @@ -1038,42 +1037,42 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, if i == 0 && p.canDropLoopEntryEdgeInLeftRecursiveRule(config) { continue } - + t := state.GetTransitions()[i] _, ok := t.(*ActionTransition) continueCollecting := collectPredicates && !ok c := p.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEOFAsEpsilon) if ci, ok := c.(*BaseATNConfig); ok && ci != nil { newDepth := depth - + if _, ok := config.GetState().(*RuleStopState); ok { // target fell off end of rule mark resulting c as having dipped into outer context // We can't get here if incoming config was rule stop and we had context // track how far we dip into outer context. Might // come in handy and we avoid evaluating context dependent - // preds if p is > 0. - + // preds if this is > 0. + if p.dfa != nil && p.dfa.getPrecedenceDfa() { if t.(*EpsilonTransition).outermostPrecedenceReturn == p.dfa.atnStartState.GetRuleIndex() { c.setPrecedenceFilterSuppressed(true) } } - + c.SetReachesIntoOuterContext(c.GetReachesIntoOuterContext() + 1) - + _, present := closureBusy.Put(c) if present { // avoid infinite recursion for right-recursive rules continue } - - configs.SetDipsIntoOuterContext(true) // TODO: can remove? only care when we add to set per middle of p method + + configs.SetDipsIntoOuterContext(true) // TODO: can remove? only care when we add to set per middle of this method newDepth-- if ParserATNSimulatorDebug { fmt.Println("dips into outer ctx: " + c.String()) } } else { - + if !t.getIsEpsilon() { _, present := closureBusy.Put(c) if present { @@ -1098,9 +1097,9 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC if TurnOffLRLoopEntryBranchOpt { return false } - + _p := config.GetState() - + // First check to see if we are in StarLoopEntryState generated during // left-recursion elimination. For efficiency, also check if // the context has an empty stack case. If so, it would mean @@ -1117,7 +1116,7 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC config.GetContext().hasEmptyPath() { return false } - + // Require all return states to return back to the same rule // that p is in. numCtxs := config.GetContext().length() @@ -1131,38 +1130,38 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC decisionStartState := x.(BlockStartState) blockEndStateNum := decisionStartState.getEndState().stateNumber blockEndState := p.atn.states[blockEndStateNum].(*BlockEndState) - + // Verify that the top of each stack context leads to loop entry/exit // state through epsilon edges and w/o leaving rule. - + for i := 0; i < numCtxs; i++ { // for each stack context returnStateNumber := config.GetContext().getReturnState(i) returnState := p.atn.states[returnStateNumber] - + // all states must have single outgoing epsilon edge if len(returnState.GetTransitions()) != 1 || !returnState.GetTransitions()[0].getIsEpsilon() { return false } - + // Look for prefix op case like 'not expr', (' type ')' expr returnStateTarget := returnState.GetTransitions()[0].getTarget() if returnState.GetStateType() == ATNStateBlockEnd && returnStateTarget == _p { continue } - + // Look for 'expr op expr' or case where expr's return state is block end // of (...)* internal block; the block end points to loop back // which points to p but we don't need to check that if returnState == blockEndState { continue } - + // Look for ternary expr ? expr : expr. The return state points at block end, // which points at loop entry state if returnStateTarget == blockEndState { continue } - + // Look for complex prefix 'between expr and expr' case where 2nd expr's // return state points at block end state of (...)* internal block if returnStateTarget.GetStateType() == ATNStateBlockEnd && @@ -1171,11 +1170,11 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC returnStateTarget.GetTransitions()[0].getTarget() == _p { continue } - + // anything else ain't conforming return false } - + return true } @@ -1185,7 +1184,7 @@ func (p *ParserATNSimulator) getRuleName(index int) string { } var sb strings.Builder sb.Grow(32) - + sb.WriteString("') @@ -1193,7 +1192,7 @@ func (p *ParserATNSimulator) getRuleName(index int) string { } func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, collectPredicates, inContext, fullCtx, treatEOFAsEpsilon bool) ATNConfig { - + switch t.getSerializationType() { case TransitionRULE: return p.ruleTransition(config, t.(*RuleTransition)) @@ -1230,7 +1229,7 @@ func (p *ParserATNSimulator) actionTransition(config ATNConfig, t *ActionTransit //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, pt *PrecedencePredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { - + if ParserATNSimulatorDebug { fmt.Println("PRED (collectPredicates=" + fmt.Sprint(collectPredicates) + ") " + strconv.Itoa(pt.precedence) + ">=_p, ctx dependent=true") @@ -1267,7 +1266,7 @@ func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { - + if ParserATNSimulatorDebug { fmt.Println("PRED (collectPredicates=" + fmt.Sprint(collectPredicates) + ") " + strconv.Itoa(pt.ruleIndex) + ":" + strconv.Itoa(pt.predIndex) + ", ctx dependent=" + fmt.Sprint(pt.isCtxDependent)) @@ -1381,15 +1380,15 @@ func (p *ParserATNSimulator) GetTokenName(t int) string { if t == TokenEOF { return "EOF" } - + if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetLiteralNames()) { return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">" } - + if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetSymbolicNames()) { return p.parser.GetSymbolicNames()[t] + "<" + strconv.Itoa(t) + ">" } - + return strconv.Itoa(t) } @@ -1404,7 +1403,7 @@ func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string { func (p *ParserATNSimulator) dumpDeadEndConfigs(_ *NoViableAltException) { panic("Not implemented") - + // fmt.Println("dead end configs: ") // var decs = nvae.deadEndConfigs // @@ -1486,13 +1485,13 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA } from.setIthEdge(t+1, to) // connect p.atn.edgeMu.Unlock() - + if ParserATNSimulatorDebug { var names []string if p.parser != nil { names = p.parser.GetLiteralNames() } - + fmt.Println("DFA=\n" + dfa.String(names, nil)) } return to @@ -1518,19 +1517,19 @@ func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState { } return existing } - + // The state was not present, so update it with configs // d.stateNumber = dfa.states.Len() if !d.configs.ReadOnly() { - d.configs.OptimizeConfigs(p.BaseATNSimulator) + d.configs.OptimizeConfigs(&p.BaseATNSimulator) d.configs.SetReadOnly(true) } dfa.states.Put(d) if ParserATNSimulatorTraceATNSim { fmt.Println("addDFAState new " + d.String()) } - + return d } diff --git a/runtime/Go/antlr/v4/prediction_context.go b/runtime/Go/antlr/v4/prediction_context.go index bed6d13675..1ed15bc06a 100644 --- a/runtime/Go/antlr/v4/prediction_context.go +++ b/runtime/Go/antlr/v4/prediction_context.go @@ -6,26 +6,9 @@ package antlr import ( "fmt" - "golang.org/x/exp/slices" - "strconv" -) - -const ( - // BasePredictionContextEmptyReturnState represents '$' in local context prediction, which means wildcard. - BasePredictionContextEmptyReturnState = 0x7FFFFFFF -) - -// Represents {@code $} in an array in full context mode, when {@code $} -// doesn't mean wildcard: {@code $ + x = [$,x]}. Here, -// {@code $} = {@link //EmptyReturnState}. -// / - -//goland:noinspection GoUnusedGlobalVariable -var ( - BasePredictionContextglobalNodeCount = 1 - BasePredictionContextid = BasePredictionContextglobalNodeCount ) +// PredictionContext defines the interface that must be implemented by any flavor of prediction context. type PredictionContext interface { Hash() int Equals(interface{}) bool @@ -35,22 +18,33 @@ type PredictionContext interface { isEmpty() bool hasEmptyPath() bool String() string + Type() int } -type BasePredictionContext struct { - cachedHash int -} - -func NewBasePredictionContext(cachedHash int) *BasePredictionContext { - pc := new(BasePredictionContext) - pc.cachedHash = cachedHash +const ( + // BasePredictionContextEmptyReturnState represents {@code $} in an array in full context mode, $ + // doesn't mean wildcard: + // + // $ + x = [$,x] + // + // Here, + // + // $ = EmptyReturnState + BasePredictionContextEmptyReturnState = 0x7FFFFFFF +) - return pc -} +// TODO: JI These are meant to be atomics - this does not seem to match the Java runtime here +//goland:noinspection GoUnusedGlobalVariable +var ( + BasePredictionContextglobalNodeCount = 1 + BasePredictionContextid = BasePredictionContextglobalNodeCount +) -func (b *BasePredictionContext) isEmpty() bool { - return false -} +const ( + PredictionContextEmpty = iota + PredictionContextSingleton + PredictionContextArray +) func calculateHash(parent PredictionContext, returnState int) int { h := murmurInit(1) @@ -59,301 +53,6 @@ func calculateHash(parent PredictionContext, returnState int) int { return murmurFinish(h, 2) } -var _emptyPredictionContextHash int - -func init() { - _emptyPredictionContextHash = murmurInit(1) - _emptyPredictionContextHash = murmurFinish(_emptyPredictionContextHash, 0) -} - -func calculateEmptyHash() int { - return _emptyPredictionContextHash -} - -// Used to cache {@link BasePredictionContext} objects. Its used for the shared -// context cash associated with contexts in DFA states. This cache -// can be used for both lexers and parsers. - -type PredictionContextCache struct { - cache map[PredictionContext]PredictionContext -} - -func NewPredictionContextCache() *PredictionContextCache { - t := new(PredictionContextCache) - t.cache = make(map[PredictionContext]PredictionContext) - return t -} - -// Add a context to the cache and return it. If the context already exists, -// return that one instead and do not add a new context to the cache. -// Protect shared cache from unsafe thread access. -func (p *PredictionContextCache) add(ctx PredictionContext) PredictionContext { - if ctx == BasePredictionContextEMPTY { - return BasePredictionContextEMPTY - } - existing := p.cache[ctx] - if existing != nil { - return existing - } - p.cache[ctx] = ctx - return ctx -} - -func (p *PredictionContextCache) Get(ctx PredictionContext) PredictionContext { - return p.cache[ctx] -} - -func (p *PredictionContextCache) length() int { - return len(p.cache) -} - -type SingletonPredictionContext interface { - PredictionContext -} - -type BaseSingletonPredictionContext struct { - *BasePredictionContext - - parentCtx PredictionContext - returnState int -} - -func NewBaseSingletonPredictionContext(parent PredictionContext, returnState int) *BaseSingletonPredictionContext { - var cachedHash int - if parent != nil { - cachedHash = calculateHash(parent, returnState) - } else { - cachedHash = calculateEmptyHash() - } - - s := new(BaseSingletonPredictionContext) - s.BasePredictionContext = NewBasePredictionContext(cachedHash) - - s.parentCtx = parent - s.returnState = returnState - - return s -} - -func SingletonBasePredictionContextCreate(parent PredictionContext, returnState int) PredictionContext { - if returnState == BasePredictionContextEmptyReturnState && parent == nil { - // someone can pass in the bits of an array ctx that mean $ - return BasePredictionContextEMPTY - } - - return NewBaseSingletonPredictionContext(parent, returnState) -} - -func (b *BaseSingletonPredictionContext) length() int { - return 1 -} - -func (b *BaseSingletonPredictionContext) GetParent(_ int) PredictionContext { - return b.parentCtx -} - -func (b *BaseSingletonPredictionContext) getReturnState(_ int) int { - return b.returnState -} - -func (b *BaseSingletonPredictionContext) hasEmptyPath() bool { - return b.returnState == BasePredictionContextEmptyReturnState -} - -func (b *BaseSingletonPredictionContext) Hash() int { - return b.cachedHash -} - -func (b *BaseSingletonPredictionContext) Equals(other interface{}) bool { - if b == other { - return true - } - if _, ok := other.(*BaseSingletonPredictionContext); !ok { - return false - } - - otherP := other.(*BaseSingletonPredictionContext) - - if b.returnState != otherP.getReturnState(0) { - return false - } - if b.parentCtx == nil { - return otherP.parentCtx == nil - } - - return b.parentCtx.Equals(otherP.parentCtx) -} - -func (b *BaseSingletonPredictionContext) String() string { - var up string - - if b.parentCtx == nil { - up = "" - } else { - up = b.parentCtx.String() - } - - if len(up) == 0 { - if b.returnState == BasePredictionContextEmptyReturnState { - return "$" - } - - return strconv.Itoa(b.returnState) - } - - return strconv.Itoa(b.returnState) + " " + up -} - -var BasePredictionContextEMPTY = NewEmptyPredictionContext() - -type EmptyPredictionContext struct { - *BaseSingletonPredictionContext -} - -func NewEmptyPredictionContext() *EmptyPredictionContext { - - p := new(EmptyPredictionContext) - - p.BaseSingletonPredictionContext = NewBaseSingletonPredictionContext(nil, BasePredictionContextEmptyReturnState) - p.cachedHash = calculateEmptyHash() - return p -} - -func (e *EmptyPredictionContext) isEmpty() bool { - return true -} - -func (e *EmptyPredictionContext) GetParent(_ int) PredictionContext { - return nil -} - -func (e *EmptyPredictionContext) getReturnState(_ int) int { - return e.returnState -} - -func (e *EmptyPredictionContext) Hash() int { - return e.cachedHash -} - -func (e *EmptyPredictionContext) Equals(other interface{}) bool { - return e == other -} - -func (e *EmptyPredictionContext) String() string { - return "$" -} - -type ArrayPredictionContext struct { - *BasePredictionContext - - parents []PredictionContext - returnStates []int -} - -func NewArrayPredictionContext(parents []PredictionContext, returnStates []int) *ArrayPredictionContext { - // Parent can be nil only if full ctx mode and we make an array - // from {@link //EMPTY} and non-empty. We merge {@link //EMPTY} by using - // nil parent and - // returnState == {@link //EmptyReturnState}. - hash := murmurInit(1) - - for _, parent := range parents { - hash = murmurUpdate(hash, parent.Hash()) - } - - for _, returnState := range returnStates { - hash = murmurUpdate(hash, returnState) - } - - hash = murmurFinish(hash, len(parents)<<1) - - c := new(ArrayPredictionContext) - c.BasePredictionContext = NewBasePredictionContext(hash) - - c.parents = parents - c.returnStates = returnStates - - return c -} - -func (a *ArrayPredictionContext) GetReturnStates() []int { - return a.returnStates -} - -func (a *ArrayPredictionContext) hasEmptyPath() bool { - return a.getReturnState(a.length()-1) == BasePredictionContextEmptyReturnState -} - -func (a *ArrayPredictionContext) isEmpty() bool { - // since EmptyReturnState can only appear in the last position, we - // don't need to verify that size==1 - return a.returnStates[0] == BasePredictionContextEmptyReturnState -} - -func (a *ArrayPredictionContext) length() int { - return len(a.returnStates) -} - -func (a *ArrayPredictionContext) GetParent(index int) PredictionContext { - return a.parents[index] -} - -func (a *ArrayPredictionContext) getReturnState(index int) int { - return a.returnStates[index] -} - -// Equals is the default comparison function for ArrayPredictionContext when no specialized -// implementation is needed for a collection -func (a *ArrayPredictionContext) Equals(o interface{}) bool { - if a == o { - return true - } - other, ok := o.(*ArrayPredictionContext) - if !ok { - return false - } - if a.cachedHash != other.Hash() { - return false // can't be same if hash is different - } - - // Must compare the actual array elements and not just the array address - // - return slices.Equal(a.returnStates, other.returnStates) && - slices.EqualFunc(a.parents, other.parents, func(x, y PredictionContext) bool { - return x.Equals(y) - }) -} - -// Hash is the default hash function for ArrayPredictionContext when no specialized -// implementation is needed for a collection -func (a *ArrayPredictionContext) Hash() int { - return a.BasePredictionContext.cachedHash -} - -func (a *ArrayPredictionContext) String() string { - if a.isEmpty() { - return "[]" - } - - s := "[" - for i := 0; i < len(a.returnStates); i++ { - if i > 0 { - s = s + ", " - } - if a.returnStates[i] == BasePredictionContextEmptyReturnState { - s = s + "$" - continue - } - s = s + strconv.Itoa(a.returnStates[i]) - if a.parents[i] != nil { - s = s + " " + a.parents[i].String() - } else { - s = s + "nil" - } - } - - return s + "]" -} // Convert a {@link RuleContext} tree to a {@link BasePredictionContext} graph. // Return {@link //EMPTY} if {@code outerContext} is empty or nil. @@ -371,65 +70,59 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) Predicti parent := predictionContextFromRuleContext(a, outerContext.GetParent().(RuleContext)) state := a.states[outerContext.GetInvokingState()] transition := state.GetTransitions()[0] - + return SingletonBasePredictionContextCreate(parent, transition.(*RuleTransition).followState.GetStateNumber()) } func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { - + // Share same graph if both same // if a == b || a.Equals(b) { return a } - + // In Java, EmptyPredictionContext inherits from SingletonPredictionContext, and so the test // in java for SingletonPredictionContext will succeed and a new ArrayPredictionContext will be created // from it. // In go, EmptyPredictionContext does not equate to SingletonPredictionContext and so that conversion // will fail. We need to test for both Empty and Singleton and create an ArrayPredictionContext from // either of them. - ac, ok1 := a.(*BaseSingletonPredictionContext) bc, ok2 := b.(*BaseSingletonPredictionContext) - + if ok1 && ok2 { return mergeSingletons(ac, bc, rootIsWildcard, mergeCache) } // At least one of a or b is array - // If one is $ and rootIsWildcard, return $ as// wildcard + // If one is $ and rootIsWildcard, return $ as wildcard if rootIsWildcard { - if _, ok := a.(*EmptyPredictionContext); ok { + if a.isEmpty() { return a } - if _, ok := b.(*EmptyPredictionContext); ok { + if b.isEmpty() { return b } } + + // Convert either Singleton or Empty to arrays, so that we can merge them + var ara, arb *ArrayPredictionContext + + ara = convertToArray(a) + arb = convertToArray(b) + return mergeArrays(ara, arb, rootIsWildcard, mergeCache) +} - // Convert Singleton or Empty so both are arrays to normalize - We should not use the existing parameters - // here. - // - // TODO: I think that maybe the Prediction Context structs should be redone as there is a chance we will see this mess again - maybe redo the logic here - - var arp, arb *ArrayPredictionContext - var ok bool - if arp, ok = a.(*ArrayPredictionContext); ok { - } else if _, ok = a.(*BaseSingletonPredictionContext); ok { - arp = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)}) - } else if _, ok = a.(*EmptyPredictionContext); ok { - arp = NewArrayPredictionContext([]PredictionContext{}, []int{}) - } - - if arb, ok = b.(*ArrayPredictionContext); ok { - } else if _, ok = b.(*BaseSingletonPredictionContext); ok { - arb = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)}) - } else if _, ok = b.(*EmptyPredictionContext); ok { - arb = NewArrayPredictionContext([]PredictionContext{}, []int{}) +func convertToArray(pc PredictionContext) *ArrayPredictionContext { + switch pc.Type() { + case PredictionContextEmpty: + return NewArrayPredictionContext([]PredictionContext{}, []int{}) + case PredictionContextSingleton: + return NewArrayPredictionContext([]PredictionContext{pc.GetParent(0)}, []int{pc.getReturnState(0)}) + default: + // Already an array } - - // Both arp and arb - return mergeArrays(arp, arb, rootIsWildcard, mergeCache) + return pc.(*ArrayPredictionContext) } // mergeSingletons merges two [SingletonBasePredictionContext] instances. @@ -473,7 +166,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, return previous.(PredictionContext) } } - + rootMerge := mergeRoot(a, b, rootIsWildcard) if rootMerge != nil { if mergeCache != nil { @@ -579,20 +272,20 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, // / func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionContext { if rootIsWildcard { - if a == BasePredictionContextEMPTY { + if a.isEmpty() { return BasePredictionContextEMPTY // // + b =// } - if b == BasePredictionContextEMPTY { + if b.isEmpty() { return BasePredictionContextEMPTY // a +// =// } } else { - if a == BasePredictionContextEMPTY && b == BasePredictionContextEMPTY { + if a.isEmpty() && b.isEmpty() { return BasePredictionContextEMPTY // $ + $ = $ - } else if a == BasePredictionContextEMPTY { // $ + x = [$,x] + } else if a.isEmpty() { // $ + x = [$,x] payloads := []int{b.getReturnState(-1), BasePredictionContextEmptyReturnState} parents := []PredictionContext{b.GetParent(-1), nil} return NewArrayPredictionContext(parents, payloads) - } else if b == BasePredictionContextEMPTY { // x + $ = [$,x] ($ is always first if present) + } else if b.isEmpty() { // x + $ = [$,x] ($ is always first if present) payloads := []int{a.getReturnState(-1), BasePredictionContextEmptyReturnState} parents := []PredictionContext{a.GetParent(-1), nil} return NewArrayPredictionContext(parents, payloads) @@ -642,7 +335,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * i := 0 // walks a j := 0 // walks b k := 0 // walks target M array - + mergedReturnStates := make([]int, len(a.returnStates)+len(b.returnStates)) mergedParents := make([]PredictionContext, len(a.returnStates)+len(b.returnStates)) // walk and merge to yield mergedParents, mergedReturnStates @@ -704,12 +397,12 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * mergedParents = mergedParents[0:k] mergedReturnStates = mergedReturnStates[0:k] } - + M := NewArrayPredictionContext(mergedParents, mergedReturnStates) - + // if we created same array as a or b, return that instead // TODO: JI track whether this is possible above during merge sort for speed - // TODO: JI In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems + // TODO: JI VERY IMPORTANT - In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems if M == a { if mergeCache != nil { mergeCache.set(a.Hash(), b.Hash(), a) @@ -719,7 +412,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * } return a } - if M == b { + if M.Equals(b) { if mergeCache != nil { mergeCache.set(a.Hash(), b.Hash(), b) } @@ -729,7 +422,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * return b } combineCommonParents(mergedParents) - + if mergeCache != nil { mergeCache.set(a.Hash(), b.Hash(), M) } @@ -744,7 +437,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * // / func combineCommonParents(parents []PredictionContext) { uniqueParents := make(map[PredictionContext]PredictionContext) - + for p := 0; p < len(parents); p++ { parent := parents[p] if uniqueParents[parent] == nil { @@ -757,7 +450,7 @@ func combineCommonParents(parents []PredictionContext) { } func getCachedBasePredictionContext(context PredictionContext, contextCache *PredictionContextCache, visited map[PredictionContext]PredictionContext) PredictionContext { - + if context.isEmpty() { return context } @@ -801,6 +494,6 @@ func getCachedBasePredictionContext(context PredictionContext, contextCache *Pre contextCache.add(updated) visited[updated] = updated visited[context] = updated - + return updated } diff --git a/runtime/Go/antlr/v4/prediction_context_cache.go b/runtime/Go/antlr/v4/prediction_context_cache.go new file mode 100644 index 0000000000..30c9556509 --- /dev/null +++ b/runtime/Go/antlr/v4/prediction_context_cache.go @@ -0,0 +1,39 @@ +package antlr + +var BasePredictionContextEMPTY = NewEmptyPredictionContext() + +// PredictionContextCache is Used to cache [PredictionContext] objects. It is used for the shared +// context cash associated with contexts in DFA states. This cache +// can be used for both lexers and parsers. +type PredictionContextCache struct { + cache map[PredictionContext]PredictionContext +} + +func NewPredictionContextCache() *PredictionContextCache { + t := new(PredictionContextCache) + t.cache = make(map[PredictionContext]PredictionContext) + return t +} + +// Add a context to the cache and return it. If the context already exists, +// return that one instead and do not add a new context to the cache. +// Protect shared cache from unsafe thread access. +func (p *PredictionContextCache) add(ctx PredictionContext) PredictionContext { + if ctx.isEmpty() { + return BasePredictionContextEMPTY + } + existing := p.cache[ctx] + if existing != nil { + return existing + } + p.cache[ctx] = ctx + return ctx +} + +func (p *PredictionContextCache) Get(ctx PredictionContext) PredictionContext { + return p.cache[ctx] +} + +func (p *PredictionContextCache) length() int { + return len(p.cache) +} diff --git a/runtime/Go/antlr/v4/singleton_prediction_context.go b/runtime/Go/antlr/v4/singleton_prediction_context.go new file mode 100644 index 0000000000..49206cb542 --- /dev/null +++ b/runtime/Go/antlr/v4/singleton_prediction_context.go @@ -0,0 +1,104 @@ +package antlr + +import "strconv" + +type SingletonPredictionContext interface { + PredictionContext +} + +type BaseSingletonPredictionContext struct { + BasePredictionContext + parentCtx PredictionContext + returnState int +} + +func NewBaseSingletonPredictionContext(parent PredictionContext, returnState int) PredictionContext { + var cachedHash int + if parent != nil { + cachedHash = calculateHash(parent, returnState) + } else { + cachedHash = calculateEmptyHash() + } + return &BaseSingletonPredictionContext{ + BasePredictionContext: BasePredictionContext{ + cachedHash: cachedHash, + pcType: PredictionContextSingleton, + }, + parentCtx: parent, + returnState: returnState, + } +} + +func SingletonBasePredictionContextCreate(parent PredictionContext, returnState int) PredictionContext { + if returnState == BasePredictionContextEmptyReturnState && parent == nil { + // someone can pass in the bits of an array ctx that mean $ + return BasePredictionContextEMPTY + } + return NewBaseSingletonPredictionContext(parent, returnState) +} + +func (b *BaseSingletonPredictionContext) length() int { + return 1 +} + +func (b *BaseSingletonPredictionContext) GetParent(_ int) PredictionContext { + return b.parentCtx +} + +func (b *BaseSingletonPredictionContext) getReturnState(_ int) int { + return b.returnState +} + +func (b *BaseSingletonPredictionContext) hasEmptyPath() bool { + return b.returnState == BasePredictionContextEmptyReturnState +} + +func (b *BaseSingletonPredictionContext) Hash() int { + return b.cachedHash +} + +func (b *BaseSingletonPredictionContext) Equals(other interface{}) bool { + if b == other { + return true + } + if _, ok := other.(*BaseSingletonPredictionContext); !ok { + return false + } + + otherP := other.(*BaseSingletonPredictionContext) + + if b.cachedHash != otherP.Hash() { + return false // Can't be same if hash is different + } + + if b.returnState != otherP.getReturnState(0) { + return false + } + + // Both parents must be nil if one is + if b.parentCtx == nil { + return otherP.parentCtx == nil + } + + return b.parentCtx.Equals(otherP.parentCtx) +} + +func (b *BaseSingletonPredictionContext) String() string { + var up string + + if b.parentCtx == nil { + up = "" + } else { + up = b.parentCtx.String() + } + + if len(up) == 0 { + if b.returnState == BasePredictionContextEmptyReturnState { + return "$" + } + + return strconv.Itoa(b.returnState) + } + + return strconv.Itoa(b.returnState) + " " + up +} diff --git a/runtime/Go/antlr/v4/token.go b/runtime/Go/antlr/v4/token.go index fcb8e66d8c..78c2c396cd 100644 --- a/runtime/Go/antlr/v4/token.go +++ b/runtime/Go/antlr/v4/token.go @@ -26,16 +26,16 @@ type Token interface { GetStop() int GetLine() int GetColumn() int - + GetText() string SetText(s string) - + GetTokenIndex() int SetTokenIndex(v int) - + GetTokenSource() TokenSource GetInputStream() CharStream - + String() string } @@ -55,15 +55,15 @@ type BaseToken struct { const ( TokenInvalidType = 0 - // TokenEpsilon - during lookahead operations, this "token" signifies we hit the rule end [ATN] state + // TokenEpsilon - during lookahead operations, this "token" signifies we hit the rule end [ATN] state // and did not follow it despite needing to. TokenEpsilon = -2 - + TokenMinUserTokenType = 1 TokenEOF = -1 - // TokenDefaultChannel is the default channel upon which tokens are sent to the parser. + // TokenDefaultChannel is the default channel upon which tokens are sent to the parser. // // All tokens go to the parser (unless [Skip] is called in the lexer rule) // on a particular "channel". The parser tunes to a particular channel @@ -121,21 +121,22 @@ func (b *BaseToken) GetInputStream() CharStream { } type CommonToken struct { - *BaseToken + BaseToken } func NewCommonToken(source *TokenSourceCharStreamPair, tokenType, channel, start, stop int) *CommonToken { - - t := new(CommonToken) - - t.BaseToken = new(BaseToken) - - t.source = source - t.tokenType = tokenType - t.channel = channel - t.start = start - t.stop = stop - t.tokenIndex = -1 + + t := &CommonToken{ + BaseToken: BaseToken{ + source: source, + tokenType: tokenType, + channel: channel, + start: start, + stop: stop, + tokenIndex: -1, + }, + } + if t.source.tokenSource != nil { t.line = source.tokenSource.GetLine() t.column = source.tokenSource.GetCharPositionInLine() @@ -198,14 +199,14 @@ func (c *CommonToken) String() string { } else { txt = "" } - + var ch string if c.channel > 0 { ch = ",channel=" + strconv.Itoa(c.channel) } else { ch = "" } - + return "[@" + strconv.Itoa(c.tokenIndex) + "," + strconv.Itoa(c.start) + ":" + strconv.Itoa(c.stop) + "='" + txt + "',<" + strconv.Itoa(c.tokenType) + ">" + ch + "," + strconv.Itoa(c.line) + ":" + strconv.Itoa(c.column) + "]" diff --git a/runtime/Go/antlr/v4/tokenstream_rewriter.go b/runtime/Go/antlr/v4/tokenstream_rewriter.go index 980717050e..4c60056d08 100644 --- a/runtime/Go/antlr/v4/tokenstream_rewriter.go +++ b/runtime/Go/antlr/v4/tokenstream_rewriter.go @@ -174,7 +174,7 @@ func (op *BaseRewriteOperation) String() string { op.tokens.Get(op.GetIndex()), op.text, ) - + } type InsertBeforeOp struct { @@ -579,7 +579,6 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit rewrites[prevop.instructionIndex] = nil rop.index = min(prevop.index, rop.index) rop.LastIndex = max(prevop.LastIndex, rop.LastIndex) - println("new rop" + rop.String()) //TODO: remove console write, taken from Java version } else if !disjoint { panic("replace op boundaries of " + rop.String() + " overlap with previous " + prevop.String()) } diff --git a/runtime/Go/antlr/v4/transition.go b/runtime/Go/antlr/v4/transition.go index aad094cd15..62976688a6 100644 --- a/runtime/Go/antlr/v4/transition.go +++ b/runtime/Go/antlr/v4/transition.go @@ -131,18 +131,20 @@ var TransitionserializationNames = []string{ // AtomTransition // TODO: make all transitions sets? no, should remove set edges type AtomTransition struct { - *BaseTransition + BaseTransition } func NewAtomTransition(target ATNState, intervalSet int) *AtomTransition { - - t := new(AtomTransition) - t.BaseTransition = NewBaseTransition(target) - - t.label = intervalSet // The token type or character value or, signifies special intervalSet. + t := &AtomTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionATOM, + label: intervalSet, + isEpsilon: false, + }, + } t.intervalSet = t.makeLabel() - t.serializationType = TransitionATOM - + return t } @@ -161,24 +163,22 @@ func (t *AtomTransition) String() string { } type RuleTransition struct { - *BaseTransition - + BaseTransition followState ATNState ruleIndex, precedence int } func NewRuleTransition(ruleStart ATNState, ruleIndex, precedence int, followState ATNState) *RuleTransition { - - t := new(RuleTransition) - t.BaseTransition = NewBaseTransition(ruleStart) - - t.ruleIndex = ruleIndex - t.precedence = precedence - t.followState = followState - t.serializationType = TransitionRULE - t.isEpsilon = true - - return t + return &RuleTransition{ + BaseTransition: BaseTransition{ + target: ruleStart, + isEpsilon: true, + serializationType: TransitionRULE, + }, + ruleIndex: ruleIndex, + precedence: precedence, + followState: followState, + } } func (t *RuleTransition) Matches(_, _, _ int) bool { @@ -186,20 +186,19 @@ func (t *RuleTransition) Matches(_, _, _ int) bool { } type EpsilonTransition struct { - *BaseTransition - + BaseTransition outermostPrecedenceReturn int } func NewEpsilonTransition(target ATNState, outermostPrecedenceReturn int) *EpsilonTransition { - - t := new(EpsilonTransition) - t.BaseTransition = NewBaseTransition(target) - - t.serializationType = TransitionEPSILON - t.isEpsilon = true - t.outermostPrecedenceReturn = outermostPrecedenceReturn - return t + return &EpsilonTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionEPSILON, + isEpsilon: true, + }, + outermostPrecedenceReturn: outermostPrecedenceReturn, + } } func (t *EpsilonTransition) Matches(_, _, _ int) bool { @@ -211,19 +210,20 @@ func (t *EpsilonTransition) String() string { } type RangeTransition struct { - *BaseTransition - + BaseTransition start, stop int } func NewRangeTransition(target ATNState, start, stop int) *RangeTransition { - - t := new(RangeTransition) - t.BaseTransition = NewBaseTransition(target) - - t.serializationType = TransitionRANGE - t.start = start - t.stop = stop + t := &RangeTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionRANGE, + isEpsilon: false, + }, + start: start, + stop: stop, + } t.intervalSet = t.makeLabel() return t } @@ -254,37 +254,38 @@ type AbstractPredicateTransition interface { } type BaseAbstractPredicateTransition struct { - *BaseTransition + BaseTransition } func NewBasePredicateTransition(target ATNState) *BaseAbstractPredicateTransition { - - t := new(BaseAbstractPredicateTransition) - t.BaseTransition = NewBaseTransition(target) - - return t + return &BaseAbstractPredicateTransition{ + BaseTransition: BaseTransition{ + target: target, + }, + } } func (a *BaseAbstractPredicateTransition) IAbstractPredicateTransitionFoo() {} type PredicateTransition struct { - *BaseAbstractPredicateTransition - + BaseAbstractPredicateTransition isCtxDependent bool ruleIndex, predIndex int } func NewPredicateTransition(target ATNState, ruleIndex, predIndex int, isCtxDependent bool) *PredicateTransition { - - t := new(PredicateTransition) - t.BaseAbstractPredicateTransition = NewBasePredicateTransition(target) - - t.serializationType = TransitionPREDICATE - t.ruleIndex = ruleIndex - t.predIndex = predIndex - t.isCtxDependent = isCtxDependent // e.g., $i ref in pred - t.isEpsilon = true - return t + return &PredicateTransition{ + BaseAbstractPredicateTransition: BaseAbstractPredicateTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionPREDICATE, + isEpsilon: true, + }, + }, + isCtxDependent: isCtxDependent, + ruleIndex: ruleIndex, + predIndex: predIndex, + } } func (t *PredicateTransition) Matches(_, _, _ int) bool { @@ -300,23 +301,22 @@ func (t *PredicateTransition) String() string { } type ActionTransition struct { - *BaseTransition - + BaseTransition isCtxDependent bool ruleIndex, actionIndex, predIndex int } func NewActionTransition(target ATNState, ruleIndex, actionIndex int, isCtxDependent bool) *ActionTransition { - - t := new(ActionTransition) - t.BaseTransition = NewBaseTransition(target) - - t.serializationType = TransitionACTION - t.ruleIndex = ruleIndex - t.actionIndex = actionIndex - t.isCtxDependent = isCtxDependent // e.g., $i ref in pred - t.isEpsilon = true - return t + return &ActionTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionACTION, + isEpsilon: true, + }, + isCtxDependent: isCtxDependent, + ruleIndex: ruleIndex, + actionIndex: actionIndex, + } } func (t *ActionTransition) Matches(_, _, _ int) bool { @@ -328,22 +328,23 @@ func (t *ActionTransition) String() string { } type SetTransition struct { - *BaseTransition + BaseTransition } func NewSetTransition(target ATNState, set *IntervalSet) *SetTransition { - - t := new(SetTransition) - t.BaseTransition = NewBaseTransition(target) - - t.serializationType = TransitionSET - if set != nil { + t := &SetTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionSET, + }, + } + + if set != nil { t.intervalSet = set } else { t.intervalSet = NewIntervalSet() t.intervalSet.addOne(TokenInvalidType) } - return t } @@ -356,16 +357,24 @@ func (t *SetTransition) String() string { } type NotSetTransition struct { - *SetTransition + SetTransition } func NewNotSetTransition(target ATNState, set *IntervalSet) *NotSetTransition { - - t := new(NotSetTransition) - - t.SetTransition = NewSetTransition(target, set) - - t.serializationType = TransitionNOTSET + t := &NotSetTransition{ + SetTransition: SetTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionNOTSET, + }, + }, + } + if set != nil { + t.intervalSet = set + } else { + t.intervalSet = NewIntervalSet() + t.intervalSet.addOne(TokenInvalidType) + } return t } @@ -379,16 +388,16 @@ func (t *NotSetTransition) String() string { } type WildcardTransition struct { - *BaseTransition + BaseTransition } func NewWildcardTransition(target ATNState) *WildcardTransition { - - t := new(WildcardTransition) - t.BaseTransition = NewBaseTransition(target) - - t.serializationType = TransitionWILDCARD - return t + return &WildcardTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionWILDCARD, + }, + } } func (t *WildcardTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { @@ -400,21 +409,21 @@ func (t *WildcardTransition) String() string { } type PrecedencePredicateTransition struct { - *BaseAbstractPredicateTransition - + BaseAbstractPredicateTransition precedence int } func NewPrecedencePredicateTransition(target ATNState, precedence int) *PrecedencePredicateTransition { - - t := new(PrecedencePredicateTransition) - t.BaseAbstractPredicateTransition = NewBasePredicateTransition(target) - - t.serializationType = TransitionPRECEDENCE - t.precedence = precedence - t.isEpsilon = true - - return t + return &PrecedencePredicateTransition{ + BaseAbstractPredicateTransition: BaseAbstractPredicateTransition{ + BaseTransition: BaseTransition{ + target: target, + serializationType: TransitionPRECEDENCE, + isEpsilon: true, + }, + }, + precedence: precedence, + } } func (t *PrecedencePredicateTransition) Matches(_, _, _ int) bool { diff --git a/runtime/Go/antlr/v4/tree.go b/runtime/Go/antlr/v4/tree.go index 26efc993e9..b9abb89d3c 100644 --- a/runtime/Go/antlr/v4/tree.go +++ b/runtime/Go/antlr/v4/tree.go @@ -21,35 +21,35 @@ type Tree interface { type SyntaxTree interface { Tree - + GetSourceInterval() *Interval } type ParseTree interface { SyntaxTree - + Accept(Visitor ParseTreeVisitor) interface{} GetText() string - + ToStringTree([]string, Recognizer) string } type RuleNode interface { ParseTree - + GetRuleContext() RuleContext GetBaseRuleContext() *BaseRuleContext } type TerminalNode interface { ParseTree - + GetSymbol() Token } type ErrorNode interface { TerminalNode - + errorNode() } @@ -69,7 +69,7 @@ func (v *BaseParseTreeVisitor) VisitChildren(_ RuleNode) interface{} { retur func (v *BaseParseTreeVisitor) VisitTerminal(_ TerminalNode) interface{} { return nil } func (v *BaseParseTreeVisitor) VisitErrorNode(_ ErrorNode) interface{} { return nil } -// TODO +// TODO: Implement this? //func (this ParseTreeVisitor) Visit(ctx) { // if (Utils.isArray(ctx)) { // self := this @@ -108,7 +108,7 @@ func (l *BaseParseTreeListener) ExitEveryRule(_ ParserRuleContext) {} type TerminalNodeImpl struct { parentCtx RuleContext - + symbol Token } @@ -116,10 +116,10 @@ var _ TerminalNode = &TerminalNodeImpl{} func NewTerminalNodeImpl(symbol Token) *TerminalNodeImpl { tn := new(TerminalNodeImpl) - + tn.parentCtx = nil tn.symbol = symbol - + return tn } @@ -175,7 +175,7 @@ func (t *TerminalNodeImpl) String() string { if t.symbol.GetTokenType() == TokenEOF { return "" } - + return t.symbol.GetText() } @@ -266,7 +266,7 @@ func (i *IterativeParseTreeWalker) Walk(listener ParseTreeListener, t Tree) { var indexStack []int currentNode := t currentIndex := 0 - + for currentNode != nil { // pre-order visit switch tt := currentNode.(type) { @@ -285,7 +285,7 @@ func (i *IterativeParseTreeWalker) Walk(listener ParseTreeListener, t Tree) { currentNode = currentNode.GetChild(0) continue } - + for { // post-order visit if ruleNode, ok := currentNode.(RuleNode); ok {