Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions runtime/Go/antlr/v4/array_prediction_context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package antlr

import (
"golang.org/x/exp/slices"
"strconv"
)

type ArrayPredictionContext struct {
BasePredictionContext
parents []PredictionContext
returnStates []int
}

func NewArrayPredictionContext(parents []PredictionContext, returnStates []int) *ArrayPredictionContext {
// Parent can be nil only if full ctx mode and we make an array
// from {@link //EMPTY} and non-empty. We merge {@link //EMPTY} by using
// nil parent and
// returnState == {@link //EmptyReturnState}.
hash := murmurInit(1)
for _, parent := range parents {
hash = murmurUpdate(hash, parent.Hash())
}
for _, returnState := range returnStates {
hash = murmurUpdate(hash, returnState)
}
hash = murmurFinish(hash, len(parents)<<1)

return &ArrayPredictionContext{
BasePredictionContext: BasePredictionContext{
cachedHash: hash,
pcType: PredictionContextArray,
},
parents: parents,
returnStates: returnStates,
}
}

func (a *ArrayPredictionContext) GetReturnStates() []int {
return a.returnStates
}

func (a *ArrayPredictionContext) hasEmptyPath() bool {
return a.getReturnState(a.length()-1) == BasePredictionContextEmptyReturnState
}

func (a *ArrayPredictionContext) isEmpty() bool {
// since EmptyReturnState can only appear in the last position, we
// don't need to verify that size==1
return a.returnStates[0] == BasePredictionContextEmptyReturnState
}

func (a *ArrayPredictionContext) length() int {
return len(a.returnStates)
}

func (a *ArrayPredictionContext) GetParent(index int) PredictionContext {
return a.parents[index]
}

func (a *ArrayPredictionContext) getReturnState(index int) int {
return a.returnStates[index]
}

// Equals is the default comparison function for ArrayPredictionContext when no specialized
// implementation is needed for a collection
func (a *ArrayPredictionContext) Equals(o interface{}) bool {
if a == o {
return true
}
other, ok := o.(*ArrayPredictionContext)
if !ok {
return false
}
if a.cachedHash != other.Hash() {
return false // can't be same if hash is different
}

// Must compare the actual array elements and not just the array address
//
return slices.Equal(a.returnStates, other.returnStates) &&
slices.EqualFunc(a.parents, other.parents, func(x, y PredictionContext) bool {
return x.Equals(y)
})
}

// Hash is the default hash function for ArrayPredictionContext when no specialized
// implementation is needed for a collection
func (a *ArrayPredictionContext) Hash() int {
return a.BasePredictionContext.cachedHash
}

func (a *ArrayPredictionContext) String() string {
if a.isEmpty() {
return "[]"
}

s := "["
for i := 0; i < len(a.returnStates); i++ {
if i > 0 {
s = s + ", "
}
if a.returnStates[i] == BasePredictionContextEmptyReturnState {
s = s + "$"
continue
}
s = s + strconv.Itoa(a.returnStates[i])
if a.parents[i] != nil {
s = s + " " + a.parents[i].String()
} else {
s = s + "nil"
}
}

return s + "]"
}
71 changes: 51 additions & 20 deletions runtime/Go/antlr/v4/atn_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,23 @@ func NewBaseATNConfig1(c ATNConfig, state ATNState, context PredictionContext) *
// are just wrappers around this one.
func NewBaseATNConfig(c ATNConfig, state ATNState, context PredictionContext, semanticContext SemanticContext) *BaseATNConfig {
if semanticContext == nil {
panic("semanticContext cannot be nil")
panic("semanticContext cannot be nil") // TODO: Remove this - probably put here for some bug that is now fixed
}

return &BaseATNConfig{
state: state,
alt: c.GetAlt(),
context: context,
semanticContext: semanticContext,
reachesIntoOuterContext: c.GetReachesIntoOuterContext(),
precedenceFilterSuppressed: c.getPrecedenceFilterSuppressed(),
}
b := &BaseATNConfig{}
b.InitBaseATNConfig(c, state, c.GetAlt(), context, semanticContext)

return b
}

func (b *BaseATNConfig) InitBaseATNConfig(c ATNConfig, state ATNState, alt int, context PredictionContext, semanticContext SemanticContext) {

b.state = state
b.alt = alt
b.context = context
b.semanticContext = semanticContext
b.reachesIntoOuterContext = c.GetReachesIntoOuterContext()
b.precedenceFilterSuppressed = c.getPrecedenceFilterSuppressed()
}

func (b *BaseATNConfig) getPrecedenceFilterSuppressed() bool {
Expand Down Expand Up @@ -237,49 +243,74 @@ func (b *BaseATNConfig) String() string {
// BaseATNConfig struct.
// TODO: Stop using a pointer and embed the struct instead as this saves allocations. Same for the LexerATNConfig "constructors"
type LexerATNConfig struct {
*BaseATNConfig
BaseATNConfig
lexerActionExecutor *LexerActionExecutor
passedThroughNonGreedyDecision bool
}

func NewLexerATNConfig6(state ATNState, alt int, context PredictionContext) *LexerATNConfig {
return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)}

return &LexerATNConfig{
BaseATNConfig: BaseATNConfig{
state: state,
alt: alt,
context: context,
semanticContext: SemanticContextNone,
},
}
}

func NewLexerATNConfig5(state ATNState, alt int, context PredictionContext, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig {
return &LexerATNConfig{
BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone),
BaseATNConfig: BaseATNConfig{
state: state,
alt: alt,
context: context,
semanticContext: SemanticContextNone,
},
lexerActionExecutor: lexerActionExecutor,
}
}

func NewLexerATNConfig4(c *LexerATNConfig, state ATNState) *LexerATNConfig {
return &LexerATNConfig{
BaseATNConfig: NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()),
lac := &LexerATNConfig{

lexerActionExecutor: c.lexerActionExecutor,
passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state),
}
lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext())
return lac
}

func NewLexerATNConfig3(c *LexerATNConfig, state ATNState, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig {
return &LexerATNConfig{
BaseATNConfig: NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()),
lac := &LexerATNConfig{
lexerActionExecutor: lexerActionExecutor,
passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state),
}
lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext())
return lac
}

func NewLexerATNConfig2(c *LexerATNConfig, state ATNState, context PredictionContext) *LexerATNConfig {
return &LexerATNConfig{
BaseATNConfig: NewBaseATNConfig(c, state, context, c.GetSemanticContext()),
lac := &LexerATNConfig{
lexerActionExecutor: c.lexerActionExecutor,
passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state),
}
lac.BaseATNConfig.InitBaseATNConfig(c, state, c.GetAlt(), context, c.GetSemanticContext())
return lac
}

//goland:noinspection GoUnusedExportedFunction
func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *LexerATNConfig {
return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)}
lac := &LexerATNConfig{
BaseATNConfig: BaseATNConfig{
state: state,
alt: alt,
context: context,
semanticContext: SemanticContextNone,
},
}
return lac
}

// Hash is the default hash function for LexerATNConfig objects, it can be used directly or via
Expand Down Expand Up @@ -330,7 +361,7 @@ func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool {
return false
}

return l.BaseATNConfig.Equals(otherT.BaseATNConfig)
return l.BaseATNConfig.Equals(&otherT.BaseATNConfig)
}

func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool {
Expand Down
Loading