summaryrefslogtreecommitdiff
path: root/vendor/github.com/antlr4-go/antlr/v4/atn_config.go
blob: a83f25d3492e6b3e8d15a6af54e009944f03585a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.

package antlr

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 struct {
	precedenceFilterSuppressed     bool
	state                          ATNState
	alt                            int
	context                        *PredictionContext
	semanticContext                SemanticContext
	reachesIntoOuterContext        int
	cType                          int // lexerConfig or parserConfig
	lexerActionExecutor            *LexerActionExecutor
	passedThroughNonGreedyDecision bool
}

// 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)
}

// 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?
	}

	pac := &ATNConfig{}
	pac.state = state
	pac.alt = alt
	pac.context = context
	pac.semanticContext = semanticContext
	pac.cType = parserConfig
	return pac
}

// 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())
}

// 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)
}

// 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)
}

// 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())
}

// 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 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 := &ATNConfig{}
	b.InitATNConfig(c, state, c.GetAlt(), context, semanticContext)
	b.cType = parserConfig
	return b
}

func (a *ATNConfig) InitATNConfig(c *ATNConfig, state ATNState, alt int, context *PredictionContext, semanticContext SemanticContext) {

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

func (a *ATNConfig) getPrecedenceFilterSuppressed() bool {
	return a.precedenceFilterSuppressed
}

func (a *ATNConfig) setPrecedenceFilterSuppressed(v bool) {
	a.precedenceFilterSuppressed = v
}

// GetState returns the ATN state associated with this configuration
func (a *ATNConfig) GetState() ATNState {
	return a.state
}

// GetAlt returns the alternative associated with this configuration
func (a *ATNConfig) GetAlt() int {
	return a.alt
}

// SetContext sets the rule invocation stack associated with this configuration
func (a *ATNConfig) SetContext(v *PredictionContext) {
	a.context = v
}

// GetContext returns the rule invocation stack associated with this configuration
func (a *ATNConfig) GetContext() *PredictionContext {
	return a.context
}

// GetSemanticContext returns the semantic context associated with this configuration
func (a *ATNConfig) GetSemanticContext() SemanticContext {
	return a.semanticContext
}

// GetReachesIntoOuterContext returns the count of references to an outer context from this configuration
func (a *ATNConfig) GetReachesIntoOuterContext() int {
	return a.reachesIntoOuterContext
}

// SetReachesIntoOuterContext sets the count of references to an outer context from this configuration
func (a *ATNConfig) SetReachesIntoOuterContext(v int) {
	a.reachesIntoOuterContext = v
}

// Equals is the default comparison function for an 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) 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")
	}
}

// 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 a.context == nil {
		equal = other.context == nil
	} else {
		equal = a.context.Equals(other.context)
	}

	var (
		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 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 (a *ATNConfig) PHash() int {
	var c int
	if a.context != nil {
		c = a.context.Hash()
	}

	h := murmurInit(7)
	h = murmurUpdate(h, a.state.GetStateNumber())
	h = murmurUpdate(h, a.alt)
	h = murmurUpdate(h, c)
	h = murmurUpdate(h, a.semanticContext.Hash())
	return murmurFinish(h, 4)
}

// String returns a string representation of the ATNConfig, usually used for debugging purposes
func (a *ATNConfig) String() string {
	var s1, s2, s3 string

	if a.context != nil {
		s1 = ",[" + fmt.Sprint(a.context) + "]"
	}

	if a.semanticContext != SemanticContextNone {
		s2 = "," + fmt.Sprint(a.semanticContext)
	}

	if a.reachesIntoOuterContext > 0 {
		s3 = ",up=" + fmt.Sprint(a.reachesIntoOuterContext)
	}

	return fmt.Sprintf("(%v,%v%v%v%v)", a.state, a.alt, s1, s2, s3)
}

func NewLexerATNConfig6(state ATNState, alt int, context *PredictionContext) *ATNConfig {
	lac := &ATNConfig{}
	lac.state = state
	lac.alt = alt
	lac.context = context
	lac.semanticContext = SemanticContextNone
	lac.cType = lexerConfig
	return lac
}

func NewLexerATNConfig4(c *ATNConfig, state ATNState) *ATNConfig {
	lac := &ATNConfig{}
	lac.lexerActionExecutor = c.lexerActionExecutor
	lac.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state)
	lac.InitATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext())
	lac.cType = lexerConfig
	return lac
}

func NewLexerATNConfig3(c *ATNConfig, state ATNState, lexerActionExecutor *LexerActionExecutor) *ATNConfig {
	lac := &ATNConfig{}
	lac.lexerActionExecutor = lexerActionExecutor
	lac.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state)
	lac.InitATNConfig(c, state, c.GetAlt(), c.GetContext(), c.GetSemanticContext())
	lac.cType = lexerConfig
	return lac
}

func NewLexerATNConfig2(c *ATNConfig, state ATNState, context *PredictionContext) *ATNConfig {
	lac := &ATNConfig{}
	lac.lexerActionExecutor = c.lexerActionExecutor
	lac.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state)
	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) *ATNConfig {
	lac := &ATNConfig{}
	lac.state = state
	lac.alt = alt
	lac.context = context
	lac.semanticContext = SemanticContextNone
	lac.cType = lexerConfig
	return lac
}

// LHash is the default hash function for Lexer ATNConfig objects, it can be used directly or via
// the default comparator [ObjEqComparator].
func (a *ATNConfig) LHash() int {
	var f int
	if a.passedThroughNonGreedyDecision {
		f = 1
	} else {
		f = 0
	}
	h := murmurInit(7)
	h = murmurUpdate(h, a.state.GetStateNumber())
	h = murmurUpdate(h, a.alt)
	h = murmurUpdate(h, a.context.Hash())
	h = murmurUpdate(h, a.semanticContext.Hash())
	h = murmurUpdate(h, f)
	h = murmurUpdate(h, a.lexerActionExecutor.Hash())
	h = murmurFinish(h, 6)
	return h
}

// LEquals is the default comparison function for Lexer ATNConfig objects, it can be used directly or via
// the default comparator [ObjEqComparator].
func (a *ATNConfig) LEquals(other Collectable[*ATNConfig]) bool {
	var otherT, ok = other.(*ATNConfig)
	if !ok {
		return false
	} else if a == otherT {
		return true
	} else if a.passedThroughNonGreedyDecision != otherT.passedThroughNonGreedyDecision {
		return false
	}

	switch {
	case a.lexerActionExecutor == nil && otherT.lexerActionExecutor == nil:
		return true
	case a.lexerActionExecutor != nil && otherT.lexerActionExecutor != nil:
		if !a.lexerActionExecutor.Equals(otherT.lexerActionExecutor) {
			return false
		}
	default:
		return false // One but not both, are nil
	}

	return a.PEquals(otherT)
}

func checkNonGreedyDecision(source *ATNConfig, target ATNState) bool {
	var ds, ok = target.(DecisionState)

	return source.passedThroughNonGreedyDecision || (ok && ds.getNonGreedy())
}