diff --git a/runtime/Go/antlr/v4/atn_config.go b/runtime/Go/antlr/v4/atn_config.go index e09b761a57..84b94e3989 100644 --- a/runtime/Go/antlr/v4/atn_config.go +++ b/runtime/Go/antlr/v4/atn_config.go @@ -8,164 +8,146 @@ import ( "fmt" ) +const ( + lexerConfig = iota // Indicates that this ATNConfig is for a lexer + parserConfig // Indicates that this ATNConfig is for a parser +) + // ATNConfig is a tuple: (ATN state, predicted alt, syntactic, semantic // context). The syntactic context is a graph-structured stack node whose // path(s) to the root is the rule invocation(s) chain used to arrive in the // state. The semantic context is the tree of semantic predicates encountered // before reaching an ATN state. -type ATNConfig interface { - - // Equals compares this ATNConfig to another for equality - Equals(o Collectable[ATNConfig]) bool - - // Hash returns the hash code for this ATNConfig for use in maps and comparisons - Hash() int - - // GetState returns the ATN state associated with this configuration - GetState() ATNState - // GetAlt returns the alternative associated with this configuration - GetAlt() int - // GetSemanticContext returns the semantic context associated with this configuration - GetSemanticContext() SemanticContext - - // GetContext returns the rule invocation stack associated with this configuration - GetContext() *PredictionContext - // SetContext sets the rule invocation stack associated with this configuration - SetContext(*PredictionContext) - - // GetReachesIntoOuterContext returns the count of references to an outer context from this configuration - GetReachesIntoOuterContext() int - // SetReachesIntoOuterContext sets the count of references to an outer context from this configuration - SetReachesIntoOuterContext(int) - - // String returns a string representation of the configuration - String() string - - getPrecedenceFilterSuppressed() bool - setPrecedenceFilterSuppressed(bool) -} - -// BaseATNConfig is a base implementation of ATNConfig. Thi si s done to emulate Java's ability to have multiple -// constructors for a single class. This is not idiomatic Go, but it works for now. -// TODO: this isn't the way to do this I think, but it will take time to rework - JI Also, getters and setters are not Go. Might be better to just access the fields, though the compiler will probably eliminate the calls -type BaseATNConfig struct { - precedenceFilterSuppressed bool - state ATNState - alt int - context *PredictionContext - semanticContext SemanticContext - reachesIntoOuterContext int +// +type ATNConfig struct { + precedenceFilterSuppressed bool + state ATNState + alt int + context *PredictionContext + semanticContext SemanticContext + reachesIntoOuterContext int + cType int // lexerConfig or parserConfig + lexerActionExecutor *LexerActionExecutor + passedThroughNonGreedyDecision bool } //goland:noinspection GoUnusedExportedFunction -func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup - maybe delete this - return &BaseATNConfig{ +func NewATNConfig7(old *ATNConfig) *ATNConfig { // TODO: Dup - maybe delete this + return &ATNConfig{ state: old.state, alt: old.alt, context: old.context, semanticContext: old.semanticContext, reachesIntoOuterContext: old.reachesIntoOuterContext, + cType: old.cType, } } -// NewBaseATNConfig6 creates a new BaseATNConfig instance given a state, alt and context only -func NewBaseATNConfig6(state ATNState, alt int, context *PredictionContext) *BaseATNConfig { - return NewBaseATNConfig5(state, alt, context, SemanticContextNone) +// NewATNConfig6 creates a new ATNConfig instance given a state, alt and context only +func NewATNConfig6(state ATNState, alt int, context *PredictionContext) *ATNConfig { + return NewATNConfig5(state, alt, context, SemanticContextNone) } -// NewBaseATNConfig5 creates a new BaseATNConfig instance given a state, alt, context and semantic context -func NewBaseATNConfig5(state ATNState, alt int, context *PredictionContext, semanticContext SemanticContext) *BaseATNConfig { +// NewATNConfig5 creates a new ATNConfig instance given a state, alt, context and semantic context +func NewATNConfig5(state ATNState, alt int, context *PredictionContext, semanticContext SemanticContext) *ATNConfig { if semanticContext == nil { panic("semanticContext cannot be nil") // TODO: Necessary? } - return &BaseATNConfig{state: state, alt: alt, context: context, semanticContext: semanticContext} + return &ATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: semanticContext, + cType: parserConfig, + } } -// NewBaseATNConfig4 creates a new BaseATNConfig instance given an existing config, and a state only -func NewBaseATNConfig4(c ATNConfig, state ATNState) *BaseATNConfig { - return NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()) +// NewATNConfig4 creates a new ATNConfig instance given an existing config, and a state only +func NewATNConfig4(c *ATNConfig, state ATNState) *ATNConfig { + return NewATNConfig(c, state, c.GetContext(), c.GetSemanticContext()) } -// NewBaseATNConfig3 creates a new BaseATNConfig instance given an existing config, a state and a semantic context -func NewBaseATNConfig3(c ATNConfig, state ATNState, semanticContext SemanticContext) *BaseATNConfig { - return NewBaseATNConfig(c, state, c.GetContext(), semanticContext) +// NewATNConfig3 creates a new ATNConfig instance given an existing config, a state and a semantic context +func NewATNConfig3(c *ATNConfig, state ATNState, semanticContext SemanticContext) *ATNConfig { + return NewATNConfig(c, state, c.GetContext(), semanticContext) } -// NewBaseATNConfig2 creates a new BaseATNConfig instance given an existing config, and a context only -func NewBaseATNConfig2(c ATNConfig, semanticContext SemanticContext) *BaseATNConfig { - return NewBaseATNConfig(c, c.GetState(), c.GetContext(), semanticContext) +// NewATNConfig2 creates a new ATNConfig instance given an existing config, and a context only +func NewATNConfig2(c *ATNConfig, semanticContext SemanticContext) *ATNConfig { + return NewATNConfig(c, c.GetState(), c.GetContext(), semanticContext) } -// NewBaseATNConfig1 creates a new BaseATNConfig instance given an existing config, a state, and a context only -func NewBaseATNConfig1(c ATNConfig, state ATNState, context *PredictionContext) *BaseATNConfig { - return NewBaseATNConfig(c, state, context, c.GetSemanticContext()) +// NewATNConfig1 creates a new ATNConfig instance given an existing config, a state, and a context only +func NewATNConfig1(c *ATNConfig, state ATNState, context *PredictionContext) *ATNConfig { + return NewATNConfig(c, state, context, c.GetSemanticContext()) } -// NewBaseATNConfig creates a new BaseATNConfig instance given an existing config, a state, a context and a semantic context, other 'constructors' +// NewATNConfig creates a new ATNConfig instance given an existing config, a state, a context and a semantic context, other 'constructors' // are just wrappers around this one. -func NewBaseATNConfig(c ATNConfig, state ATNState, context *PredictionContext, semanticContext SemanticContext) *BaseATNConfig { +func NewATNConfig(c *ATNConfig, state ATNState, context *PredictionContext, semanticContext SemanticContext) *ATNConfig { if semanticContext == nil { panic("semanticContext cannot be nil") // TODO: Remove this - probably put here for some bug that is now fixed } - - b := &BaseATNConfig{} - b.InitBaseATNConfig(c, state, c.GetAlt(), context, semanticContext) + b := &ATNConfig{ + cType: parserConfig, + } + b.InitATNConfig(c, state, c.GetAlt(), context, semanticContext) return b } -func (b *BaseATNConfig) InitBaseATNConfig(c ATNConfig, state ATNState, alt int, context *PredictionContext, semanticContext SemanticContext) { +func (a *ATNConfig) InitATNConfig(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() + a.state = state + a.alt = alt + a.context = context + a.semanticContext = semanticContext + a.reachesIntoOuterContext = c.GetReachesIntoOuterContext() + a.precedenceFilterSuppressed = c.getPrecedenceFilterSuppressed() } -func (b *BaseATNConfig) getPrecedenceFilterSuppressed() bool { - return b.precedenceFilterSuppressed +func (a *ATNConfig) getPrecedenceFilterSuppressed() bool { + return a.precedenceFilterSuppressed } -func (b *BaseATNConfig) setPrecedenceFilterSuppressed(v bool) { - b.precedenceFilterSuppressed = v +func (a *ATNConfig) setPrecedenceFilterSuppressed(v bool) { + a.precedenceFilterSuppressed = v } // GetState returns the ATN state associated with this configuration -func (b *BaseATNConfig) GetState() ATNState { - return b.state +func (a *ATNConfig) GetState() ATNState { + return a.state } // GetAlt returns the alternative associated with this configuration -func (b *BaseATNConfig) GetAlt() int { - return b.alt +func (a *ATNConfig) GetAlt() int { + return a.alt } // SetContext sets the rule invocation stack associated with this configuration -func (b *BaseATNConfig) SetContext(v *PredictionContext) { - b.context = v +func (a *ATNConfig) SetContext(v *PredictionContext) { + a.context = v } // GetContext returns the rule invocation stack associated with this configuration -func (b *BaseATNConfig) GetContext() *PredictionContext { - return b.context +func (a *ATNConfig) GetContext() *PredictionContext { + return a.context } // GetSemanticContext returns the semantic context associated with this configuration -func (b *BaseATNConfig) GetSemanticContext() SemanticContext { - return b.semanticContext +func (a *ATNConfig) GetSemanticContext() SemanticContext { + return a.semanticContext } // GetReachesIntoOuterContext returns the count of references to an outer context from this configuration -func (b *BaseATNConfig) GetReachesIntoOuterContext() int { - return b.reachesIntoOuterContext +func (a *ATNConfig) GetReachesIntoOuterContext() int { + return a.reachesIntoOuterContext } // SetReachesIntoOuterContext sets the count of references to an outer context from this configuration -func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) { - b.reachesIntoOuterContext = v +func (a *ATNConfig) SetReachesIntoOuterContext(v int) { + a.reachesIntoOuterContext = v } // Equals is the default comparison function for an ATNConfig when no specialist implementation is required @@ -173,149 +155,166 @@ func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) { // // An ATN configuration is equal to another if both have the same state, they // predict the same alternative, and syntactic/semantic contexts are the same. -func (b *BaseATNConfig) Equals(o Collectable[ATNConfig]) bool { - if b == o { - return true - } else if o == nil { - return false +func (a *ATNConfig) Equals(o Collectable[*ATNConfig]) bool { + switch a.cType { + case lexerConfig: + return a.LEquals(o) + case parserConfig: + return a.PEquals(o) + default: + panic("Invalid ATNConfig type") } - - var other, ok = o.(*BaseATNConfig) +} + +// PEquals is the default comparison function for a Parser ATNConfig when no specialist implementation is required +// for a collection. +// +// An ATN configuration is equal to another if both have the same state, they +// predict the same alternative, and syntactic/semantic contexts are the same. +func (a *ATNConfig) PEquals(o Collectable[*ATNConfig]) bool { + var other, ok = o.(*ATNConfig) if !ok { return false } + if a == other { + return true + } else if other == nil { + return false + } var equal bool - if b.context == nil { + if a.context == nil { equal = other.context == nil } else { - equal = b.context.Equals(other.context) + equal = a.context.Equals(other.context) } var ( - nums = b.state.GetStateNumber() == other.state.GetStateNumber() - alts = b.alt == other.alt - cons = b.semanticContext.Equals(other.semanticContext) - sups = b.precedenceFilterSuppressed == other.precedenceFilterSuppressed + nums = a.state.GetStateNumber() == other.state.GetStateNumber() + alts = a.alt == other.alt + cons = a.semanticContext.Equals(other.semanticContext) + sups = a.precedenceFilterSuppressed == other.precedenceFilterSuppressed ) return nums && alts && cons && sups && equal } -// Hash is the default hash function for BaseATNConfig, when no specialist hash function +// Hash is the default hash function for a parser ATNConfig, when no specialist hash function +// is required for a collection +func (a *ATNConfig) Hash() int { + switch a.cType { + case lexerConfig: + return a.LHash() + case parserConfig: + return a.PHash() + default: + panic("Invalid ATNConfig type") + } +} + +// PHash is the default hash function for a parser ATNConfig, when no specialist hash function // is required for a collection -func (b *BaseATNConfig) Hash() int { +func (a *ATNConfig) PHash() int { var c int - if b.context != nil { - c = b.context.Hash() + if a.context != nil { + c = a.context.Hash() } h := murmurInit(7) - h = murmurUpdate(h, b.state.GetStateNumber()) - h = murmurUpdate(h, b.alt) + h = murmurUpdate(h, a.state.GetStateNumber()) + h = murmurUpdate(h, a.alt) h = murmurUpdate(h, c) - h = murmurUpdate(h, b.semanticContext.Hash()) + h = murmurUpdate(h, a.semanticContext.Hash()) return murmurFinish(h, 4) } -// String returns a string representation of the BaseATNConfig, usually used for debugging purposes -func (b *BaseATNConfig) String() string { +// String returns a string representation of the ATNConfig, usually used for debugging purposes +func (a *ATNConfig) String() string { var s1, s2, s3 string - if b.context != nil { - s1 = ",[" + fmt.Sprint(b.context) + "]" + if a.context != nil { + s1 = ",[" + fmt.Sprint(a.context) + "]" } - if b.semanticContext != SemanticContextNone { - s2 = "," + fmt.Sprint(b.semanticContext) + if a.semanticContext != SemanticContextNone { + s2 = "," + fmt.Sprint(a.semanticContext) } - if b.reachesIntoOuterContext > 0 { - s3 = ",up=" + fmt.Sprint(b.reachesIntoOuterContext) + if a.reachesIntoOuterContext > 0 { + s3 = ",up=" + fmt.Sprint(a.reachesIntoOuterContext) } - return fmt.Sprintf("(%v,%v%v%v%v)", b.state, b.alt, s1, s2, s3) -} - -// LexerATNConfig represents a lexer ATN configuration which tracks the lexer action, and which "inherits" from the -// 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 - lexerActionExecutor *LexerActionExecutor - passedThroughNonGreedyDecision bool + return fmt.Sprintf("(%v,%v%v%v%v)", a.state, a.alt, s1, s2, s3) } -func NewLexerATNConfig6(state ATNState, alt int, context *PredictionContext) *LexerATNConfig { - - return &LexerATNConfig{ - BaseATNConfig: BaseATNConfig{ - state: state, - alt: alt, - context: context, - semanticContext: SemanticContextNone, - }, +func NewLexerATNConfig6(state ATNState, alt int, context *PredictionContext) *ATNConfig { + return &ATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: SemanticContextNone, + cType: lexerConfig, } } -func NewLexerATNConfig5(state ATNState, alt int, context *PredictionContext, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig { - return &LexerATNConfig{ - BaseATNConfig: BaseATNConfig{ - state: state, - alt: alt, - context: context, - semanticContext: SemanticContextNone, - }, +func NewLexerATNConfig5(state ATNState, alt int, context *PredictionContext, lexerActionExecutor *LexerActionExecutor) *ATNConfig { + return &ATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: SemanticContextNone, lexerActionExecutor: lexerActionExecutor, + cType: lexerConfig, } } -func NewLexerATNConfig4(c *LexerATNConfig, state ATNState) *LexerATNConfig { - lac := &LexerATNConfig{ - +func NewLexerATNConfig4(c *ATNConfig, state ATNState) *ATNConfig { + lac := &ATNConfig{ lexerActionExecutor: c.lexerActionExecutor, passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), } - lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext()) + lac.InitATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext()) + lac.cType = lexerConfig return lac } -func NewLexerATNConfig3(c *LexerATNConfig, state ATNState, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig { - lac := &LexerATNConfig{ +func NewLexerATNConfig3(c *ATNConfig, state ATNState, lexerActionExecutor *LexerActionExecutor) *ATNConfig { + lac := &ATNConfig{ lexerActionExecutor: lexerActionExecutor, passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), } - lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext()) + lac.InitATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext()) + lac.cType = lexerConfig return lac } -func NewLexerATNConfig2(c *LexerATNConfig, state ATNState, context *PredictionContext) *LexerATNConfig { - lac := &LexerATNConfig{ +func NewLexerATNConfig2(c *ATNConfig, state ATNState, context *PredictionContext) *ATNConfig { + lac := &ATNConfig{ lexerActionExecutor: c.lexerActionExecutor, passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), } - lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), context, c.GetSemanticContext()) + lac.InitATNConfig(c, state, c.GetAlt(), context, c.GetSemanticContext()) + lac.cType = lexerConfig return lac } //goland:noinspection GoUnusedExportedFunction -func NewLexerATNConfig1(state ATNState, alt int, context *PredictionContext) *LexerATNConfig { - lac := &LexerATNConfig{ - BaseATNConfig: BaseATNConfig{ - state: state, - alt: alt, - context: context, - semanticContext: SemanticContextNone, - }, +func NewLexerATNConfig1(state ATNState, alt int, context *PredictionContext) *ATNConfig { + lac := &ATNConfig{ + state: state, + alt: alt, + context: context, + semanticContext: SemanticContextNone, + cType: lexerConfig, } return lac } -// Hash is the default hash function for LexerATNConfig objects, it can be used directly or via +// LHash is the default hash function for Lexer ATNConfig objects, it can be used directly or via // the default comparator [ObjEqComparator]. -func (l *LexerATNConfig) Hash() int { +func (l *ATNConfig) LHash() int { var f int if l.passedThroughNonGreedyDecision { f = 1 @@ -333,21 +332,21 @@ func (l *LexerATNConfig) Hash() int { return h } -// Equals is the default comparison function for LexerATNConfig objects, it can be used directly or via +// LEquals is the default comparison function for Lexer ATNConfig objects, it can be used directly or via // the default comparator [ObjEqComparator]. -func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool { - if l == other { - return true - } - var otherT, ok = other.(*LexerATNConfig) +func (l *ATNConfig) LEquals(other Collectable[*ATNConfig]) bool { + var otherT, ok = other.(*ATNConfig) if !ok { return false + } else if l == otherT { + return true } else if l.passedThroughNonGreedyDecision != otherT.passedThroughNonGreedyDecision { return false } switch { case l.lexerActionExecutor == nil && otherT.lexerActionExecutor == nil: + return true case l.lexerActionExecutor != nil && otherT.lexerActionExecutor != nil: if !l.lexerActionExecutor.Equals(otherT.lexerActionExecutor) { return false @@ -356,10 +355,10 @@ func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool { return false // One but not both, are nil } - return l.BaseATNConfig.Equals(&otherT.BaseATNConfig) + return l.PEquals(otherT) } -func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool { +func checkNonGreedyDecision(source *ATNConfig, target ATNState) bool { var ds, ok = target.(DecisionState) return source.passedThroughNonGreedyDecision || (ok && ds.getNonGreedy()) diff --git a/runtime/Go/antlr/v4/atn_config_set.go b/runtime/Go/antlr/v4/atn_config_set.go index f6780cda1e..38461fed6e 100644 --- a/runtime/Go/antlr/v4/atn_config_set.go +++ b/runtime/Go/antlr/v4/atn_config_set.go @@ -8,62 +8,21 @@ import ( "fmt" ) -type ATNConfigSet interface { - Hash() int - Equals(o Collectable[ATNConfig]) bool - Add(ATNConfig, *DoubleDict) bool - AddAll([]ATNConfig) bool - - GetStates() *JStore[ATNState, Comparator[ATNState]] - GetPredicates() []SemanticContext - GetItems() []ATNConfig - - OptimizeConfigs(interpreter *BaseATNSimulator) - - Length() int - IsEmpty() bool - Contains(ATNConfig) bool - ContainsFast(ATNConfig) bool - Clear() - String() string - - HasSemanticContext() bool - SetHasSemanticContext(v bool) - - ReadOnly() bool - SetReadOnly(bool) - - GetConflictingAlts() *BitSet - SetConflictingAlts(*BitSet) - - Alts() *BitSet - - FullContext() bool - - GetUniqueAlt() int - SetUniqueAlt(int) - - GetDipsIntoOuterContext() bool - SetDipsIntoOuterContext(bool) -} - -// BaseATNConfigSet is a specialized set of ATNConfig that tracks information +// ATNConfigSet is a specialized set of ATNConfig that tracks information // about its elements and can combine similar configurations using a // graph-structured stack. -type BaseATNConfigSet struct { - - // TODO: Is this actually valid? JI +type ATNConfigSet struct { cachedHash int - // configLookup is used to determine whether two BaseATNConfigSets are equal. We + // configLookup is used to determine whether two ATNConfigSets are equal. We // need all configurations with the same (s, i, _, semctx) to be equal. A key // effectively doubles the number of objects associated with ATNConfigs. All // keys are hashed by (s, i, _, pi), not including the context. Wiped out when // read-only because a set becomes a DFA state. - configLookup *JStore[ATNConfig, Comparator[ATNConfig]] + configLookup *JStore[*ATNConfig, Comparator[*ATNConfig]] // configs is the added elements. - configs []ATNConfig + configs []*ATNConfig // TODO: These fields make me pretty uncomfortable, but it is nice to pack up // info together because it saves re-computation. Can we track conflicts as they @@ -72,7 +31,7 @@ type BaseATNConfigSet struct { // dipsIntoOuterContext is used by parsers and lexers. In a lexer, it indicates // we hit a pred while computing a closure operation. Do not make a DFA state - // from the BaseATNConfigSet in this case. TODO: How is this used by parsers? + // from the ATNConfigSet in this case. TODO: How is this used by parsers? dipsIntoOuterContext bool // fullCtx is whether it is part of a full context LL prediction. Used to @@ -97,7 +56,7 @@ type BaseATNConfigSet struct { } // Alts returns the combined set of alts for all the configurations in this set. -func (b *BaseATNConfigSet) Alts() *BitSet { +func (b *ATNConfigSet) Alts() *BitSet { alts := NewBitSet() for _, it := range b.configs { alts.add(it.GetAlt()) @@ -105,11 +64,11 @@ func (b *BaseATNConfigSet) Alts() *BitSet { return alts } -// NewBaseATNConfigSet creates a new BaseATNConfigSet instance. -func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { - return &BaseATNConfigSet{ +// NewATNConfigSet creates a new ATNConfigSet instance. +func NewATNConfigSet(fullCtx bool) *ATNConfigSet { + return &ATNConfigSet{ cachedHash: -1, - configLookup: NewJStore[ATNConfig, Comparator[ATNConfig]](aConfCompInst), + configLookup: NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfCompInst), fullCtx: fullCtx, } } @@ -120,7 +79,7 @@ func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { // // We use (s,i,pi) as the key. // Updates dipsIntoOuterContext and hasSemanticContext when necessary. -func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { +func (b *ATNConfigSet) Add(config *ATNConfig, mergeCache *JPCMap) bool { if b.readOnly { panic("set is read-only") } @@ -164,7 +123,7 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { } // GetStates returns the set of states represented by all configurations in this config set -func (b *BaseATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] { +func (b *ATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] { // states uses the standard comparator and Hash() provided by the ATNState instance // @@ -177,17 +136,7 @@ func (b *BaseATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] { return states } -// HasSemanticContext returns true if this set contains a semantic context. -func (b *BaseATNConfigSet) HasSemanticContext() bool { - return b.hasSemanticContext -} - -// SetHasSemanticContext sets whether this set contains a semantic context. -func (b *BaseATNConfigSet) SetHasSemanticContext(v bool) { - b.hasSemanticContext = v -} - -func (b *BaseATNConfigSet) GetPredicates() []SemanticContext { +func (b *ATNConfigSet) GetPredicates() []SemanticContext { predicates := make([]SemanticContext, 0) for i := 0; i < len(b.configs); i++ { @@ -201,11 +150,7 @@ func (b *BaseATNConfigSet) GetPredicates() []SemanticContext { return predicates } -func (b *BaseATNConfigSet) GetItems() []ATNConfig { - return b.configs -} - -func (b *BaseATNConfigSet) OptimizeConfigs(interpreter *BaseATNSimulator) { +func (b *ATNConfigSet) OptimizeConfigs(interpreter *BaseATNSimulator) { if b.readOnly { panic("set is read-only") } @@ -221,7 +166,7 @@ func (b *BaseATNConfigSet) OptimizeConfigs(interpreter *BaseATNSimulator) { } } -func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool { +func (b *ATNConfigSet) AddAll(coll []*ATNConfig) bool { for i := 0; i < len(coll); i++ { b.Add(coll[i], nil) } @@ -235,8 +180,7 @@ func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool { // only equal if they are in the same order too as Java uses ArrayList.equals(), which requires // the same order. // -// TODO: JI - Look to change the way config set is implemented. Improve data structure if possible -func (b *BaseATNConfigSet) Compare(bs *BaseATNConfigSet) bool { +func (b *ATNConfigSet) Compare(bs *ATNConfigSet) bool { if len(b.configs) != len(bs.configs) { return false } @@ -249,14 +193,14 @@ func (b *BaseATNConfigSet) Compare(bs *BaseATNConfigSet) bool { return true } -func (b *BaseATNConfigSet) Equals(other Collectable[ATNConfig]) bool { +func (b *ATNConfigSet) Equals(other Collectable[ATNConfig]) bool { if b == other { return true - } else if _, ok := other.(*BaseATNConfigSet); !ok { + } else if _, ok := other.(*ATNConfigSet); !ok { return false } - other2 := other.(*BaseATNConfigSet) + other2 := other.(*ATNConfigSet) var eca bool switch { case b.conflictingAlts == nil && other2.conflictingAlts == nil: @@ -273,7 +217,7 @@ func (b *BaseATNConfigSet) Equals(other Collectable[ATNConfig]) bool { b.Compare(other2) } -func (b *BaseATNConfigSet) Hash() int { +func (b *ATNConfigSet) Hash() int { if b.readOnly { if b.cachedHash == -1 { b.cachedHash = b.hashCodeConfigs() @@ -285,7 +229,7 @@ func (b *BaseATNConfigSet) Hash() int { return b.hashCodeConfigs() } -func (b *BaseATNConfigSet) hashCodeConfigs() int { +func (b *ATNConfigSet) hashCodeConfigs() int { h := 1 for _, config := range b.configs { h = 31*h + config.Hash() @@ -293,15 +237,7 @@ func (b *BaseATNConfigSet) hashCodeConfigs() int { return h } -func (b *BaseATNConfigSet) Length() int { - return len(b.configs) -} - -func (b *BaseATNConfigSet) IsEmpty() bool { - return len(b.configs) == 0 -} - -func (b *BaseATNConfigSet) Contains(item ATNConfig) bool { +func (b *ATNConfigSet) Contains(item *ATNConfig) bool { if b.configLookup == nil { panic("not implemented for read-only sets") } @@ -309,7 +245,7 @@ func (b *BaseATNConfigSet) Contains(item ATNConfig) bool { return b.configLookup.Contains(item) } -func (b *BaseATNConfigSet) ContainsFast(item ATNConfig) bool { +func (b *ATNConfigSet) ContainsFast(item *ATNConfig) bool { if b.configLookup == nil { panic("not implemented for read-only sets") } @@ -317,57 +253,17 @@ func (b *BaseATNConfigSet) ContainsFast(item ATNConfig) bool { return b.configLookup.Contains(item) // TODO: containsFast is not implemented for Set } -func (b *BaseATNConfigSet) Clear() { +func (b *ATNConfigSet) Clear() { if b.readOnly { panic("set is read-only") } - - b.configs = make([]ATNConfig, 0) + b.configs = make([]*ATNConfig, 0) b.cachedHash = -1 - b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst) + b.configLookup = NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfCompInst) } -func (b *BaseATNConfigSet) FullContext() bool { - return b.fullCtx -} - -func (b *BaseATNConfigSet) GetDipsIntoOuterContext() bool { - return b.dipsIntoOuterContext -} - -func (b *BaseATNConfigSet) SetDipsIntoOuterContext(v bool) { - b.dipsIntoOuterContext = v -} - -func (b *BaseATNConfigSet) GetUniqueAlt() int { - return b.uniqueAlt -} - -func (b *BaseATNConfigSet) SetUniqueAlt(v int) { - b.uniqueAlt = v -} - -func (b *BaseATNConfigSet) GetConflictingAlts() *BitSet { - return b.conflictingAlts -} - -func (b *BaseATNConfigSet) SetConflictingAlts(v *BitSet) { - b.conflictingAlts = v -} - -func (b *BaseATNConfigSet) ReadOnly() bool { - return b.readOnly -} - -func (b *BaseATNConfigSet) SetReadOnly(readOnly bool) { - b.readOnly = readOnly - - if readOnly { - b.configLookup = nil // Read only, so no need for the lookup cache - } -} +func (b *ATNConfigSet) String() string { -func (b *BaseATNConfigSet) String() string { s := "[" for i, c := range b.configs { @@ -399,15 +295,13 @@ func (b *BaseATNConfigSet) String() string { return s } -type OrderedATNConfigSet struct { - *BaseATNConfigSet -} - -func NewOrderedATNConfigSet() *OrderedATNConfigSet { - b := NewBaseATNConfigSet(false) - - // This set uses the standard Hash() and Equals() from ATNConfig - b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) - - return &OrderedATNConfigSet{BaseATNConfigSet: b} +// NewOrderedATNConfigSet creates a config set with a slightly different Hash/Equal pair +// for use in lexers. +func NewOrderedATNConfigSet() *ATNConfigSet { + return &ATNConfigSet{ + cachedHash: -1, + // This set uses the standard Hash() and Equals() from ATNConfig + configLookup: NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfEqInst), + fullCtx: false, + } } diff --git a/runtime/Go/antlr/v4/atn_simulator.go b/runtime/Go/antlr/v4/atn_simulator.go index e26be67199..902f26c9e8 100644 --- a/runtime/Go/antlr/v4/atn_simulator.go +++ b/runtime/Go/antlr/v4/atn_simulator.go @@ -4,7 +4,7 @@ package antlr -var ATNSimulatorError = NewDFAState(0x7FFFFFFF, NewBaseATNConfigSet(false)) +var ATNSimulatorError = NewDFAState(0x7FFFFFFF, NewATNConfigSet(false)) type IATNSimulator interface { SharedContextCache() *PredictionContextCache @@ -24,7 +24,7 @@ func (b *BaseATNSimulator) getCachedContext(context *PredictionContext) *Predict } // TODO: Should this be guarded by a mutex? - visited := NewJStore[*PredictionContext, Comparator[*PredictionContext]](pContextEqInst) + visited := NewJMap[*PredictionContext, *PredictionContext, Comparator[*PredictionContext]](pContextEqInst) 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 d854ef1a84..96d60db3b5 100644 --- a/runtime/Go/antlr/v4/atn_state.go +++ b/runtime/Go/antlr/v4/atn_state.go @@ -78,7 +78,7 @@ type BaseATNState struct { transitions []Transition } -func NewBaseATNState() *BaseATNState { +func NewATNState() *BaseATNState { return &BaseATNState{stateNumber: ATNStateInvalidStateNumber, stateType: ATNStateInvalidType} } diff --git a/runtime/Go/antlr/v4/atnconfigset_test.go b/runtime/Go/antlr/v4/atnconfigset_test.go index 44fd4db4c2..5d7c042258 100644 --- a/runtime/Go/antlr/v4/atnconfigset_test.go +++ b/runtime/Go/antlr/v4/atnconfigset_test.go @@ -18,17 +18,17 @@ import ( func TestCompare(t *testing.T) { var set = NewOrderedATNConfigSet() - var s0 = NewBaseATNState() - var s1 = NewBaseATNState() - var s2 = NewBaseATNState() - var s3 = NewBaseATNState() - var s16 = NewBaseATNState() + var s0 = NewATNState() + var s1 = NewATNState() + var s2 = NewATNState() + var s3 = NewATNState() + var s16 = NewATNState() s16.SetStateNumber(16) - var s17 = NewBaseATNState() + var s17 = NewATNState() s17.SetStateNumber(17) - var s18 = NewBaseATNState() + var s18 = NewATNState() s18.SetStateNumber(18) - var s19 = NewBaseATNState() + var s19 = NewATNState() s19.SetStateNumber(19) var la0 = NewBaseLexerAction(1) var la1 = NewBaseLexerAction(2) @@ -36,42 +36,42 @@ func TestCompare(t *testing.T) { laa[0] = la0 laa[1] = la1 var ae = NewLexerActionExecutor(laa) - set.Add(NewLexerATNConfig5(s0, 0, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s0, 1, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s0, 2, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s1, 0, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s1, 1, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s1, 2, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s2, 0, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s2, 1, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s2, 2, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s3, 0, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s3, 1, BasePredictionContextEMPTY, ae), nil) - set.Add(NewLexerATNConfig5(s3, 2, BasePredictionContextEMPTY, ae), nil) - - set.Add(NewLexerATNConfig5(s0, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s0, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s0, 2, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s1, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s1, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s1, 2, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s2, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s2, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s2, 2, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s3, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s3, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s3, 2, BasePredictionContextEMPTY, nil), nil) - - set.Add(NewLexerATNConfig5(s16, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s16, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s16, 2, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s17, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s17, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s17, 2, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s18, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s18, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s18, 2, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s19, 0, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s19, 1, BasePredictionContextEMPTY, nil), nil) - set.Add(NewLexerATNConfig5(s19, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s0, 0, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s0, 1, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s0, 2, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s1, 0, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s1, 1, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s1, 2, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s2, 0, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s2, 1, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s2, 2, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s3, 0, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s3, 1, BasePredictionContextEMPTY, ae), nil) + set.Add(NewATNConfig5(s3, 2, BasePredictionContextEMPTY, ae), nil) + + set.Add(NewATNConfig5(s0, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s0, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s0, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s1, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s1, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s1, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s2, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s2, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s2, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s3, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s3, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s3, 2, BasePredictionContextEMPTY, nil), nil) + + set.Add(NewATNConfig5(s16, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s16, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s16, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s17, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s17, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s17, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s18, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s18, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s18, 2, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s19, 0, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s19, 1, BasePredictionContextEMPTY, nil), nil) + set.Add(NewATNConfig5(s19, 2, BasePredictionContextEMPTY, nil), nil) } diff --git a/runtime/Go/antlr/v4/common_token_stream_test.go b/runtime/Go/antlr/v4/common_token_stream_test.go index e7c75d49b1..d8503e10a1 100644 --- a/runtime/Go/antlr/v4/common_token_stream_test.go +++ b/runtime/Go/antlr/v4/common_token_stream_test.go @@ -171,8 +171,7 @@ func TestCommonTokenStreamGetTextFromInterval(t *testing.T) { }, } tokens := NewCommonTokenStream(lexEngine, TokenDefaultChannel) - assert.Equal("x", tokens.GetTextFromInterval(&Interval{Start: 1, Stop: 1})) + assert.Equal("x", tokens.GetTextFromInterval(Interval{Start: 1, Stop: 1})) assert.Equal(len(tokens.tokens), 2) - assert.Equal(" x =34 ; \n", tokens.GetTextFromInterval(nil)) assert.Equal(len(tokens.tokens), 11) } diff --git a/runtime/Go/antlr/v4/comparators.go b/runtime/Go/antlr/v4/comparators.go index da5a116b40..0d27713885 100644 --- a/runtime/Go/antlr/v4/comparators.go +++ b/runtime/Go/antlr/v4/comparators.go @@ -22,13 +22,15 @@ package antlr type ObjEqComparator[T Collectable[T]] struct{} var ( - aStateEqInst = &ObjEqComparator[ATNState]{} - aConfEqInst = &ObjEqComparator[ATNConfig]{} - aConfCompInst = &ATNConfigComparator[ATNConfig]{} - atnConfCompInst = &BaseATNConfigComparator[ATNConfig]{} + aStateEqInst = &ObjEqComparator[ATNState]{} + aConfEqInst = &ObjEqComparator[*ATNConfig]{} + + // aConfCompInst is the comparator used for the ATNConfigSet for the configLookup cache + aConfCompInst = &ATNConfigComparator[*ATNConfig]{} + atnConfCompInst = &BaseATNConfigComparator[*ATNConfig]{} dfaStateEqInst = &ObjEqComparator[*DFAState]{} semctxEqInst = &ObjEqComparator[SemanticContext]{} - atnAltCfgEqInst = &ATNAltConfigComparator[ATNConfig]{} + atnAltCfgEqInst = &ATNAltConfigComparator[*ATNConfig]{} pContextEqInst = &ObjEqComparator[*PredictionContext]{} ) @@ -52,7 +54,7 @@ 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 { +func (c *ATNConfigComparator[T]) Equals2(o1, o2 *ATNConfig) bool { // Same pointer, must be equal, even if both nil // @@ -69,21 +71,16 @@ func (c *ATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && o1.GetAlt() == o2.GetAlt() && - o1.GetContext().Equals(o2.GetContext()) && - o1.GetSemanticContext().Equals(o2.GetSemanticContext()) && - o1.getPrecedenceFilterSuppressed() == o2.getPrecedenceFilterSuppressed() + o1.GetSemanticContext().Equals(o2.GetSemanticContext()) } // Hash1 is custom hash implementation for ATNConfigs specifically for configLookup -func (c *ATNConfigComparator[T]) Hash1(o ATNConfig) int { - - hash := murmurInit(7) - hash = murmurUpdate(hash, o.GetState().GetStateNumber()) - hash = murmurUpdate(hash, o.GetAlt()) - hash = murmurUpdate(hash, o.GetContext().Hash()) - hash = murmurUpdate(hash, o.GetSemanticContext().Hash()) - hash = murmurFinish(hash, 4) +func (c *ATNConfigComparator[T]) Hash1(o *ATNConfig) int { + hash := 7 + hash = 31*hash + o.GetState().GetStateNumber() + hash = 31*hash + o.GetAlt() + hash = 31*hash + o.GetSemanticContext().Hash() return hash } @@ -92,7 +89,7 @@ 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 { +func (c *ATNAltConfigComparator[T]) Equals2(o1, o2 *ATNConfig) bool { // Same pointer, must be equal, even if both nil // @@ -112,21 +109,21 @@ func (c *ATNAltConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { } // Hash1 is custom hash implementation for ATNConfigs specifically for configLookup -func (c *ATNAltConfigComparator[T]) Hash1(o ATNConfig) int { +func (c *ATNAltConfigComparator[T]) Hash1(o *ATNConfig) int { h := murmurInit(7) h = murmurUpdate(h, o.GetState().GetStateNumber()) h = murmurUpdate(h, o.GetContext().Hash()) return murmurFinish(h, 2) } -// BaseATNConfigComparator is used as the comparator for the configLookup field of a BaseATNConfigSet +// BaseATNConfigComparator is used as the comparator for the configLookup field of a ATNConfigSet // and has a custom Equals() and Hash() implementation, because equality is not based on the // standard Hash() and Equals() methods of the ATNConfig type. 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 { +func (c *BaseATNConfigComparator[T]) Equals2(o1, o2 *ATNConfig) bool { // Same pointer, must be equal, even if both nil // @@ -148,7 +145,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 { - +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 74a06d4757..c7ce29354a 100644 --- a/runtime/Go/antlr/v4/dfa.go +++ b/runtime/Go/antlr/v4/dfa.go @@ -37,7 +37,7 @@ func NewDFA(atnStartState DecisionState, decision int) *DFA { } if s, ok := atnStartState.(*StarLoopEntryState); ok && s.precedenceRuleDecision { dfa.precedenceDfa = true - dfa.s0 = NewDFAState(-1, NewBaseATNConfigSet(false)) + dfa.s0 = NewDFAState(-1, NewATNConfigSet(false)) dfa.s0.isAcceptState = false dfa.s0.requiresFullContext = false } @@ -100,8 +100,7 @@ func (d *DFA) setPrecedenceDfa(precedenceDfa bool) { d.numstates = 0 if precedenceDfa { - precedenceState := NewDFAState(-1, NewBaseATNConfigSet(false)) - + precedenceState := NewDFAState(-1, NewATNConfigSet(false)) precedenceState.setEdges(make([]*DFAState, 0)) precedenceState.isAcceptState = false precedenceState.requiresFullContext = false diff --git a/runtime/Go/antlr/v4/dfa_state.go b/runtime/Go/antlr/v4/dfa_state.go index 8f94d05ed5..b22cf9efec 100644 --- a/runtime/Go/antlr/v4/dfa_state.go +++ b/runtime/Go/antlr/v4/dfa_state.go @@ -46,27 +46,27 @@ func (p *PredPrediction) String() string { // reached via a different set of rule invocations. type DFAState struct { stateNumber int - configs ATNConfigSet - + configs *ATNConfigSet + // edges elements point to the target of the symbol. Shift up by 1 so (-1) // Token.EOF maps to the first element. edges []*DFAState - + isAcceptState bool // prediction is the 'ttype' we match or alt we predict if the state is 'accept'. // Set to ATN.INVALID_ALT_NUMBER when predicates != nil or // requiresFullContext. prediction int - + lexerActionExecutor *LexerActionExecutor - + // requiresFullContext indicates it was created during an SLL prediction that // discovered a conflict between the configurations in the state. Future // ParserATNSimulator.execATN invocations immediately jump doing // full context prediction if true. requiresFullContext bool - + // predicates is the predicates associated with the ATN configurations of the // DFA state during SLL parsing. When we have predicates, requiresFullContext // is false, since full context prediction evaluates predicates on-the-fly. If @@ -82,28 +82,28 @@ type DFAState struct { predicates []*PredPrediction } -func NewDFAState(stateNumber int, configs ATNConfigSet) *DFAState { +func NewDFAState(stateNumber int, configs *ATNConfigSet) *DFAState { if configs == nil { - configs = NewBaseATNConfigSet(false) + configs = NewATNConfigSet(false) } - + return &DFAState{configs: configs, stateNumber: stateNumber} } // GetAltSet gets the set of all alts mentioned by all ATN configurations in d. func (d *DFAState) GetAltSet() []int { var alts []int - + if d.configs != nil { - for _, c := range d.configs.GetItems() { + for _, c := range d.configs.configs { alts = append(alts, c.GetAlt()) } } - + if len(alts) == 0 { return nil } - + return alts } @@ -140,7 +140,7 @@ func (d *DFAState) String() string { s = "=>" + fmt.Sprint(d.prediction) } } - + return fmt.Sprintf("%d:%s%s", d.stateNumber, fmt.Sprint(d.configs), s) } @@ -165,6 +165,6 @@ func (d *DFAState) Equals(o Collectable[*DFAState]) bool { if d == o { return true } - + return d.configs.Equals(o.(*DFAState).configs) } diff --git a/runtime/Go/antlr/v4/diagnostic_error_listener.go b/runtime/Go/antlr/v4/diagnostic_error_listener.go index 91ae237b51..bd2cd8bc3a 100644 --- a/runtime/Go/antlr/v4/diagnostic_error_listener.go +++ b/runtime/Go/antlr/v4/diagnostic_error_listener.go @@ -43,7 +43,7 @@ func NewDiagnosticErrorListener(exactOnly bool) *DiagnosticErrorListener { return n } -func (d *DiagnosticErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { +func (d *DiagnosticErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs *ATNConfigSet) { if d.exactOnly && !exact { return } @@ -56,7 +56,7 @@ func (d *DiagnosticErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, s recognizer.NotifyErrorListeners(msg, nil, nil) } -func (d *DiagnosticErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, _ *BitSet, _ ATNConfigSet) { +func (d *DiagnosticErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, _ *BitSet, _ *ATNConfigSet) { msg := "reportAttemptingFullContext d=" + d.getDecisionDescription(recognizer, dfa) + @@ -65,7 +65,7 @@ func (d *DiagnosticErrorListener) ReportAttemptingFullContext(recognizer Parser, recognizer.NotifyErrorListeners(msg, nil, nil) } -func (d *DiagnosticErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, _ int, _ ATNConfigSet) { +func (d *DiagnosticErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, _ int, _ *ATNConfigSet) { msg := "reportContextSensitivity d=" + d.getDecisionDescription(recognizer, dfa) + ", input='" + @@ -97,12 +97,12 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa // @param configs The conflicting or ambiguous configuration set. // @return Returns {@code ReportedAlts} if it is not {@code nil}, otherwise // returns the set of alternatives represented in {@code configs}. -func (d *DiagnosticErrorListener) getConflictingAlts(ReportedAlts *BitSet, set ATNConfigSet) *BitSet { +func (d *DiagnosticErrorListener) getConflictingAlts(ReportedAlts *BitSet, set *ATNConfigSet) *BitSet { if ReportedAlts != nil { return ReportedAlts } result := NewBitSet() - for _, c := range set.GetItems() { + for _, c := range set.configs { result.add(c.GetAlt()) } diff --git a/runtime/Go/antlr/v4/error_listener.go b/runtime/Go/antlr/v4/error_listener.go index 40edcd71a4..21a0216434 100644 --- a/runtime/Go/antlr/v4/error_listener.go +++ b/runtime/Go/antlr/v4/error_listener.go @@ -16,9 +16,9 @@ import ( type ErrorListener interface { SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) - ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) - ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) - ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) + ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs *ATNConfigSet) + ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs *ATNConfigSet) + ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs *ATNConfigSet) } type DefaultErrorListener struct { @@ -32,13 +32,13 @@ func NewDefaultErrorListener() *DefaultErrorListener { func (d *DefaultErrorListener) SyntaxError(_ Recognizer, _ interface{}, _, _ int, _ string, _ RecognitionException) { } -func (d *DefaultErrorListener) ReportAmbiguity(_ Parser, _ *DFA, _, _ int, _ bool, _ *BitSet, _ ATNConfigSet) { +func (d *DefaultErrorListener) ReportAmbiguity(_ Parser, _ *DFA, _, _ int, _ bool, _ *BitSet, _ *ATNConfigSet) { } -func (d *DefaultErrorListener) ReportAttemptingFullContext(_ Parser, _ *DFA, _, _ int, _ *BitSet, _ ATNConfigSet) { +func (d *DefaultErrorListener) ReportAttemptingFullContext(_ Parser, _ *DFA, _, _ int, _ *BitSet, _ *ATNConfigSet) { } -func (d *DefaultErrorListener) ReportContextSensitivity(_ Parser, _ *DFA, _, _, _ int, _ ATNConfigSet) { +func (d *DefaultErrorListener) ReportContextSensitivity(_ Parser, _ *DFA, _, _, _ int, _ *ATNConfigSet) { } type ConsoleErrorListener struct { @@ -81,19 +81,19 @@ func (p *ProxyErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol } } -func (p *ProxyErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { +func (p *ProxyErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs *ATNConfigSet) { for _, d := range p.delegates { d.ReportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) } } -func (p *ProxyErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) { +func (p *ProxyErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs *ATNConfigSet) { for _, d := range p.delegates { d.ReportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) } } -func (p *ProxyErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) { +func (p *ProxyErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs *ATNConfigSet) { for _, d := range p.delegates { d.ReportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs) } diff --git a/runtime/Go/antlr/v4/errors.go b/runtime/Go/antlr/v4/errors.go index 1a4868e585..8239e13130 100644 --- a/runtime/Go/antlr/v4/errors.go +++ b/runtime/Go/antlr/v4/errors.go @@ -100,10 +100,10 @@ type LexerNoViableAltException struct { *BaseRecognitionException startIndex int - deadEndConfigs ATNConfigSet + deadEndConfigs *ATNConfigSet } -func NewLexerNoViableAltException(lexer Lexer, input CharStream, startIndex int, deadEndConfigs ATNConfigSet) *LexerNoViableAltException { +func NewLexerNoViableAltException(lexer Lexer, input CharStream, startIndex int, deadEndConfigs *ATNConfigSet) *LexerNoViableAltException { l := new(LexerNoViableAltException) @@ -129,7 +129,7 @@ type NoViableAltException struct { startToken Token offendingToken Token ctx ParserRuleContext - deadEndConfigs ATNConfigSet + deadEndConfigs *ATNConfigSet } // NewNoViableAltException creates an exception indicating that the parser could not decide which of two or more paths @@ -138,7 +138,7 @@ type NoViableAltException struct { // in the various paths when the error. // // Reported by [ReportNoViableAlternative] -func NewNoViableAltException(recognizer Parser, input TokenStream, startToken Token, offendingToken Token, deadEndConfigs ATNConfigSet, ctx ParserRuleContext) *NoViableAltException { +func NewNoViableAltException(recognizer Parser, input TokenStream, startToken Token, offendingToken Token, deadEndConfigs *ATNConfigSet, ctx ParserRuleContext) *NoViableAltException { if ctx == nil { ctx = recognizer.GetParserRuleContext() diff --git a/runtime/Go/antlr/v4/jcollect.go b/runtime/Go/antlr/v4/jcollect.go index 137a287280..a336e8f3cb 100644 --- a/runtime/Go/antlr/v4/jcollect.go +++ b/runtime/Go/antlr/v4/jcollect.go @@ -196,3 +196,41 @@ func (m *JMap[K, V, C]) Delete(key K) { func (m *JMap[K, V, C]) Clear() { m.store = make(map[int][]*entry[K, V]) } + +type JPCMap struct { + store *JMap[*PredictionContext, *JMap[*PredictionContext, *PredictionContext, *ObjEqComparator[*PredictionContext]], *ObjEqComparator[*PredictionContext]] +} + +func NewJPCMap() *JPCMap { + return &JPCMap{ + store: NewJMap[*PredictionContext, *JMap[*PredictionContext, *PredictionContext, *ObjEqComparator[*PredictionContext]], *ObjEqComparator[*PredictionContext]](pContextEqInst), + } +} + +func (pcm *JPCMap) Get(k1, k2 *PredictionContext) (*PredictionContext, bool) { + + // Do we have a map stored by k1? + // + m2, present := pcm.store.Get(k1) + if present { + // We found a map of values corresponding to k1, so now we need to look up k2 in that map + // + return m2.Get(k2) + } + return nil, false +} + +func (pcm *JPCMap) Put(k1, k2, v *PredictionContext) { + + // First does a map already exist for k1? + // + if m2, present := pcm.store.Get(k1); present { + m2.Put(k2, v) + } else { + // No map found for k1, so we create it, add in our value, then store is + // + m2 = NewJMap[*PredictionContext, *PredictionContext, *ObjEqComparator[*PredictionContext]](pContextEqInst) + m2.Put(k2, v) + pcm.store.Put(k1, m2) + } +} diff --git a/runtime/Go/antlr/v4/lexer_action_executor.go b/runtime/Go/antlr/v4/lexer_action_executor.go index f7fcfc8c75..ab38e99799 100644 --- a/runtime/Go/antlr/v4/lexer_action_executor.go +++ b/runtime/Go/antlr/v4/lexer_action_executor.go @@ -29,7 +29,7 @@ func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor { l.lexerActions = lexerActions // Caches the result of {@link //hashCode} since the hash code is an element - // of the performance-critical {@link LexerATNConfig//hashCode} operation. + // of the performance-critical {@link ATNConfig//hashCode} operation. l.cachedHash = murmurInit(0) for _, a := range lexerActions { l.cachedHash = murmurUpdate(l.cachedHash, a.Hash()) diff --git a/runtime/Go/antlr/v4/lexer_atn_simulator.go b/runtime/Go/antlr/v4/lexer_atn_simulator.go index bca6444c5d..8dff06324c 100644 --- a/runtime/Go/antlr/v4/lexer_atn_simulator.go +++ b/runtime/Go/antlr/v4/lexer_atn_simulator.go @@ -37,7 +37,7 @@ type LexerATNSimulator struct { recog Lexer predictionMode int - mergeCache DoubleDict + mergeCache *JPCMap startIndex int Line int CharPositionInLine int @@ -245,7 +245,7 @@ func (l *LexerATNSimulator) computeTargetState(input CharStream, s *DFAState, t // 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) + l.getReachableConfigSet(input, s.configs, reach, t) if len(reach.configs) == 0 { // we got nowhere on t from s if !reach.hasSemanticContext { @@ -257,10 +257,10 @@ func (l *LexerATNSimulator) computeTargetState(input CharStream, s *DFAState, t return ATNSimulatorError } // Add an edge from s to target DFA found/created for reach - return l.addDFAEdge(s, t, nil, reach.BaseATNConfigSet) + return l.addDFAEdge(s, t, nil, reach) } -func (l *LexerATNSimulator) failOrAccept(prevAccept *SimState, input CharStream, reach ATNConfigSet, t int) int { +func (l *LexerATNSimulator) failOrAccept(prevAccept *SimState, input CharStream, reach *ATNConfigSet, t int) int { if l.prevAccept.dfaState != nil { lexerActionExecutor := prevAccept.dfaState.lexerActionExecutor l.accept(input, lexerActionExecutor, l.startIndex, prevAccept.index, prevAccept.line, prevAccept.column) @@ -279,14 +279,14 @@ func (l *LexerATNSimulator) failOrAccept(prevAccept *SimState, input CharStream, // we can reach upon input t. // // Parameter reach is a return parameter. -func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNConfigSet, reach ATNConfigSet, t int) { +func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure *ATNConfigSet, reach *ATNConfigSet, t int) { // 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() { + + for _, cfg := range closure.configs { currentAltReachedAcceptState := cfg.GetAlt() == SkipAlt - if currentAltReachedAcceptState && cfg.(*LexerATNConfig).passedThroughNonGreedyDecision { + if currentAltReachedAcceptState && cfg.passedThroughNonGreedyDecision { continue } @@ -299,12 +299,12 @@ func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNC for _, trans := range cfg.GetState().GetTransitions() { target := l.getReachableTarget(trans, t) if target != nil { - lexerActionExecutor := cfg.(*LexerATNConfig).lexerActionExecutor + lexerActionExecutor := cfg.lexerActionExecutor if lexerActionExecutor != nil { lexerActionExecutor = lexerActionExecutor.fixOffsetBeforeMatch(input.Index() - l.startIndex) } treatEOFAsEpsilon := t == TokenEOF - config := NewLexerATNConfig3(cfg.(*LexerATNConfig), target, lexerActionExecutor) + config := NewLexerATNConfig3(cfg, target, lexerActionExecutor) if l.closure(input, config, reach, currentAltReachedAcceptState, true, treatEOFAsEpsilon) { // any remaining configs for l alt have a lower priority @@ -338,7 +338,7 @@ func (l *LexerATNSimulator) getReachableTarget(trans Transition, t int) ATNState return nil } -func (l *LexerATNSimulator) computeStartState(input CharStream, p ATNState) *OrderedATNConfigSet { +func (l *LexerATNSimulator) computeStartState(input CharStream, p ATNState) *ATNConfigSet { configs := NewOrderedATNConfigSet() for i := 0; i < len(p.GetTransitions()); i++ { target := p.GetTransitions()[i].getTarget() @@ -356,7 +356,7 @@ func (l *LexerATNSimulator) computeStartState(input CharStream, p ATNState) *Ord // this rule would have a lower priority. // // The func returns true if an accept state is reached. -func (l *LexerATNSimulator) closure(input CharStream, config *LexerATNConfig, configs ATNConfigSet, +func (l *LexerATNSimulator) closure(input CharStream, config *ATNConfig, configs *ATNConfigSet, currentAltReachedAcceptState, speculative, treatEOFAsEpsilon bool) bool { if //goland:noinspection GoBoolExpressions @@ -415,10 +415,10 @@ 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 { +func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *ATNConfig, trans Transition, + configs *ATNConfigSet, speculative, treatEOFAsEpsilon bool) *ATNConfig { - var cfg *LexerATNConfig + var cfg *ATNConfig if trans.getSerializationType() == TransitionRULE { @@ -453,7 +453,7 @@ func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNC LexerATNSimulatorDebug { fmt.Println("EVAL rule " + strconv.Itoa(trans.(*PredicateTransition).ruleIndex) + ":" + strconv.Itoa(pt.predIndex)) } - configs.SetHasSemanticContext(true) + configs.hasSemanticContext = true if l.evaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative) { cfg = NewLexerATNConfig4(config, trans.getTarget()) } @@ -534,7 +534,7 @@ func (l *LexerATNSimulator) captureSimState(settings *SimState, input CharStream settings.dfaState = dfaState } -func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfgs ATNConfigSet) *DFAState { +func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfgs *ATNConfigSet) *DFAState { if to == nil && cfgs != nil { // leading to l call, ATNConfigSet.hasSemanticContext is used as a // marker indicating dynamic predicate evaluation makes l edge @@ -546,10 +546,9 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg // TJP notes: next time through the DFA, we see a pred again and eval. // If that gets us to a previously created (but dangling) DFA // state, we can continue in pure DFA mode from there. - // / - suppressEdge := cfgs.HasSemanticContext() - cfgs.SetHasSemanticContext(false) - + // + suppressEdge := cfgs.hasSemanticContext + cfgs.hasSemanticContext = false to = l.addDFAState(cfgs, true) if suppressEdge { @@ -580,13 +579,12 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg // configurations already. This method also detects the first // 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 { +func (l *LexerATNSimulator) addDFAState(configs *ATNConfigSet, suppressEdge bool) *DFAState { proposed := NewDFAState(-1, configs) - var firstConfigWithRuleStopState ATNConfig + var firstConfigWithRuleStopState *ATNConfig - for _, cfg := range configs.GetItems() { - + for _, cfg := range configs.configs { _, ok := cfg.GetState().(*RuleStopState) if ok { @@ -596,7 +594,7 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool) } if firstConfigWithRuleStopState != nil { proposed.isAcceptState = true - proposed.lexerActionExecutor = firstConfigWithRuleStopState.(*LexerATNConfig).lexerActionExecutor + proposed.lexerActionExecutor = firstConfigWithRuleStopState.lexerActionExecutor proposed.setPrediction(l.atn.ruleToTokenType[firstConfigWithRuleStopState.GetState().GetRuleIndex()]) } dfa := l.decisionToDFA[l.mode] @@ -614,7 +612,8 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool) // We need to add the new state // proposed.stateNumber = dfa.states.Len() - configs.SetReadOnly(true) + configs.readOnly = true + configs.configLookup = nil // Not needed now proposed.configs = configs dfa.states.Put(proposed) } diff --git a/runtime/Go/antlr/v4/ll1_analyzer.go b/runtime/Go/antlr/v4/ll1_analyzer.go index 0b86272bfd..3319f8642b 100644 --- a/runtime/Go/antlr/v4/ll1_analyzer.go +++ b/runtime/Go/antlr/v4/ll1_analyzer.go @@ -40,7 +40,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { for alt := 0; alt < count; alt++ { look[alt] = NewIntervalSet() - lookBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) + lookBusy := NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfEqInst) la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), false, false) // Wipe out lookahead for la alternative if we found nothing, @@ -75,7 +75,7 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet if ctx != nil { lookContext = predictionContextFromRuleContext(s.GetATN(), ctx) } - la.look1(s, stopState, lookContext, r, NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst), NewBitSet(), true, true) + la.look1(s, stopState, lookContext, r, NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfEqInst), NewBitSet(), true, true) return r } @@ -109,16 +109,16 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet // outermost context is reached. This parameter has no effect if {@code ctx} // is {@code nil}. -func (la *LL1Analyzer) look2(_, stopState ATNState, ctx *PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) { +func (la *LL1Analyzer) look2(_, stopState ATNState, ctx *PredictionContext, look *IntervalSet, lookBusy *JStore[*ATNConfig, Comparator[*ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) { returnState := la.atn.states[ctx.getReturnState(i)] la.look1(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF) } -func (la *LL1Analyzer) look1(s, stopState ATNState, ctx *PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool) { +func (la *LL1Analyzer) look1(s, stopState ATNState, ctx *PredictionContext, look *IntervalSet, lookBusy *JStore[*ATNConfig, Comparator[*ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool) { - c := NewBaseATNConfig6(s, 0, ctx) + c := NewATNConfig6(s, 0, ctx) if lookBusy.Contains(c) { return @@ -201,7 +201,7 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx *PredictionContext, look } } -func (la *LL1Analyzer) look3(stopState ATNState, ctx *PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { +func (la *LL1Analyzer) look3(stopState ATNState, ctx *PredictionContext, look *IntervalSet, lookBusy *JStore[*ATNConfig, Comparator[*ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber()) diff --git a/runtime/Go/antlr/v4/parser_atn_simulator.go b/runtime/Go/antlr/v4/parser_atn_simulator.go index bd047da056..df74767faa 100644 --- a/runtime/Go/antlr/v4/parser_atn_simulator.go +++ b/runtime/Go/antlr/v4/parser_atn_simulator.go @@ -26,7 +26,7 @@ type ParserATNSimulator struct { input TokenStream startIndex int dfa *DFA - mergeCache *DoubleDict + mergeCache *JPCMap outerContext ParserRuleContext } @@ -50,7 +50,7 @@ func NewParserATNSimulator(parser Parser, atn *ATN, decisionToDFA []*DFA, shared p.outerContext = nil p.dfa = nil // Each prediction operation uses a cache for merge of prediction contexts. - // Don't keep around as it wastes huge amounts of memory. DoubleKeyMap + // Don't keep around as it wastes huge amounts of memory. [JPCMap] // isn't Synchronized, but we're ok since two threads shouldn't reuse same // parser/atn-simulator object because it can only handle one input at a time. // This maps graphs a and b to merged result c. (a,b) -> c. We can avoid @@ -81,7 +81,6 @@ func (p *ParserATNSimulator) AdaptivePredict(parser *BaseParser, input TokenStre " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn())) } - p.input = input p.startIndex = input.Index() p.outerContext = outerContext @@ -231,7 +230,7 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, } if D.requiresFullContext && p.predictionMode != PredictionModeSLL { // IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error) - conflictingAlts := D.configs.GetConflictingAlts() + conflictingAlts := D.configs.conflictingAlts if D.predicates != nil { if ParserATNSimulatorDebug { fmt.Println("DFA state has preds in DFA sim LL fail-over") @@ -351,17 +350,17 @@ func (p *ParserATNSimulator) computeTargetState(dfa *DFA, previousD *DFAState, t if predictedAlt != ATNInvalidAltNumber { // NO CONFLICT, UNIQUELY PREDICTED ALT D.isAcceptState = true - D.configs.SetUniqueAlt(predictedAlt) + D.configs.uniqueAlt = predictedAlt D.setPrediction(predictedAlt) } else if PredictionModehasSLLConflictTerminatingPrediction(p.predictionMode, reach) { // MORE THAN ONE VIABLE ALTERNATIVE - D.configs.SetConflictingAlts(p.getConflictingAlts(reach)) + D.configs.conflictingAlts = p.getConflictingAlts(reach) D.requiresFullContext = true // in SLL-only mode, we will stop at p state and return the minimum alt D.isAcceptState = true - D.setPrediction(D.configs.GetConflictingAlts().minValue()) + D.setPrediction(D.configs.conflictingAlts.minValue()) } - if D.isAcceptState && D.configs.HasSemanticContext() { + if D.isAcceptState && D.configs.hasSemanticContext { p.predicateDFAState(D, p.atn.getDecisionState(dfa.decision)) if D.predicates != nil { D.setPrediction(ATNInvalidAltNumber) @@ -394,7 +393,7 @@ func (p *ParserATNSimulator) predicateDFAState(dfaState *DFAState, decisionState // comes back with reach.uniqueAlt set to a valid alt // //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 ATNConfigSet, input TokenStream, startIndex int, outerContext ParserRuleContext) (int, RecognitionException) { +func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 *ATNConfigSet, input TokenStream, startIndex int, outerContext ParserRuleContext) (int, RecognitionException) { if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("execATNWithFullContext " + s0.String()) @@ -402,7 +401,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT fullCtx := true foundExactAmbig := false - var reach ATNConfigSet + var reach *ATNConfigSet previous := s0 input.Seek(startIndex) t := input.LA(1) @@ -433,10 +432,10 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT strconv.Itoa(PredictionModegetUniqueAlt(altSubSets)) + ", resolvesToJustOneViableAlt=" + fmt.Sprint(PredictionModeresolvesToJustOneViableAlt(altSubSets))) } - reach.SetUniqueAlt(p.getUniqueAlt(reach)) + reach.uniqueAlt = p.getUniqueAlt(reach) // unique prediction? - if reach.GetUniqueAlt() != ATNInvalidAltNumber { - predictedAlt = reach.GetUniqueAlt() + if reach.uniqueAlt != ATNInvalidAltNumber { + predictedAlt = reach.uniqueAlt break } if p.predictionMode != PredictionModeLLExactAmbigDetection { @@ -465,7 +464,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT // If the configuration set uniquely predicts an alternative, // without conflict, then we know that it's a full LL decision // not SLL. - if reach.GetUniqueAlt() != ATNInvalidAltNumber { + if reach.uniqueAlt != ATNInvalidAltNumber { p.ReportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.Index()) return predictedAlt, nil } @@ -502,11 +501,11 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCtx bool) ATNConfigSet { +func (p *ParserATNSimulator) computeReachSet(closure *ATNConfigSet, t int, fullCtx bool) *ATNConfigSet { if p.mergeCache == nil { - p.mergeCache = NewDoubleDict() + p.mergeCache = NewJPCMap() } - intermediate := NewBaseATNConfigSet(fullCtx) + intermediate := NewATNConfigSet(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 @@ -518,17 +517,17 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // ensure that the alternative Matching the longest overall sequence is // chosen when multiple such configurations can Match the input. - var skippedStopStates []*BaseATNConfig + var skippedStopStates []*ATNConfig // First figure out where we can reach on input t - for _, c := range closure.GetItems() { + for _, c := range closure.configs { 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)) + skippedStopStates = append(skippedStopStates, c) if ParserATNSimulatorDebug { fmt.Println("added " + c.String() + " to SkippedStopStates") } @@ -539,7 +538,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt for _, trans := range c.GetState().GetTransitions() { target := p.getReachableTarget(trans, t) if target != nil { - cfg := NewBaseATNConfig4(c, target) + cfg := NewATNConfig4(c, target) intermediate.Add(cfg, p.mergeCache) if ParserATNSimulatorDebug { fmt.Println("added " + cfg.String() + " to intermediate") @@ -549,7 +548,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt } // Now figure out where the reach operation can take us... - var reach ATNConfigSet + var reach *ATNConfigSet // This block optimizes the reach operation for intermediate sets which // trivially indicate a termination state for the overall @@ -577,8 +576,8 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // operation on the intermediate set to compute its initial value. // if reach == nil { - reach = NewBaseATNConfigSet(fullCtx) - closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) + reach = NewATNConfigSet(fullCtx) + closureBusy := NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfEqInst) treatEOFAsEpsilon := t == TokenEOF amount := len(intermediate.configs) for k := 0; k < amount; k++ { @@ -603,7 +602,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // already guaranteed to meet this condition whether it's // required. // - reach = p.removeAllConfigsNotInRuleStopState(reach, reach == intermediate) + reach = p.removeAllConfigsNotInRuleStopState(reach, reach.Equals(intermediate)) } // If SkippedStopStates!=nil, then it contains at least one // configuration. For full-context reach operations, these @@ -623,7 +622,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt fmt.Println("computeReachSet " + closure.String() + " -> " + reach.String()) } - if len(reach.GetItems()) == 0 { + if len(reach.configs) == 0 { return nil } @@ -647,12 +646,12 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // The func returns configs if all configurations in configs are in a // rule stop state, otherwise it returns a new configuration set containing only // the configurations from configs which are in a rule stop state -func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfigSet, lookToEndOfRule bool) ATNConfigSet { +func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs *ATNConfigSet, lookToEndOfRule bool) *ATNConfigSet { if PredictionModeallConfigsInRuleStopStates(configs) { return configs } - result := NewBaseATNConfigSet(configs.FullContext()) - for _, config := range configs.GetItems() { + result := NewATNConfigSet(configs.fullCtx) + for _, config := range configs.configs { if _, ok := config.GetState().(*RuleStopState); ok { result.Add(config, p.mergeCache) continue @@ -661,7 +660,7 @@ func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfi NextTokens := p.atn.NextTokens(config.GetState(), nil) if NextTokens.contains(TokenEpsilon) { endOfRuleState := p.atn.ruleToStopState[config.GetState().GetRuleIndex()] - result.Add(NewBaseATNConfig4(config, endOfRuleState), p.mergeCache) + result.Add(NewATNConfig4(config, endOfRuleState), p.mergeCache) } } } @@ -669,10 +668,10 @@ func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfi } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, fullCtx bool) ATNConfigSet { +func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, fullCtx bool) *ATNConfigSet { // always at least the implicit call to start rule initialContext := predictionContextFromRuleContext(p.atn, ctx) - configs := NewBaseATNConfigSet(fullCtx) + configs := NewATNConfigSet(fullCtx) if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("computeStartState from ATN state " + a.String() + " initialContext=" + initialContext.String()) @@ -680,8 +679,8 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full for i := 0; i < len(a.GetTransitions()); i++ { target := a.GetTransitions()[i].getTarget() - c := NewBaseATNConfig6(target, i+1, initialContext) - closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst) + c := NewATNConfig6(target, i+1, initialContext) + closureBusy := NewJStore[*ATNConfig, Comparator[*ATNConfig]](atnConfCompInst) p.closure(c, configs, closureBusy, true, fullCtx, false) } return configs @@ -730,12 +729,12 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full // The func returns the transformed configuration set representing the start state // for a precedence [DFA] at a particular precedence level (determined by // calling [Parser].getPrecedence). -func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConfigSet { +func (p *ParserATNSimulator) applyPrecedenceFilter(configs *ATNConfigSet) *ATNConfigSet { statesFromAlt1 := make(map[int]*PredictionContext) - configSet := NewBaseATNConfigSet(configs.FullContext()) + configSet := NewATNConfigSet(configs.fullCtx) - for _, config := range configs.GetItems() { + for _, config := range configs.configs { // handle alt 1 first if config.GetAlt() != 1 { continue @@ -747,12 +746,12 @@ func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConf } statesFromAlt1[config.GetState().GetStateNumber()] = config.GetContext() if updatedContext != config.GetSemanticContext() { - configSet.Add(NewBaseATNConfig2(config, updatedContext), p.mergeCache) + configSet.Add(NewATNConfig2(config, updatedContext), p.mergeCache) } else { configSet.Add(config, p.mergeCache) } } - for _, config := range configs.GetItems() { + for _, config := range configs.configs { if config.GetAlt() == 1 { // already handled @@ -782,10 +781,10 @@ func (p *ParserATNSimulator) getReachableTarget(trans Transition, ttype int) ATN } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs ATNConfigSet, nalts int) []SemanticContext { +func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs *ATNConfigSet, nalts int) []SemanticContext { altToPred := make([]SemanticContext, nalts+1) - for _, c := range configs.GetItems() { + for _, c := range configs.configs { if ambigAlts.contains(c.GetAlt()) { altToPred[c.GetAlt()] = SemanticContextorContext(altToPred[c.GetAlt()], c.GetSemanticContext()) } @@ -863,7 +862,7 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre // Teh func returns the value to return from [AdaptivePredict], or // [ATNInvalidAltNumber] if a suitable alternative was not // identified and [AdaptivePredict] should report an error instead. -func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs ATNConfigSet, outerContext ParserRuleContext) int { +func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs *ATNConfigSet, outerContext ParserRuleContext) int { cfgs := p.splitAccordingToSemanticValidity(configs, outerContext) semValidConfigs := cfgs[0] semInvalidConfigs := cfgs[1] @@ -872,7 +871,7 @@ func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntry return alt } // Is there a syntactically valid path with a failed pred? - if len(semInvalidConfigs.GetItems()) > 0 { + if len(semInvalidConfigs.configs) > 0 { alt = p.GetAltThatFinishedDecisionEntryRule(semInvalidConfigs) if alt != ATNInvalidAltNumber { // syntactically viable path exists return alt @@ -881,10 +880,10 @@ func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntry return ATNInvalidAltNumber } -func (p *ParserATNSimulator) GetAltThatFinishedDecisionEntryRule(configs ATNConfigSet) int { +func (p *ParserATNSimulator) GetAltThatFinishedDecisionEntryRule(configs *ATNConfigSet) int { alts := NewIntervalSet() - for _, c := range configs.GetItems() { + for _, c := range configs.configs { _, ok := c.GetState().(*RuleStopState) if c.GetReachesIntoOuterContext() > 0 || (ok && c.GetContext().hasEmptyPath()) { @@ -908,14 +907,14 @@ func (p *ParserATNSimulator) GetAltThatFinishedDecisionEntryRule(configs ATNConf // prediction, which is where predicates need to evaluate. type ATNConfigSetPair struct { - item0, item1 ATNConfigSet + item0, item1 *ATNConfigSet } -func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigSet, outerContext ParserRuleContext) []ATNConfigSet { - succeeded := NewBaseATNConfigSet(configs.FullContext()) - failed := NewBaseATNConfigSet(configs.FullContext()) +func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs *ATNConfigSet, outerContext ParserRuleContext) []*ATNConfigSet { + succeeded := NewATNConfigSet(configs.fullCtx) + failed := NewATNConfigSet(configs.fullCtx) - for _, c := range configs.GetItems() { + for _, c := range configs.configs { if c.GetSemanticContext() != SemanticContextNone { predicateEvaluationResult := c.GetSemanticContext().evaluate(p.parser, outerContext) if predicateEvaluationResult { @@ -927,7 +926,7 @@ func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigS succeeded.Add(c, nil) } } - return []ATNConfigSet{succeeded, failed} + return []*ATNConfigSet{succeeded, failed} } // evalSemanticContext looks through a list of predicate/alt pairs, returning alts for the @@ -966,14 +965,14 @@ func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPredicti return predictions } -func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx, treatEOFAsEpsilon bool) { +func (p *ParserATNSimulator) closure(config *ATNConfig, configs *ATNConfigSet, closureBusy *JStore[*ATNConfig, Comparator[*ATNConfig]], collectPredicates, fullCtx, treatEOFAsEpsilon bool) { initialDepth := 0 p.closureCheckingStopState(config, configs, closureBusy, collectPredicates, fullCtx, initialDepth, treatEOFAsEpsilon) } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { +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() + ")") } @@ -985,7 +984,8 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs for i := 0; i < config.GetContext().length(); i++ { if config.GetContext().getReturnState(i) == BasePredictionContextEmptyReturnState { if fullCtx { - configs.Add(NewBaseATNConfig1(config, config.GetState(), BasePredictionContextEMPTY), p.mergeCache) + nb := NewATNConfig1(config, config.GetState(), BasePredictionContextEMPTY) + configs.Add(nb, p.mergeCache) continue } else { // we have no context info, just chase follow links (if greedy) @@ -999,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()) + c := NewATNConfig5(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. // Make sure we track that we are now out of context. @@ -1024,7 +1024,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs // Do the actual work of walking epsilon edges // //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { +func (p *ParserATNSimulator) closureWork(config *ATNConfig, configs *ATNConfigSet, closureBusy *JStore[*ATNConfig, Comparator[*ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { state := config.GetState() // optimization if !state.GetEpsilonOnlyTransitions() { @@ -1041,7 +1041,7 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, _, ok := t.(*ActionTransition) continueCollecting := collectPredicates && !ok c := p.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEOFAsEpsilon) - if ci, ok := c.(*BaseATNConfig); ok && ci != nil { + if c != nil { newDepth := depth if _, ok := config.GetState().(*RuleStopState); ok { @@ -1065,7 +1065,7 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, continue } - configs.SetDipsIntoOuterContext(true) // TODO: can remove? only care when we add to set per middle of this method + configs.dipsIntoOuterContext = true // TODO: can remove? only care when we add to set per middle of this method newDepth-- if ParserATNSimulatorDebug { fmt.Println("dips into outer ctx: " + c.String()) @@ -1092,7 +1092,7 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNConfig) bool { +func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config *ATNConfig) bool { if TurnOffLRLoopEntryBranchOpt { return false } @@ -1190,7 +1190,7 @@ func (p *ParserATNSimulator) getRuleName(index int) string { return sb.String() } -func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, collectPredicates, inContext, fullCtx, treatEOFAsEpsilon bool) ATNConfig { +func (p *ParserATNSimulator) getEpsilonTarget(config *ATNConfig, t Transition, collectPredicates, inContext, fullCtx, treatEOFAsEpsilon bool) *ATNConfig { switch t.getSerializationType() { case TransitionRULE: @@ -1202,13 +1202,13 @@ func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, co case TransitionACTION: return p.actionTransition(config, t.(*ActionTransition)) case TransitionEPSILON: - return NewBaseATNConfig4(config, t.getTarget()) + return NewATNConfig4(config, t.getTarget()) case TransitionATOM, TransitionRANGE, TransitionSET: // EOF transitions act like epsilon transitions after the first EOF // transition is traversed if treatEOFAsEpsilon { if t.Matches(TokenEOF, 0, 1) { - return NewBaseATNConfig4(config, t.getTarget()) + return NewATNConfig4(config, t.getTarget()) } } return nil @@ -1218,16 +1218,16 @@ func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, co } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) actionTransition(config ATNConfig, t *ActionTransition) *BaseATNConfig { +func (p *ParserATNSimulator) actionTransition(config *ATNConfig, t *ActionTransition) *ATNConfig { if ParserATNSimulatorDebug { fmt.Println("ACTION edge " + strconv.Itoa(t.ruleIndex) + ":" + strconv.Itoa(t.actionIndex)) } - return NewBaseATNConfig4(config, t.getTarget()) + return NewATNConfig4(config, t.getTarget()) } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, - pt *PrecedencePredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { +func (p *ParserATNSimulator) precedenceTransition(config *ATNConfig, + pt *PrecedencePredicateTransition, collectPredicates, inContext, fullCtx bool) *ATNConfig { if ParserATNSimulatorDebug { fmt.Println("PRED (collectPredicates=" + fmt.Sprint(collectPredicates) + ") " + @@ -1236,7 +1236,7 @@ func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, fmt.Println("context surrounding pred is " + fmt.Sprint(p.parser.GetRuleInvocationStack(nil))) } } - var c *BaseATNConfig + var c *ATNConfig if collectPredicates && inContext { if fullCtx { // In full context mode, we can evaluate predicates on-the-fly @@ -1248,14 +1248,14 @@ func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, predSucceeds := pt.getPredicate().evaluate(p.parser, p.outerContext) p.input.Seek(currentPosition) if predSucceeds { - c = NewBaseATNConfig4(config, pt.getTarget()) // no pred context + c = NewATNConfig4(config, pt.getTarget()) // no pred context } } else { newSemCtx := SemanticContextandContext(config.GetSemanticContext(), pt.getPredicate()) - c = NewBaseATNConfig3(config, pt.getTarget(), newSemCtx) + c = NewATNConfig3(config, pt.getTarget(), newSemCtx) } } else { - c = NewBaseATNConfig4(config, pt.getTarget()) + c = NewATNConfig4(config, pt.getTarget()) } if ParserATNSimulatorDebug { fmt.Println("config from pred transition=" + c.String()) @@ -1264,7 +1264,7 @@ func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { +func (p *ParserATNSimulator) predTransition(config *ATNConfig, pt *PredicateTransition, collectPredicates, inContext, fullCtx bool) *ATNConfig { if ParserATNSimulatorDebug { fmt.Println("PRED (collectPredicates=" + fmt.Sprint(collectPredicates) + ") " + strconv.Itoa(pt.ruleIndex) + @@ -1273,7 +1273,7 @@ func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTrans fmt.Println("context surrounding pred is " + fmt.Sprint(p.parser.GetRuleInvocationStack(nil))) } } - var c *BaseATNConfig + var c *ATNConfig if collectPredicates && (!pt.isCtxDependent || inContext) { if fullCtx { // In full context mode, we can evaluate predicates on-the-fly @@ -1285,14 +1285,14 @@ func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTrans predSucceeds := pt.getPredicate().evaluate(p.parser, p.outerContext) p.input.Seek(currentPosition) if predSucceeds { - c = NewBaseATNConfig4(config, pt.getTarget()) // no pred context + c = NewATNConfig4(config, pt.getTarget()) // no pred context } } else { newSemCtx := SemanticContextandContext(config.GetSemanticContext(), pt.getPredicate()) - c = NewBaseATNConfig3(config, pt.getTarget(), newSemCtx) + c = NewATNConfig3(config, pt.getTarget(), newSemCtx) } } else { - c = NewBaseATNConfig4(config, pt.getTarget()) + c = NewATNConfig4(config, pt.getTarget()) } if ParserATNSimulatorDebug { fmt.Println("config from pred transition=" + c.String()) @@ -1301,16 +1301,16 @@ func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTrans } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) ruleTransition(config ATNConfig, t *RuleTransition) *BaseATNConfig { +func (p *ParserATNSimulator) ruleTransition(config *ATNConfig, t *RuleTransition) *ATNConfig { if ParserATNSimulatorDebug { fmt.Println("CALL rule " + p.getRuleName(t.getTarget().GetRuleIndex()) + ", ctx=" + config.GetContext().String()) } returnState := t.followState newContext := SingletonBasePredictionContextCreate(config.GetContext(), returnState.GetStateNumber()) - return NewBaseATNConfig1(config, t.getTarget(), newContext) + return NewATNConfig1(config, t.getTarget(), newContext) } -func (p *ParserATNSimulator) getConflictingAlts(configs ATNConfigSet) *BitSet { +func (p *ParserATNSimulator) getConflictingAlts(configs *ATNConfigSet) *BitSet { altsets := PredictionModegetConflictingAltSubsets(configs) return PredictionModeGetAlts(altsets) } @@ -1364,13 +1364,13 @@ func (p *ParserATNSimulator) getConflictingAlts(configs ATNConfigSet) *BitSet { // looking for input reasonably, I don't declare the state done. We // ignore a set of conflicting alts when we have an alternative // that we still need to pursue. -func (p *ParserATNSimulator) getConflictingAltsOrUniqueAlt(configs ATNConfigSet) *BitSet { +func (p *ParserATNSimulator) getConflictingAltsOrUniqueAlt(configs *ATNConfigSet) *BitSet { var conflictingAlts *BitSet - if configs.GetUniqueAlt() != ATNInvalidAltNumber { + if configs.uniqueAlt != ATNInvalidAltNumber { conflictingAlts = NewBitSet() - conflictingAlts.add(configs.GetUniqueAlt()) + conflictingAlts.add(configs.uniqueAlt) } else { - conflictingAlts = configs.GetConflictingAlts() + conflictingAlts = configs.conflictingAlts } return conflictingAlts } @@ -1396,9 +1396,8 @@ func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string { } // Used for debugging in [AdaptivePredict] around [execATN], but I cut -// -// it out for clarity now that alg. works well. We can leave p -// "dead" code for a bit. +// it out for clarity now that alg. works well. We can leave this +// "dead" code for a bit. func (p *ParserATNSimulator) dumpDeadEndConfigs(_ *NoViableAltException) { panic("Not implemented") @@ -1429,13 +1428,13 @@ func (p *ParserATNSimulator) dumpDeadEndConfigs(_ *NoViableAltException) { // } } -func (p *ParserATNSimulator) noViableAlt(input TokenStream, outerContext ParserRuleContext, configs ATNConfigSet, startIndex int) *NoViableAltException { +func (p *ParserATNSimulator) noViableAlt(input TokenStream, outerContext ParserRuleContext, configs *ATNConfigSet, startIndex int) *NoViableAltException { return NewNoViableAltException(p.parser, input, input.Get(startIndex), input.LT(1), configs, outerContext) } -func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int { +func (p *ParserATNSimulator) getUniqueAlt(configs *ATNConfigSet) int { alt := ATNInvalidAltNumber - for _, c := range configs.GetItems() { + for _, c := range configs.configs { if alt == ATNInvalidAltNumber { alt = c.GetAlt() // found first alt } else if c.GetAlt() != alt { @@ -1520,9 +1519,10 @@ func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState { // The state was not present, so update it with configs // d.stateNumber = dfa.states.Len() - if !d.configs.ReadOnly() { + if !d.configs.readOnly { d.configs.OptimizeConfigs(&p.BaseATNSimulator) - d.configs.SetReadOnly(true) + d.configs.readOnly = true + d.configs.configLookup = nil } dfa.states.Put(d) if ParserATNSimulatorTraceATNSim { @@ -1533,7 +1533,7 @@ func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState { } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) ReportAttemptingFullContext(dfa *DFA, conflictingAlts *BitSet, configs ATNConfigSet, startIndex, stopIndex int) { +func (p *ParserATNSimulator) ReportAttemptingFullContext(dfa *DFA, conflictingAlts *BitSet, configs *ATNConfigSet, startIndex, stopIndex int) { if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { interval := NewInterval(startIndex, stopIndex+1) fmt.Println("ReportAttemptingFullContext decision=" + strconv.Itoa(dfa.decision) + ":" + configs.String() + @@ -1545,7 +1545,7 @@ func (p *ParserATNSimulator) ReportAttemptingFullContext(dfa *DFA, conflictingAl } //goland:noinspection GoBoolExpressions -func (p *ParserATNSimulator) ReportContextSensitivity(dfa *DFA, prediction int, configs ATNConfigSet, startIndex, stopIndex int) { +func (p *ParserATNSimulator) ReportContextSensitivity(dfa *DFA, prediction int, configs *ATNConfigSet, startIndex, stopIndex int) { if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { interval := NewInterval(startIndex, stopIndex+1) fmt.Println("ReportContextSensitivity decision=" + strconv.Itoa(dfa.decision) + ":" + configs.String() + @@ -1563,7 +1563,7 @@ func (p *ParserATNSimulator) ReportContextSensitivity(dfa *DFA, prediction int, // //goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) ReportAmbiguity(dfa *DFA, _ *DFAState, startIndex, stopIndex int, - exact bool, ambigAlts *BitSet, configs ATNConfigSet) { + exact bool, ambigAlts *BitSet, configs *ATNConfigSet) { if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { interval := NewInterval(startIndex, stopIndex+1) fmt.Println("ReportAmbiguity " + ambigAlts.String() + ":" + configs.String() + diff --git a/runtime/Go/antlr/v4/prediction_context.go b/runtime/Go/antlr/v4/prediction_context.go index 87f9e0bab9..5a6ae188c0 100644 --- a/runtime/Go/antlr/v4/prediction_context.go +++ b/runtime/Go/antlr/v4/prediction_context.go @@ -117,7 +117,8 @@ func (p *PredictionContext) Hash() int { func (p *PredictionContext) Equals(other Collectable[*PredictionContext]) bool { switch p.pcType { case PredictionContextEmpty: - return other == nil || other.(*PredictionContext).isEmpty() + otherP := other.(*PredictionContext) + return other == nil || otherP == nil || otherP.isEmpty() case PredictionContextSingleton: return p.SingletonEquals(other) case PredictionContextArray: @@ -131,7 +132,7 @@ func (p *PredictionContext) ArrayEquals(o Collectable[*PredictionContext]) bool return false } other := o.(*PredictionContext) - if other.pcType != PredictionContextArray { + if other == nil || other.pcType != PredictionContextArray { return false } if p.cachedHash != other.Hash() { @@ -151,6 +152,9 @@ func (p *PredictionContext) SingletonEquals(other Collectable[*PredictionContext return false } otherP := other.(*PredictionContext) + if otherP == nil { + return false + } if p.cachedHash != otherP.Hash() { return false // Can't be same if hash is different @@ -309,7 +313,7 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) *Predict return SingletonBasePredictionContextCreate(parent, transition.(*RuleTransition).followState.GetStateNumber()) } -func merge(a, b *PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) *PredictionContext { +func merge(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *PredictionContext { // Share same graph if both same // @@ -380,22 +384,22 @@ func convertToArray(pc *PredictionContext) *PredictionContext { // otherwise false to indicate a full-context merge // @param mergeCache // / -func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) *PredictionContext { +func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *PredictionContext { if mergeCache != nil { - previous := mergeCache.Get(a.Hash(), b.Hash()) - if previous != nil { - return previous.(*PredictionContext) + previous, present := mergeCache.Get(a, b) + if present { + return previous } - previous = mergeCache.Get(b.Hash(), a.Hash()) + previous, present = mergeCache.Get(b, a) if previous != nil { - return previous.(*PredictionContext) + return previous } } rootMerge := mergeRoot(a, b, rootIsWildcard) if rootMerge != nil { if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), rootMerge) + mergeCache.Put(a, b, rootMerge) } return rootMerge } @@ -415,7 +419,7 @@ func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *D // New joined parent so create a new singleton pointing to it, a' spc := SingletonBasePredictionContextCreate(parent, a.returnState) if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), spc) + mergeCache.Put(a, b, spc) } return spc } @@ -437,7 +441,7 @@ func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *D parents := []*PredictionContext{singleParent, singleParent} apc := NewArrayPredictionContext(parents, payloads) if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), apc) + mergeCache.Put(a, b, apc) } return apc } @@ -453,7 +457,7 @@ func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *D } apc := NewArrayPredictionContext(parents, payloads) if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), apc) + mergeCache.Put(a, b, apc) } return apc } @@ -539,21 +543,21 @@ func mergeRoot(a, b *PredictionContext, rootIsWildcard bool) *PredictionContext //

// //goland:noinspection GoBoolExpressions -func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) *PredictionContext { +func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *PredictionContext { if mergeCache != nil { - previous := mergeCache.Get(a.Hash(), b.Hash()) - if previous != nil { + previous, present := mergeCache.Get(a, b) + if present { if ParserATNSimulatorTraceATNSim { fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous") } - return previous.(*PredictionContext) + return previous } - previous = mergeCache.Get(b.Hash(), a.Hash()) - if previous != nil { + previous, present = mergeCache.Get(b, a) + if present { if ParserATNSimulatorTraceATNSim { fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous") } - return previous.(*PredictionContext) + return previous } } // merge sorted payloads a + b => M @@ -615,7 +619,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *Doubl if k == 1 { // for just one merged element, return singleton top pc := SingletonBasePredictionContextCreate(mergedParents[0], mergedReturnStates[0]) if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), pc) + mergeCache.Put(a, b, pc) } return pc } @@ -629,7 +633,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *Doubl // TODO: JI track whether this is possible above during merge sort for speed and possibly avoid an allocation if M.Equals(a) { if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), a) + mergeCache.Put(a, b, a) } if ParserATNSimulatorTraceATNSim { fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> a") @@ -638,7 +642,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *Doubl } if M.Equals(b) { if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), b) + mergeCache.Put(a, b, b) } if ParserATNSimulatorTraceATNSim { fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> b") @@ -648,7 +652,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *Doubl combineCommonParents(mergedParents) if mergeCache != nil { - mergeCache.set(a.Hash(), b.Hash(), M) + mergeCache.Put(a, b, M) } if ParserATNSimulatorTraceATNSim { fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> " + M.String()) @@ -673,8 +677,7 @@ func combineCommonParents(parents []*PredictionContext) { } } -func getCachedBasePredictionContext(context *PredictionContext, contextCache *PredictionContextCache, visited *JStore[*PredictionContext, Comparator[*PredictionContext]]) *PredictionContext { - +func getCachedBasePredictionContext(context *PredictionContext, contextCache *PredictionContextCache, visited *JMap[*PredictionContext, *PredictionContext, Comparator[*PredictionContext]]) *PredictionContext { if context.isEmpty() { return context } @@ -684,7 +687,7 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr } existing, present = contextCache.Get(context) if present { - _, _ = visited.Put(existing) + visited.Put(context, existing) return existing } changed := false @@ -704,7 +707,7 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr } if !changed { contextCache.add(context) - _, _ = visited.Put(context) + visited.Put(context, context) return context } var updated *PredictionContext @@ -716,8 +719,8 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr updated = NewArrayPredictionContext(parents, context.GetReturnStates()) } contextCache.add(updated) - visited.Put(updated) - visited.Put(context) + visited.Put(updated, updated) + visited.Put(context, updated) return updated } diff --git a/runtime/Go/antlr/v4/prediction_context_cache.go b/runtime/Go/antlr/v4/prediction_context_cache.go index 2e4390acf6..4b5e34f0e3 100644 --- a/runtime/Go/antlr/v4/prediction_context_cache.go +++ b/runtime/Go/antlr/v4/prediction_context_cache.go @@ -6,12 +6,12 @@ var BasePredictionContextEMPTY = NewEmptyPredictionContext() // context cash associated with contexts in DFA states. This cache // can be used for both lexers and parsers. type PredictionContextCache struct { - cache *JStore[*PredictionContext, Comparator[*PredictionContext]] + cache *JMap[*PredictionContext, *PredictionContext, Comparator[*PredictionContext]] } func NewPredictionContextCache() *PredictionContextCache { return &PredictionContextCache{ - cache: NewJStore[*PredictionContext, Comparator[*PredictionContext]](pContextEqInst), + cache: NewJMap[*PredictionContext, *PredictionContext, Comparator[*PredictionContext]](pContextEqInst), } } @@ -26,8 +26,12 @@ func (p *PredictionContextCache) add(ctx *PredictionContext) *PredictionContext // Put will return the existing entry if it is present (note this is done via Equals, not whether it is // the same pointer), otherwise it will add the new entry and return that. // - pc, _ := p.cache.Put(ctx) - return pc + existing, present := p.cache.Get(ctx) + if present { + return existing + } + p.cache.Put(ctx, ctx) + return ctx } func (p *PredictionContextCache) Get(ctx *PredictionContext) (*PredictionContext, bool) { diff --git a/runtime/Go/antlr/v4/prediction_mode.go b/runtime/Go/antlr/v4/prediction_mode.go index 625ad2974a..deb675b43d 100644 --- a/runtime/Go/antlr/v4/prediction_mode.go +++ b/runtime/Go/antlr/v4/prediction_mode.go @@ -29,7 +29,7 @@ const ( // behavior for syntactically-incorrect inputs. // PredictionModeSLL = 0 - + // PredictionModeLL represents the LL(*) prediction mode. // This prediction mode allows the current parser // context to be used for resolving SLL conflicts that occur during @@ -47,7 +47,7 @@ const ( // behavior for syntactically-incorrect inputs. // PredictionModeLL = 1 - + // PredictionModeLLExactAmbigDetection represents the LL(*) prediction mode // with exact ambiguity detection. // @@ -165,8 +165,8 @@ const ( // [ATNConfigSet.hasSemanticContext]), this algorithm makes a copy of // the configurations to strip out all the predicates so that a standard // [ATNConfigSet] will merge everything ignoring predicates. -func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConfigSet) bool { - +func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs *ATNConfigSet) bool { + // Configs in rule stop states indicate reaching the end of the decision // rule (local context) or end of start rule (full context). If all // configs meet this condition, then none of the configurations is able @@ -175,19 +175,19 @@ func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConf if PredictionModeallConfigsInRuleStopStates(configs) { return true } - + // pure SLL mode parsing if mode == PredictionModeSLL { // Don't bother with combining configs from different semantic // contexts if we can fail over to full LL costs more time // since we'll often fail over anyway. - if configs.HasSemanticContext() { + if configs.hasSemanticContext { // dup configs, tossing out semantic predicates - dup := NewBaseATNConfigSet(false) - for _, c := range configs.GetItems() { - - // NewBaseATNConfig({semanticContext:}, c) - c = NewBaseATNConfig2(c, SemanticContextNone) + dup := NewATNConfigSet(false) + for _, c := range configs.configs { + + // NewATNConfig({semanticContext:}, c) + c = NewATNConfig2(c, SemanticContextNone) dup.Add(c, nil) } configs = dup @@ -205,8 +205,8 @@ func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConf // context). // // The func returns true if any configuration in the supplied configs is in a [RuleStopState] -func PredictionModehasConfigInRuleStopState(configs ATNConfigSet) bool { - for _, c := range configs.GetItems() { +func PredictionModehasConfigInRuleStopState(configs *ATNConfigSet) bool { + for _, c := range configs.configs { if _, ok := c.GetState().(*RuleStopState); ok { return true } @@ -221,9 +221,9 @@ func PredictionModehasConfigInRuleStopState(configs ATNConfigSet) bool { // // the func returns true if all configurations in configs are in a // [RuleStopState] -func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { - - for _, c := range configs.GetItems() { +func PredictionModeallConfigsInRuleStopStates(configs *ATNConfigSet) bool { + + for _, c := range configs.configs { if _, ok := c.GetState().(*RuleStopState); !ok { return false } @@ -430,7 +430,7 @@ func PredictionModehasConflictingAltSet(altsets []*BitSet) bool { // The func returns true if every member of altsets is equal to the others. func PredictionModeallSubsetsEqual(altsets []*BitSet) bool { var first *BitSet - + for i := 0; i < len(altsets); i++ { alts := altsets[i] if first == nil { @@ -439,7 +439,7 @@ func PredictionModeallSubsetsEqual(altsets []*BitSet) bool { return false } } - + return true } @@ -453,7 +453,7 @@ func PredictionModegetUniqueAlt(altsets []*BitSet) int { if all.length() == 1 { return all.minValue() } - + return ATNInvalidAltNumber } @@ -472,11 +472,11 @@ func PredictionModeGetAlts(altsets []*BitSet) *BitSet { // // for each configuration c in configs: // map[c] U= c.ATNConfig.alt // map hash/equals uses s and x, not alt and not pred -func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet { - configToAlts := NewJMap[ATNConfig, *BitSet, *ATNAltConfigComparator[ATNConfig]](atnAltCfgEqInst) - - for _, c := range configs.GetItems() { - +func PredictionModegetConflictingAltSubsets(configs *ATNConfigSet) []*BitSet { + configToAlts := NewJMap[*ATNConfig, *BitSet, *ATNAltConfigComparator[*ATNConfig]](atnAltCfgEqInst) + + for _, c := range configs.configs { + alts, ok := configToAlts.Get(c) if !ok { alts = NewBitSet() @@ -484,7 +484,7 @@ func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet { } alts.add(c.GetAlt()) } - + return configToAlts.Values() } @@ -492,10 +492,10 @@ func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet { // // for each configuration c in configs: // map[c.ATNConfig.state] U= c.ATNConfig.alt} -func PredictionModeGetStateToAltMap(configs ATNConfigSet) *AltDict { +func PredictionModeGetStateToAltMap(configs *ATNConfigSet) *AltDict { m := NewAltDict() - - for _, c := range configs.GetItems() { + + for _, c := range configs.configs { alts := m.Get(c.GetState().String()) if alts == nil { alts = NewBitSet() @@ -506,7 +506,7 @@ func PredictionModeGetStateToAltMap(configs ATNConfigSet) *AltDict { return m } -func PredictionModehasStateAssociatedWithOneAlt(configs ATNConfigSet) bool { +func PredictionModehasStateAssociatedWithOneAlt(configs *ATNConfigSet) bool { values := PredictionModeGetStateToAltMap(configs).values() for i := 0; i < len(values); i++ { if values[i].(*BitSet).length() == 1 { @@ -522,7 +522,7 @@ func PredictionModehasStateAssociatedWithOneAlt(configs ATNConfigSet) bool { // TODO: JI - Review this code - it does not seem to do the same thing as the Java code - maybe because [BitSet] is not like the Java utils BitSet func PredictionModegetSingleViableAlt(altsets []*BitSet) int { result := ATNInvalidAltNumber - + for i := 0; i < len(altsets); i++ { alts := altsets[i] minAlt := alts.minValue() diff --git a/runtime/Go/antlr/v4/testing_util_test.go b/runtime/Go/antlr/v4/testing_util_test.go index a0fbd0f164..dd73703220 100644 --- a/runtime/Go/antlr/v4/testing_util_test.go +++ b/runtime/Go/antlr/v4/testing_util_test.go @@ -9,7 +9,6 @@ import ( // notice: test purpose only func newTestCommonToken(tokenType int, text string, channel int) *CommonToken { t := new(CommonToken) - t.BaseToken = new(BaseToken) t.tokenType = tokenType t.channel = channel t.text = text @@ -25,6 +24,6 @@ func tokensToString(tokens []Token) string { for i, token := range tokens { buf[i] = fmt.Sprintf("%v", token) } - + return "[" + strings.Join(buf, ", ") + "]" } diff --git a/runtime/Go/antlr/v4/utils.go b/runtime/Go/antlr/v4/utils.go index 900e0449aa..23e4e45210 100644 --- a/runtime/Go/antlr/v4/utils.go +++ b/runtime/Go/antlr/v4/utils.go @@ -48,7 +48,7 @@ func (s *IntStack) Push(e int) { } func standardEqualsFunction(a Collectable[any], b Collectable[any]) bool { - + return a.Equals(b) } @@ -56,7 +56,6 @@ func standardHashFunction(a interface{}) int { if h, ok := a.(hasher); ok { return h.Hash() } - panic("Not 'Hasher'") } @@ -160,27 +159,27 @@ func (b *BitSet) equals(other interface{}) bool { if !ok { return false } - + if b == otherBitSet { return true } - + // We only compare set bits, so we cannot rely on the two slices having the same size. Its // possible for two BitSets to have different slice lengths but the same set bits. So we only // compare the relevant words and ignore the trailing zeros. bLen := b.minLen() otherLen := otherBitSet.minLen() - + if bLen != otherLen { return false } - + for i := 0; i < bLen; i++ { if b.data[i] != otherBitSet.data[i] { return false } } - + return true } @@ -203,7 +202,7 @@ func (b *BitSet) length() int { func (b *BitSet) String() string { vals := make([]string, 0, b.length()) - + for i, v := range b.data { for v != 0 { n := bits.TrailingZeros64(v) @@ -211,7 +210,7 @@ func (b *BitSet) String() string { v &= ^(uint64(1) << n) } } - + return "{" + strings.Join(vals, ", ") + "}" } @@ -245,39 +244,8 @@ func (a *AltDict) values() []interface{} { return vs } -type DoubleDict struct { - data map[int]map[int]interface{} -} - -func NewDoubleDict() *DoubleDict { - dd := new(DoubleDict) - dd.data = make(map[int]map[int]interface{}) - return dd -} - -func (d *DoubleDict) Get(a, b int) interface{} { - data := d.data[a] - - if data == nil { - return nil - } - - return data[b] -} - -func (d *DoubleDict) set(a, b int, o interface{}) { - data := d.data[a] - - if data == nil { - data = make(map[int]interface{}) - d.data[a] = data - } - - data[b] = o -} - func EscapeWhitespace(s string, escapeSpaces bool) string { - + s = strings.Replace(s, "\t", "\\t", -1) s = strings.Replace(s, "\n", "\\n", -1) s = strings.Replace(s, "\r", "\\r", -1) @@ -290,29 +258,29 @@ func EscapeWhitespace(s string, escapeSpaces bool) string { //goland:noinspection GoUnusedExportedFunction func TerminalNodeToStringArray(sa []TerminalNode) []string { st := make([]string, len(sa)) - + for i, s := range sa { st[i] = fmt.Sprintf("%v", s) } - + return st } //goland:noinspection GoUnusedExportedFunction func PrintArrayJavaStyle(sa []string) string { var buffer bytes.Buffer - + buffer.WriteString("[") - + for i, s := range sa { buffer.WriteString(s) if i != len(sa)-1 { buffer.WriteString(", ") } } - + buffer.WriteString("]") - + return buffer.String() } @@ -328,12 +296,12 @@ func murmurUpdate(h int, value int) int { const r2 uint32 = 13 const m uint32 = 5 const n uint32 = 0xE6546B64 - + k := uint32(value) k *= c1 k = (k << r1) | (k >> (32 - r1)) k *= c2 - + hash := uint32(h) ^ k hash = (hash << r2) | (hash >> (32 - r2)) hash = hash*m + n @@ -348,6 +316,6 @@ func murmurFinish(h int, numberOfWords int) int { hash ^= hash >> 13 hash *= 0xc2b2ae35 hash ^= hash >> 16 - + return int(hash) }