diff --git a/runtime/Go/antlr/v4/antlrdoc.go b/runtime/Go/antlr/v4/antlrdoc.go index ab51212676..61576b722f 100644 --- a/runtime/Go/antlr/v4/antlrdoc.go +++ b/runtime/Go/antlr/v4/antlrdoc.go @@ -8,6 +8,19 @@ or translating structured text or binary files. It's widely used to build langua From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface (or visitor) that makes it easy to respond to the recognition of phrases of interest. +# Go Runtime + +At version 4.11.x and prior, the Go runtime was not properly versioned for go modules. After this point, the runtime +source code is held in the `runtime/Go/antlr/v4` directory, and the go.mod file is updated to reflect the version of +ANTLR4 that it is compatible with (I.E. uses the /v4 path). The runtime is now available as a go module, and can be +imported as `github.com/antlr/antlr4/runtime/Go/antlr/v4` (the go get command should also be used with this path). See +the main documentation for the ANTLR4 project for more information. + +This means that if you are using the source code without modules, you should also use the source code in /v4. Though +we highly recommend that you use go modules, as they are now idiomatic Go. + +I am aware that this change will prove Hyrum's Law, but am prepared to live with it for teh common good. JI + # Code Generation ANTLR supports the generation of code in a number of [target languages], and the generated code is supported by a @@ -58,7 +71,7 @@ From the command line at the root of your package “myproject” you can then s # Copyright Notice -Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. +Copyright (c) 2012-2023 The ANTLR Project. All rights reserved. Use of this file is governed by the BSD 3-clause license, which can be found in the [LICENSE.txt] file in the project root. diff --git a/runtime/Go/antlr/v4/atn.go b/runtime/Go/antlr/v4/atn.go index 98010d2e6e..cdeefed247 100644 --- a/runtime/Go/antlr/v4/atn.go +++ b/runtime/Go/antlr/v4/atn.go @@ -20,10 +20,11 @@ var ATNInvalidAltNumber int // [ALL(*)]: https://www.antlr.org/papers/allstar-techreport.pdf // [Recursive Transition Network]: https://en.wikipedia.org/wiki/Recursive_transition_network type ATN struct { - // DecisionToState is the decision points for all rules, subrules, optional - // blocks, ()+, ()*, etc. Each subrule/rule is a decision point, and we must track them so we + + // DecisionToState is the decision points for all rules, sub-rules, optional + // blocks, ()+, ()*, etc. Each sub-rule/rule is a decision point, and we must track them, so we // can go back later and build DFA predictors for them. This includes - // all the rules, subrules, optional blocks, ()+, ()* etc... + // all the rules, sub-rules, optional blocks, ()+, ()* etc... DecisionToState []DecisionState // grammarType is the ATN type and is used for deserializing ATNs from strings. @@ -51,6 +52,8 @@ type ATN struct { // specified, and otherwise is nil. ruleToTokenType []int + // ATNStates is a list of all states in the ATN, ordered by state number. + // states []ATNState mu sync.Mutex diff --git a/runtime/Go/antlr/v4/atn_config.go b/runtime/Go/antlr/v4/atn_config.go index 7619fa172e..9bdc99fc87 100644 --- a/runtime/Go/antlr/v4/atn_config.go +++ b/runtime/Go/antlr/v4/atn_config.go @@ -10,29 +10,44 @@ import ( // 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 at the +// 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 @@ -42,7 +57,8 @@ type BaseATNConfig struct { reachesIntoOuterContext int } -func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup +//goland:noinspection GoUnusedExportedFunction +func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup - maybe delete this return &BaseATNConfig{ state: old.state, alt: old.alt, @@ -52,10 +68,12 @@ func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup } } +// 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) } +// 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 { if semanticContext == nil { panic("semanticContext cannot be nil") // TODO: Necessary? @@ -64,22 +82,28 @@ func NewBaseATNConfig5(state ATNState, alt int, context PredictionContext, seman return &BaseATNConfig{state: state, alt: alt, context: context, semanticContext: semanticContext} } +// 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()) } +// 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) } +// 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) } +// 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()) } +// NewBaseATNConfig creates a new BaseATNConfig 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 { if semanticContext == nil { panic("semanticContext cannot be nil") @@ -103,29 +127,37 @@ func (b *BaseATNConfig) setPrecedenceFilterSuppressed(v bool) { b.precedenceFilterSuppressed = v } +// GetState returns the ATN state associated with this configuration func (b *BaseATNConfig) GetState() ATNState { return b.state } +// GetAlt returns the alternative associated with this configuration func (b *BaseATNConfig) GetAlt() int { return b.alt } +// SetContext sets the rule invocation stack associated with this configuration func (b *BaseATNConfig) SetContext(v PredictionContext) { b.context = v } + +// GetContext returns the rule invocation stack associated with this configuration func (b *BaseATNConfig) GetContext() PredictionContext { return b.context } +// GetSemanticContext returns the semantic context associated with this configuration func (b *BaseATNConfig) GetSemanticContext() SemanticContext { return b.semanticContext } +// GetReachesIntoOuterContext returns the count of references to an outer context from this configuration func (b *BaseATNConfig) GetReachesIntoOuterContext() int { return b.reachesIntoOuterContext } +// SetReachesIntoOuterContext sets the count of references to an outer context from this configuration func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) { b.reachesIntoOuterContext = v } @@ -182,6 +214,7 @@ func (b *BaseATNConfig) Hash() int { return murmurFinish(h, 4) } +// String returns a string representation of the BaseATNConfig, usually used for debugging purposes func (b *BaseATNConfig) String() string { var s1, s2, s3 string @@ -200,6 +233,9 @@ func (b *BaseATNConfig) String() string { 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 @@ -241,6 +277,7 @@ func NewLexerATNConfig2(c *LexerATNConfig, state ATNState, context PredictionCon } } +//goland:noinspection GoUnusedExportedFunction func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *LexerATNConfig { return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)} } @@ -271,29 +308,29 @@ func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool { if l == other { return true } - var othert, ok = other.(*LexerATNConfig) + var otherT, ok = other.(*LexerATNConfig) if l == other { return true } else if !ok { return false - } else if l.passedThroughNonGreedyDecision != othert.passedThroughNonGreedyDecision { + } else if l.passedThroughNonGreedyDecision != otherT.passedThroughNonGreedyDecision { return false } var b bool if l.lexerActionExecutor != nil { - b = !l.lexerActionExecutor.Equals(othert.lexerActionExecutor) + b = !l.lexerActionExecutor.Equals(otherT.lexerActionExecutor) } else { - b = othert.lexerActionExecutor != nil + b = otherT.lexerActionExecutor != nil } if b { return false } - return l.BaseATNConfig.Equals(othert.BaseATNConfig) + return l.BaseATNConfig.Equals(otherT.BaseATNConfig) } func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool { diff --git a/runtime/Go/antlr/v4/atn_config_set.go b/runtime/Go/antlr/v4/atn_config_set.go index 43e9b33f3b..7331cbc8d7 100644 --- a/runtime/Go/antlr/v4/atn_config_set.go +++ b/runtime/Go/antlr/v4/atn_config_set.go @@ -51,6 +51,8 @@ type ATNConfigSet interface { // about its elements and can combine similar configurations using a // graph-structured stack. type BaseATNConfigSet struct { + + // TODO: Is this actually valid? JI cachedHash int // configLookup is used to determine whether two BaseATNConfigSets are equal. We @@ -64,7 +66,7 @@ type BaseATNConfigSet struct { configs []ATNConfig // TODO: These fields make me pretty uncomfortable, but it is nice to pack up - // info together because it saves recomputation. Can we track conflicts as they + // info together because it saves re-computation. Can we track conflicts as they // are added to save scanning configs later? conflictingAlts *BitSet @@ -79,7 +81,7 @@ type BaseATNConfigSet struct { fullCtx bool // Used in parser and lexer. In lexer, it indicates we hit a pred - // while computing a closure operation. Don't make a DFA state from a. + // while computing a closure operation. Don't make a DFA state from this set. hasSemanticContext bool // readOnly is whether it is read-only. Do not @@ -89,11 +91,12 @@ type BaseATNConfigSet struct { readOnly bool // TODO: These fields make me pretty uncomfortable, but it is nice to pack up - // info together because it saves recomputation. Can we track conflicts as they + // info together because it saves re-computation. Can we track conflicts as they // are added to save scanning configs later? uniqueAlt int } +// Alts returns the combined set of alts for all the configurations in this set. func (b *BaseATNConfigSet) Alts() *BitSet { alts := NewBitSet() for _, it := range b.configs { @@ -102,6 +105,7 @@ func (b *BaseATNConfigSet) Alts() *BitSet { return alts } +// NewBaseATNConfigSet creates a new BaseATNConfigSet instance. func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { return &BaseATNConfigSet{ cachedHash: -1, @@ -110,10 +114,12 @@ func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { } } -// Add merges contexts with existing configs for (s, i, pi, _), where s is the -// ATNConfig.state, i is the ATNConfig.alt, and pi is the -// ATNConfig.semanticContext. We use (s,i,pi) as the key. Updates -// dipsIntoOuterContext and hasSemanticContext when necessary. +// Add merges contexts with existing configs for (s, i, pi, _), +// where 's' is the ATNConfig.state, 'i' is the ATNConfig.alt, and +// 'pi' is the [ATNConfig].semanticContext. +// +// We use (s,i,pi) as the key. +// Updates dipsIntoOuterContext and hasSemanticContext when necessary. func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { if b.readOnly { panic("set is read-only") @@ -157,9 +163,10 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { return true } +// GetStates returns the set of states represented by all configurations in this config set func (b *BaseATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] { - // states uses the standard comparator provided by the ATNState instance + // states uses the standard comparator and Hash() provided by the ATNState instance // states := NewJStore[ATNState, Comparator[ATNState]](aStateEqInst) @@ -170,26 +177,28 @@ 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 { - preds := make([]SemanticContext, 0) + predicates := make([]SemanticContext, 0) for i := 0; i < len(b.configs); i++ { c := b.configs[i].GetSemanticContext() if c != SemanticContextNone { - preds = append(preds, c) + predicates = append(predicates, c) } } - return preds + return predicates } func (b *BaseATNConfigSet) GetItems() []ATNConfig { @@ -220,11 +229,13 @@ func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool { return false } -// Compare is a hack function just to verify that adding DFAstares to the known -// set works, so long as comparison of ATNConfigSet s works. For that to work, we +// Compare is a hack function - O(n squared) at worst - just to verify that adding [DFA] states to the known +// set works, so long as comparison of [ATNConfigSet] works. For that to work, we // need to make sure that the set of ATNConfigs in two sets are equivalent. We can't // know the order, so we do this inefficient hack. If this proves the point, then -// we can change the config set to a better structure. +// we can change the config set to a better structure, where w e can perhaps order or hash the set of states +// +// TODO: JI - Look to change the way config set is implemented. Improve data structure if possible func (b *BaseATNConfigSet) Compare(bs *BaseATNConfigSet) bool { if len(b.configs) != len(bs.configs) { return false @@ -403,39 +414,3 @@ func NewOrderedATNConfigSet() *OrderedATNConfigSet { return &OrderedATNConfigSet{BaseATNConfigSet: b} } - -func hashATNConfig(i interface{}) int { - o := i.(ATNConfig) - hash := 7 - hash = 31*hash + o.GetState().GetStateNumber() - hash = 31*hash + o.GetAlt() - hash = 31*hash + o.GetSemanticContext().Hash() - return hash -} - -func equalATNConfigs(a, b interface{}) bool { - if a == nil || b == nil { - return false - } - - if a == b { - return true - } - - var ai, ok = a.(ATNConfig) - var bi, ok1 = b.(ATNConfig) - - if !ok || !ok1 { - return false - } - - if ai.GetState().GetStateNumber() != bi.GetState().GetStateNumber() { - return false - } - - if ai.GetAlt() != bi.GetAlt() { - return false - } - - return ai.GetSemanticContext().Equals(bi.GetSemanticContext()) -} diff --git a/runtime/Go/antlr/v4/atn_deserialization_options.go b/runtime/Go/antlr/v4/atn_deserialization_options.go index 3c975ec7bf..bdb30b3622 100644 --- a/runtime/Go/antlr/v4/atn_deserialization_options.go +++ b/runtime/Go/antlr/v4/atn_deserialization_options.go @@ -20,7 +20,7 @@ func (opts *ATNDeserializationOptions) ReadOnly() bool { func (opts *ATNDeserializationOptions) SetReadOnly(readOnly bool) { if opts.readOnly { - panic(errors.New("Cannot mutate read only ATNDeserializationOptions")) + panic(errors.New("cannot mutate read only ATNDeserializationOptions")) } opts.readOnly = readOnly } @@ -31,7 +31,7 @@ func (opts *ATNDeserializationOptions) VerifyATN() bool { func (opts *ATNDeserializationOptions) SetVerifyATN(verifyATN bool) { if opts.readOnly { - panic(errors.New("Cannot mutate read only ATNDeserializationOptions")) + panic(errors.New("cannot mutate read only ATNDeserializationOptions")) } opts.verifyATN = verifyATN } @@ -42,11 +42,12 @@ func (opts *ATNDeserializationOptions) GenerateRuleBypassTransitions() bool { func (opts *ATNDeserializationOptions) SetGenerateRuleBypassTransitions(generateRuleBypassTransitions bool) { if opts.readOnly { - panic(errors.New("Cannot mutate read only ATNDeserializationOptions")) + panic(errors.New("cannot mutate read only ATNDeserializationOptions")) } opts.generateRuleBypassTransitions = generateRuleBypassTransitions } +//goland:noinspection GoUnusedExportedFunction func DefaultATNDeserializationOptions() *ATNDeserializationOptions { return NewATNDeserializationOptions(&defaultATNDeserializationOptions) } diff --git a/runtime/Go/antlr/v4/atn_deserializer.go b/runtime/Go/antlr/v4/atn_deserializer.go index 3888856b4b..853df0870c 100644 --- a/runtime/Go/antlr/v4/atn_deserializer.go +++ b/runtime/Go/antlr/v4/atn_deserializer.go @@ -35,6 +35,7 @@ func NewATNDeserializer(options *ATNDeserializationOptions) *ATNDeserializer { return &ATNDeserializer{options: options} } +//goland:noinspection GoUnusedFunction func stringInSlice(a string, list []string) int { for i, b := range list { if b == a { @@ -193,7 +194,7 @@ func (a *ATNDeserializer) readModes(atn *ATN) { } } -func (a *ATNDeserializer) readSets(atn *ATN, sets []*IntervalSet) []*IntervalSet { +func (a *ATNDeserializer) readSets(_ *ATN, sets []*IntervalSet) []*IntervalSet { m := a.readInt() // Preallocate the needed capacity. @@ -450,7 +451,7 @@ func (a *ATNDeserializer) markPrecedenceDecisions(atn *ATN) { continue } - // We analyze the ATN to determine if a ATN decision state is the + // We analyze the [ATN] to determine if an ATN decision state is the // decision for the closure block that determines whether a // precedence rule should continue or complete. if atn.ruleToStartState[state.GetRuleIndex()].isPrecedenceRule { @@ -553,7 +554,7 @@ func (a *ATNDeserializer) readInt() int { return int(v) // data is 32 bits but int is at least that big } -func (a *ATNDeserializer) edgeFactory(atn *ATN, typeIndex, src, trg, arg1, arg2, arg3 int, sets []*IntervalSet) Transition { +func (a *ATNDeserializer) edgeFactory(atn *ATN, typeIndex, _, trg, arg1, arg2, arg3 int, sets []*IntervalSet) Transition { target := atn.states[trg] switch typeIndex { diff --git a/runtime/Go/antlr/v4/atn_state.go b/runtime/Go/antlr/v4/atn_state.go index 1f2a56bc31..5b69c476cb 100644 --- a/runtime/Go/antlr/v4/atn_state.go +++ b/runtime/Go/antlr/v4/atn_state.go @@ -25,6 +25,7 @@ const ( ATNStateInvalidStateNumber = -1 ) +//goland:noinspection GoUnusedGlobalVariable var ATNStateInitialNumTransitions = 4 type ATNState interface { @@ -361,7 +362,7 @@ func NewStarLoopEntryState() *StarLoopEntryState { b.stateType = ATNStateStarLoopEntry - // False precedenceRuleDecision indicates whether s state can benefit from a precedence DFA during SLL decision making. + // False precedenceRuleDecision indicates whether this state can benefit from a precedence [DFA] during SLL decision-making. return &StarLoopEntryState{BaseDecisionState: b} } diff --git a/runtime/Go/antlr/v4/atnconfigset_test.go b/runtime/Go/antlr/v4/atnconfigset_test.go index 3f1e9cc6cb..44fd4db4c2 100644 --- a/runtime/Go/antlr/v4/atnconfigset_test.go +++ b/runtime/Go/antlr/v4/atnconfigset_test.go @@ -4,13 +4,17 @@ import ( "testing" ) -// Test for Issue # 3319 -// To run, "cd antlr4/runtime/Go/antlr/", then "go test". +// Test for Issue #3319 +// To run: +// +// cd antlr4/runtime/Go/antlr/v4 +// go test +// // In the old runtime code, the test would crash because it would try // to compare a *LexerActionExecutor with nil, causing a nil pointer dereference. // It only happens if there were different states that had equal stateNumber mod 16, -// and you created that ATNConfig with a nil LexerActionExecutor. (That's why this -// code has a hardwired constant of 16. +// and you created that ATNConfig with a nil LexerActionExecutor. That's why this +// test code has a hardwired constant of 16. func TestCompare(t *testing.T) { var set = NewOrderedATNConfigSet() diff --git a/runtime/Go/antlr/v4/common_token_stream.go b/runtime/Go/antlr/v4/common_token_stream.go index c6c9485a20..665e258195 100644 --- a/runtime/Go/antlr/v4/common_token_stream.go +++ b/runtime/Go/antlr/v4/common_token_stream.go @@ -28,22 +28,24 @@ type CommonTokenStream struct { // trivial with bt field. fetchedEOF bool - // index indexs into tokens of the current token (next token to consume). + // index into [tokens] of the current token (next token to consume). // tokens[p] should be LT(1). It is set to -1 when the stream is first // constructed or when SetTokenSource is called, indicating that the first token // has not yet been fetched from the token source. For additional information, - // see the documentation of IntStream for a description of initializing methods. + // see the documentation of [IntStream] for a description of initializing methods. index int - // tokenSource is the TokenSource from which tokens for the bt stream are + // tokenSource is the [TokenSource] from which tokens for the bt stream are // fetched. tokenSource TokenSource - // tokens is all tokens fetched from the token source. The list is considered a + // tokens contains all tokens fetched from the token source. The list is considered a // complete view of the input once fetchedEOF is set to true. tokens []Token } +// NewCommonTokenStream creates a new CommonTokenStream instance using the supplied lexer to produce +// tokens and will pull tokens from the given lexer channel. func NewCommonTokenStream(lexer Lexer, channel int) *CommonTokenStream { return &CommonTokenStream{ channel: channel, @@ -53,6 +55,7 @@ func NewCommonTokenStream(lexer Lexer, channel int) *CommonTokenStream { } } +// GetAllTokens returns all tokens currently pulled from the token source. func (c *CommonTokenStream) GetAllTokens() []Token { return c.tokens } @@ -61,7 +64,7 @@ func (c *CommonTokenStream) Mark() int { return 0 } -func (c *CommonTokenStream) Release(marker int) {} +func (c *CommonTokenStream) Release(_ int) {} func (c *CommonTokenStream) reset() { c.Seek(0) @@ -197,8 +200,8 @@ func (c *CommonTokenStream) SetTokenSource(tokenSource TokenSource) { // NextTokenOnChannel returns the index of the next token on channel given a // starting index. Returns i if tokens[i] is on channel. Returns -1 if there are -// no tokens on channel between i and EOF. -func (c *CommonTokenStream) NextTokenOnChannel(i, channel int) int { +// no tokens on channel between 'i' and [TokenEOF]. +func (c *CommonTokenStream) NextTokenOnChannel(i, _ int) int { c.Sync(i) if i >= len(c.tokens) { @@ -244,7 +247,7 @@ func (c *CommonTokenStream) GetHiddenTokensToRight(tokenIndex, channel int) []To nextOnChannel := c.NextTokenOnChannel(tokenIndex+1, LexerDefaultTokenChannel) from := tokenIndex + 1 - // If no onchannel to the right, then nextOnChannel == -1, so set to to last token + // If no onChannel to the right, then nextOnChannel == -1, so set 'to' to the last token var to int if nextOnChannel == -1 { diff --git a/runtime/Go/antlr/v4/comparators.go b/runtime/Go/antlr/v4/comparators.go index 9ea3200536..bb9e8f7ee3 100644 --- a/runtime/Go/antlr/v4/comparators.go +++ b/runtime/Go/antlr/v4/comparators.go @@ -44,7 +44,7 @@ func (c *ObjEqComparator[T]) Hash1(o T) int { type SemCComparator[T Collectable[T]] struct{} -// ATNConfigComparator is used as the compartor for the configLookup field of an ATNConfigSet +// ATNConfigComparator is used as the comparator for the configLookup field of an 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 ATNConfigComparator[T Collectable[T]] struct { diff --git a/runtime/Go/antlr/v4/dfa.go b/runtime/Go/antlr/v4/dfa.go index bfd43e1f73..61d70f6325 100644 --- a/runtime/Go/antlr/v4/dfa.go +++ b/runtime/Go/antlr/v4/dfa.go @@ -4,6 +4,8 @@ package antlr +// DFA represents the Deterministic Finite Automaton used by the recognizer, including all the states it can +// reach and the transitions between them. type DFA struct { // atnStartState is the ATN state in which this was created atnStartState DecisionState diff --git a/runtime/Go/antlr/v4/dfa_serializer.go b/runtime/Go/antlr/v4/dfa_serializer.go index 84d0a31e53..0e11009899 100644 --- a/runtime/Go/antlr/v4/dfa_serializer.go +++ b/runtime/Go/antlr/v4/dfa_serializer.go @@ -10,7 +10,7 @@ import ( "strings" ) -// DFASerializer is a DFA walker that knows how to dump them to serialized +// DFASerializer is a DFA walker that knows how to dump the DFA states to serialized // strings. type DFASerializer struct { dfa *DFA diff --git a/runtime/Go/antlr/v4/dfa_state.go b/runtime/Go/antlr/v4/dfa_state.go index c90dec55c8..8f94d05ed5 100644 --- a/runtime/Go/antlr/v4/dfa_state.go +++ b/runtime/Go/antlr/v4/dfa_state.go @@ -22,26 +22,27 @@ func (p *PredPrediction) String() string { return "(" + fmt.Sprint(p.pred) + ", " + fmt.Sprint(p.alt) + ")" } -// DFAState represents a set of possible ATN configurations. As Aho, Sethi, +// DFAState represents a set of possible [ATN] configurations. As Aho, Sethi, // Ullman p. 117 says: "The DFA uses its state to keep track of all possible // states the ATN can be in after reading each input symbol. That is to say, -// after reading input a1a2..an, the DFA is in a state that represents the +// after reading input a1, a2,..an, the DFA is in a state that represents the // subset T of the states of the ATN that are reachable from the ATN's start -// state along some path labeled a1a2..an." In conventional NFA-to-DFA -// conversion, therefore, the subset T would be a bitset representing the set of -// states the ATN could be in. We need to track the alt predicted by each state +// state along some path labeled a1a2..an." +// +// In conventional NFA-to-DFA conversion, therefore, the subset T would be a bitset representing the set of +// states the [ATN] could be in. We need to track the alt predicted by each state // as well, however. More importantly, we need to maintain a stack of states, // tracking the closure operations as they jump from rule to rule, emulating // rule invocations (method calls). I have to add a stack to simulate the proper // lookahead sequences for the underlying LL grammar from which the ATN was // derived. // -// I use a set of ATNConfig objects, not simple states. An ATNConfig is both a -// state (ala normal conversion) and a RuleContext describing the chain of rules +// I use a set of [ATNConfig] objects, not simple states. An [ATNConfig] is both a +// state (ala normal conversion) and a [RuleContext] describing the chain of rules // (if any) followed to arrive at that state. // -// A DFAState may have multiple references to a particular state, but with -// different ATN contexts (with same or different alts) meaning that state was +// A [DFAState] may have multiple references to a particular state, but with +// different [ATN] contexts (with same or different alts) meaning that state was // reached via a different set of rule invocations. type DFAState struct { stateNumber int @@ -53,7 +54,7 @@ type DFAState struct { isAcceptState bool - // prediction is the ttype we match or alt we predict if the state is accept. + // 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 diff --git a/runtime/Go/antlr/v4/diagnostic_error_listener.go b/runtime/Go/antlr/v4/diagnostic_error_listener.go index c55bcc19b2..91ae237b51 100644 --- a/runtime/Go/antlr/v4/diagnostic_error_listener.go +++ b/runtime/Go/antlr/v4/diagnostic_error_listener.go @@ -33,6 +33,7 @@ type DiagnosticErrorListener struct { exactOnly bool } +//goland:noinspection GoUnusedExportedFunction func NewDiagnosticErrorListener(exactOnly bool) *DiagnosticErrorListener { n := new(DiagnosticErrorListener) @@ -55,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, conflictingAlts *BitSet, configs ATNConfigSet) { +func (d *DiagnosticErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, _ *BitSet, _ ATNConfigSet) { msg := "reportAttemptingFullContext d=" + d.getDecisionDescription(recognizer, dfa) + @@ -64,7 +65,7 @@ func (d *DiagnosticErrorListener) ReportAttemptingFullContext(recognizer Parser, recognizer.NotifyErrorListeners(msg, nil, nil) } -func (d *DiagnosticErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) { +func (d *DiagnosticErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, _ int, _ ATNConfigSet) { msg := "reportContextSensitivity d=" + d.getDecisionDescription(recognizer, dfa) + ", input='" + diff --git a/runtime/Go/antlr/v4/error_listener.go b/runtime/Go/antlr/v4/error_listener.go index f679f0dcd5..40edcd71a4 100644 --- a/runtime/Go/antlr/v4/error_listener.go +++ b/runtime/Go/antlr/v4/error_listener.go @@ -24,20 +24,21 @@ type ErrorListener interface { type DefaultErrorListener struct { } +//goland:noinspection GoUnusedExportedFunction func NewDefaultErrorListener() *DefaultErrorListener { return new(DefaultErrorListener) } -func (d *DefaultErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) { +func (d *DefaultErrorListener) SyntaxError(_ Recognizer, _ interface{}, _, _ int, _ string, _ RecognitionException) { } -func (d *DefaultErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { +func (d *DefaultErrorListener) ReportAmbiguity(_ Parser, _ *DFA, _, _ int, _ bool, _ *BitSet, _ ATNConfigSet) { } -func (d *DefaultErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) { +func (d *DefaultErrorListener) ReportAttemptingFullContext(_ Parser, _ *DFA, _, _ int, _ *BitSet, _ ATNConfigSet) { } -func (d *DefaultErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) { +func (d *DefaultErrorListener) ReportContextSensitivity(_ Parser, _ *DFA, _, _, _ int, _ ATNConfigSet) { } type ConsoleErrorListener struct { @@ -48,21 +49,16 @@ func NewConsoleErrorListener() *ConsoleErrorListener { return new(ConsoleErrorListener) } -// Provides a default instance of {@link ConsoleErrorListener}. +// ConsoleErrorListenerINSTANCE provides a default instance of {@link ConsoleErrorListener}. var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener() -// {@inheritDoc} +// SyntaxError prints messages to System.err containing the +// values of line, charPositionInLine, and msg using +// the following format: // -//

-// This implementation prints messages to {@link System//err} containing the -// values of {@code line}, {@code charPositionInLine}, and {@code msg} using -// the following format.

-// -//
-// line line:charPositionInLine msg
-// 
-func (c *ConsoleErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) { - fmt.Fprintln(os.Stderr, "line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg) +// line : +func (c *ConsoleErrorListener) SyntaxError(_ Recognizer, _ interface{}, line, column int, msg string, _ RecognitionException) { + _, _ = fmt.Fprintln(os.Stderr, "line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg) } type ProxyErrorListener struct { diff --git a/runtime/Go/antlr/v4/error_strategy.go b/runtime/Go/antlr/v4/error_strategy.go index 5c0a637ba4..f6fd9afc76 100644 --- a/runtime/Go/antlr/v4/error_strategy.go +++ b/runtime/Go/antlr/v4/error_strategy.go @@ -21,8 +21,8 @@ type ErrorStrategy interface { ReportMatch(Parser) } -// This is the default implementation of {@link ANTLRErrorStrategy} used for -// error Reporting and recovery in ANTLR parsers. +// DefaultErrorStrategy is the default implementation of ANTLRErrorStrategy used for +// error reporting and recovery in ANTLR parsers. type DefaultErrorStrategy struct { errorRecoveryMode bool lastErrorIndex int @@ -46,7 +46,7 @@ func NewDefaultErrorStrategy() *DefaultErrorStrategy { // The index into the input stream where the last error occurred. // This is used to prevent infinite loops where an error is found // but no token is consumed during recovery...another error is found, - // ad nauseum. This is a failsafe mechanism to guarantee that at least + // ad nauseam. This is a failsafe mechanism to guarantee that at least // one token/tree node is consumed for two errors. // d.lastErrorIndex = -1 @@ -62,50 +62,37 @@ func (d *DefaultErrorStrategy) reset(recognizer Parser) { // This method is called to enter error recovery mode when a recognition // exception is Reported. -// -// @param recognizer the parser instance -func (d *DefaultErrorStrategy) beginErrorCondition(recognizer Parser) { +func (d *DefaultErrorStrategy) beginErrorCondition(_ Parser) { d.errorRecoveryMode = true } -func (d *DefaultErrorStrategy) InErrorRecoveryMode(recognizer Parser) bool { +func (d *DefaultErrorStrategy) InErrorRecoveryMode(_ Parser) bool { return d.errorRecoveryMode } // This method is called to leave error recovery mode after recovering from // a recognition exception. -// -// @param recognizer -func (d *DefaultErrorStrategy) endErrorCondition(recognizer Parser) { +func (d *DefaultErrorStrategy) endErrorCondition(_ Parser) { d.errorRecoveryMode = false d.lastErrorStates = nil d.lastErrorIndex = -1 } -// {@inheritDoc} -// -//

The default implementation simply calls {@link //endErrorCondition}.

+// ReportMatch is the default implementation of error matching and simply calls endErrorCondition. func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) { d.endErrorCondition(recognizer) } -// {@inheritDoc} -// -//

The default implementation returns immediately if the handler is already -// in error recovery mode. Otherwise, it calls {@link //beginErrorCondition} -// and dispatches the Reporting task based on the runtime type of {@code e} -// according to the following table.

-// -//
    -//
  • {@link NoViableAltException}: Dispatches the call to -// {@link //ReportNoViableAlternative}
  • -//
  • {@link InputMisMatchException}: Dispatches the call to -// {@link //ReportInputMisMatch}
  • -//
  • {@link FailedPredicateException}: Dispatches the call to -// {@link //ReportFailedPredicate}
  • -//
  • All other types: calls {@link Parser//NotifyErrorListeners} to Report -// the exception
  • -//
+// ReportError is the default implementation of error reporting. +// It returns immediately if the handler is already +// in error recovery mode. Otherwise, it calls [beginErrorCondition] +// and dispatches the Reporting task based on the runtime type of e +// according to the following table. +// +// [NoViableAltException] : Dispatches the call to [ReportNoViableAlternative] +// [InputMisMatchException] : Dispatches the call to [ReportInputMisMatch] +// [FailedPredicateException] : Dispatches the call to [ReportFailedPredicate] +// All other types : Calls [NotifyErrorListeners] to Report the exception func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionException) { // if we've already Reported an error and have not Matched a token // yet successfully, don't Report any errors. @@ -128,12 +115,10 @@ func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionExcep } } -// {@inheritDoc} -// -//

The default implementation reSynchronizes the parser by consuming tokens -// until we find one in the reSynchronization set--loosely the set of tokens -// that can follow the current rule.

-func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException) { +// Recover is the default recovery implementation. +// It reSynchronizes the parser by consuming tokens until we find one in the reSynchronization set - +// loosely the set of tokens that can follow the current rule. +func (d *DefaultErrorStrategy) Recover(recognizer Parser, _ RecognitionException) { if d.lastErrorIndex == recognizer.GetInputStream().Index() && d.lastErrorStates != nil && d.lastErrorStates.contains(recognizer.GetState()) { @@ -148,54 +133,58 @@ func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException d.lastErrorStates = NewIntervalSet() } d.lastErrorStates.addOne(recognizer.GetState()) - followSet := d.getErrorRecoverySet(recognizer) + followSet := d.GetErrorRecoverySet(recognizer) d.consumeUntil(recognizer, followSet) } -// The default implementation of {@link ANTLRErrorStrategy//Sync} makes sure -// that the current lookahead symbol is consistent with what were expecting -// at d point in the ATN. You can call d anytime but ANTLR only -// generates code to check before subrules/loops and each iteration. +// Sync is the default implementation of error strategy synchronization. +// +// This Sync makes sure that the current lookahead symbol is consistent with what were expecting +// at this point in the [ATN]. You can call this anytime but ANTLR only +// generates code to check before sub-rules/loops and each iteration. // -//

Implements Jim Idle's magic Sync mechanism in closures and optional -// subrules. E.g.,

+// Implements [Jim Idle]'s magic Sync mechanism in closures and optional +// sub-rules. E.g.: // -//
-// a : Sync ( stuff Sync )*
-// Sync : {consume to what can follow Sync}
-// 
+// a : Sync ( stuff Sync )* +// Sync : {consume to what can follow Sync} // -// At the start of a sub rule upon error, {@link //Sync} performs single +// At the start of a sub-rule upon error, Sync performs single // token deletion, if possible. If it can't do that, it bails on the current // rule and uses the default error recovery, which consumes until the // reSynchronization set of the current rule. // -//

If the sub rule is optional ({@code (...)?}, {@code (...)*}, or block -// with an empty alternative), then the expected set includes what follows -// the subrule.

+// If the sub-rule is optional +// +// ({@code (...)?}, {@code (...)*}, // -//

During loop iteration, it consumes until it sees a token that can start a -// sub rule or what follows loop. Yes, that is pretty aggressive. We opt to -// stay in the loop as long as possible.

+// or a block with an empty alternative), then the expected set includes what follows +// the sub-rule. // -//

ORIGINS

+// During loop iteration, it consumes until it sees a token that can start a +// sub-rule or what follows loop. Yes, that is pretty aggressive. We opt to +// stay in the loop as long as possible. // -//

Previous versions of ANTLR did a poor job of their recovery within loops. +// # Origins +// +// Previous versions of ANTLR did a poor job of their recovery within loops. // A single mismatch token or missing token would force the parser to bail -// out of the entire rules surrounding the loop. So, for rule

+// out of the entire rules surrounding the loop. So, for rule: // -//
-// classfunc : 'class' ID '{' member* '}'
-// 
+// classfunc : 'class' ID '{' member* '}' // // input with an extra token between members would force the parser to // consume until it found the next class definition rather than the next // member definition of the current class. // -//

This functionality cost a little bit of effort because the parser has to -// compare token set at the start of the loop and at each iteration. If for -// some reason speed is suffering for you, you can turn off d -// functionality by simply overriding d method as a blank { }.

+// This functionality cost a bit of effort because the parser has to +// compare the token set at the start of the loop and at each iteration. If for +// some reason speed is suffering for you, you can turn off this +// functionality by simply overriding this method as empty: +// +// { } +// +// [Jim Idle]: https://github.com/jimidle func (d *DefaultErrorStrategy) Sync(recognizer Parser) { // If already recovering, don't try to Sync if d.InErrorRecoveryMode(recognizer) { @@ -222,20 +211,16 @@ func (d *DefaultErrorStrategy) Sync(recognizer Parser) { d.ReportUnwantedToken(recognizer) expecting := NewIntervalSet() expecting.addSet(recognizer.GetExpectedTokens()) - whatFollowsLoopIterationOrRule := expecting.addSet(d.getErrorRecoverySet(recognizer)) + whatFollowsLoopIterationOrRule := expecting.addSet(d.GetErrorRecoverySet(recognizer)) d.consumeUntil(recognizer, whatFollowsLoopIterationOrRule) default: // do nothing if we can't identify the exact kind of ATN state } } -// This is called by {@link //ReportError} when the exception is a -// {@link NoViableAltException}. -// -// @see //ReportError +// ReportNoViableAlternative is called by [ReportError] when the exception is a [NoViableAltException]. // -// @param recognizer the parser instance -// @param e the recognition exception +// See also [ReportError] func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *NoViableAltException) { tokens := recognizer.GetTokenStream() var input string @@ -252,48 +237,38 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N recognizer.NotifyErrorListeners(msg, e.offendingToken, e) } -// This is called by {@link //ReportError} when the exception is an -// {@link InputMisMatchException}. +// ReportInputMisMatch is called by [ReportError] when the exception is an [InputMisMatchException] // -// @see //ReportError -// -// @param recognizer the parser instance -// @param e the recognition exception -func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *InputMisMatchException) { - msg := "mismatched input " + this.GetTokenErrorDisplay(e.offendingToken) + +// See also: [ReportError] +func (d *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *InputMisMatchException) { + msg := "mismatched input " + d.GetTokenErrorDisplay(e.offendingToken) + " expecting " + e.getExpectedTokens().StringVerbose(recognizer.GetLiteralNames(), recognizer.GetSymbolicNames(), false) recognizer.NotifyErrorListeners(msg, e.offendingToken, e) } -// This is called by {@link //ReportError} when the exception is a -// {@link FailedPredicateException}. -// -// @see //ReportError +// ReportFailedPredicate is called by [ReportError] when the exception is a [FailedPredicateException]. // -// @param recognizer the parser instance -// @param e the recognition exception +// See also: [ReportError] func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *FailedPredicateException) { ruleName := recognizer.GetRuleNames()[recognizer.GetParserRuleContext().GetRuleIndex()] msg := "rule " + ruleName + " " + e.message recognizer.NotifyErrorListeners(msg, e.offendingToken, e) } -// This method is called to Report a syntax error which requires the removal +// ReportUnwantedToken is called to report a syntax error that requires the removal // of a token from the input stream. At the time d method is called, the -// erroneous symbol is current {@code LT(1)} symbol and has not yet been -// removed from the input stream. When d method returns, -// {@code recognizer} is in error recovery mode. +// erroneous symbol is the current LT(1) symbol and has not yet been +// removed from the input stream. When this method returns, +// recognizer is in error recovery mode. // -//

This method is called when {@link //singleTokenDeletion} identifies +// This method is called when singleTokenDeletion identifies // single-token deletion as a viable recovery strategy for a mismatched -// input error.

+// input error. // -//

The default implementation simply returns if the handler is already in -// error recovery mode. Otherwise, it calls {@link //beginErrorCondition} to +// The default implementation simply returns if the handler is already in +// error recovery mode. Otherwise, it calls beginErrorCondition to // enter error recovery mode, followed by calling -// {@link Parser//NotifyErrorListeners}.

-// -// @param recognizer the parser instance +// [NotifyErrorListeners] func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { if d.InErrorRecoveryMode(recognizer) { return @@ -307,21 +282,18 @@ func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { recognizer.NotifyErrorListeners(msg, t, nil) } -// This method is called to Report a syntax error which requires the -// insertion of a missing token into the input stream. At the time d -// method is called, the missing token has not yet been inserted. When d -// method returns, {@code recognizer} is in error recovery mode. +// ReportMissingToken is called to report a syntax error which requires the +// insertion of a missing token into the input stream. At the time this +// method is called, the missing token has not yet been inserted. When this +// method returns, recognizer is in error recovery mode. // -//

This method is called when {@link //singleTokenInsertion} identifies +// This method is called when singleTokenInsertion identifies // single-token insertion as a viable recovery strategy for a mismatched -// input error.

+// input error. // -//

The default implementation simply returns if the handler is already in -// error recovery mode. Otherwise, it calls {@link //beginErrorCondition} to -// enter error recovery mode, followed by calling -// {@link Parser//NotifyErrorListeners}.

-// -// @param recognizer the parser instance +// The default implementation simply returns if the handler is already in +// error recovery mode. Otherwise, it calls beginErrorCondition to +// enter error recovery mode, followed by calling [NotifyErrorListeners] func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) { if d.InErrorRecoveryMode(recognizer) { return @@ -334,54 +306,48 @@ func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) { recognizer.NotifyErrorListeners(msg, t, nil) } -//

The default implementation attempts to recover from the mismatched input +// The RecoverInline default implementation attempts to recover from the mismatched input // by using single token insertion and deletion as described below. If the -// recovery attempt fails, d method panics an -// {@link InputMisMatchException}.

+// recovery attempt fails, this method panics with [InputMisMatchException}. +// TODO: Not sure that panic() is the right thing to do here - JI // -//

EXTRA TOKEN (single token deletion)

+// # EXTRA TOKEN (single token deletion) // -//

{@code LA(1)} is not what we are looking for. If {@code LA(2)} has the -// right token, however, then assume {@code LA(1)} is some extra spurious +// LA(1) is not what we are looking for. If LA(2) has the +// right token, however, then assume LA(1) is some extra spurious // token and delete it. Then consume and return the next token (which was -// the {@code LA(2)} token) as the successful result of the Match operation.

+// the LA(2) token) as the successful result of the Match operation. // -//

This recovery strategy is implemented by {@link -// //singleTokenDeletion}.

+// # This recovery strategy is implemented by singleTokenDeletion // -//

MISSING TOKEN (single token insertion)

+// # MISSING TOKEN (single token insertion) // -//

If current token (at {@code LA(1)}) is consistent with what could come -// after the expected {@code LA(1)} token, then assume the token is missing -// and use the parser's {@link TokenFactory} to create it on the fly. The -// "insertion" is performed by returning the created token as the successful -// result of the Match operation.

+// If current token -at LA(1) - is consistent with what could come +// after the expected LA(1) token, then assume the token is missing +// and use the parser's [TokenFactory] to create it on the fly. The +// “insertion” is performed by returning the created token as the successful +// result of the Match operation. // -//

This recovery strategy is implemented by {@link -// //singleTokenInsertion}.

+// This recovery strategy is implemented by [SingleTokenInsertion]. // -//

EXAMPLE

+// # Example // -//

For example, Input {@code i=(3} is clearly missing the {@code ')'}. When -// the parser returns from the nested call to {@code expr}, it will have -// call chain:

+// For example, Input i=(3 is clearly missing the ')'. When +// the parser returns from the nested call to expr, it will have +// call the chain: // -//
-// stat &rarr expr &rarr atom
-// 
+// stat → expr → atom // -// and it will be trying to Match the {@code ')'} at d point in the +// and it will be trying to Match the ')' at this point in the // derivation: // -//
-// => ID '=' '(' INT ')' ('+' atom)* ”
-// ^
-// 
+// : ID '=' '(' INT ')' ('+' atom)* ';' +// ^ // -// The attempt to Match {@code ')'} will fail when it sees {@code ”} and -// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==”} -// is in the set of tokens that can follow the {@code ')'} token reference -// in rule {@code atom}. It can assume that you forgot the {@code ')'}. +// The attempt to [Match] ')' will fail when it sees ';' and +// call [RecoverInline]. To recover, it sees that LA(1)==';' +// is in the set of tokens that can follow the ')' token reference +// in rule atom. It can assume that you forgot the ')'. func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token { // SINGLE TOKEN DELETION MatchedSymbol := d.SingleTokenDeletion(recognizer) @@ -399,21 +365,20 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token { panic(NewInputMisMatchException(recognizer)) } -// This method implements the single-token insertion inline error recovery -// strategy. It is called by {@link //recoverInline} if the single-token +// SingleTokenInsertion implements the single-token insertion inline error recovery +// strategy. It is called by [RecoverInline] if the single-token // deletion strategy fails to recover from the mismatched input. If this // method returns {@code true}, {@code recognizer} will be in error recovery // mode. // -//

This method determines whether or not single-token insertion is viable by -// checking if the {@code LA(1)} input symbol could be successfully Matched -// if it were instead the {@code LA(2)} symbol. If d method returns +// This method determines whether single-token insertion is viable by +// checking if the LA(1) input symbol could be successfully Matched +// if it were instead the LA(2) symbol. If this method returns // {@code true}, the caller is responsible for creating and inserting a -// token with the correct type to produce d behavior.

+// token with the correct type to produce this behavior.

// -// @param recognizer the parser instance -// @return {@code true} if single-token insertion is a viable recovery -// strategy for the current mismatched input, otherwise {@code false} +// This func returns true if single-token insertion is a viable recovery +// strategy for the current mismatched input. func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool { currentSymbolType := recognizer.GetTokenStream().LA(1) // if current token is consistent with what could come after current @@ -431,23 +396,21 @@ func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool { return false } -// This method implements the single-token deletion inline error recovery -// strategy. It is called by {@link //recoverInline} to attempt to recover +// SingleTokenDeletion implements the single-token deletion inline error recovery +// strategy. It is called by [RecoverInline] to attempt to recover // from mismatched input. If this method returns nil, the parser and error // handler state will not have changed. If this method returns non-nil, -// {@code recognizer} will not be in error recovery mode since the +// recognizer will not be in error recovery mode since the // returned token was a successful Match. // -//

If the single-token deletion is successful, d method calls -// {@link //ReportUnwantedToken} to Report the error, followed by -// {@link Parser//consume} to actually "delete" the extraneous token. Then, -// before returning {@link //ReportMatch} is called to signal a successful -// Match.

+// If the single-token deletion is successful, this method calls +// [ReportUnwantedToken] to Report the error, followed by +// [Consume] to actually “delete” the extraneous token. Then, +// before returning, [ReportMatch] is called to signal a successful +// Match. // -// @param recognizer the parser instance -// @return the successfully Matched {@link Token} instance if single-token -// deletion successfully recovers from the mismatched input, otherwise -// {@code nil} +// The func returns the successfully Matched [Token] instance if single-token +// deletion successfully recovers from the mismatched input, otherwise nil. func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token { NextTokenType := recognizer.GetTokenStream().LA(2) expecting := d.GetExpectedTokens(recognizer) @@ -467,24 +430,28 @@ func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token { return nil } -// Conjure up a missing token during error recovery. +// GetMissingSymbol conjures up a missing token during error recovery. // // The recognizer attempts to recover from single missing // symbols. But, actions might refer to that missing symbol. -// For example, x=ID {f($x)}. The action clearly assumes +// For example: +// +// x=ID {f($x)}. +// +// The action clearly assumes // that there has been an identifier Matched previously and that // $x points at that token. If that token is missing, but // the next token in the stream is what we want we assume that -// d token is missing and we keep going. Because we +// this token is missing, and we keep going. Because we // have to return some token to replace the missing token, // we have to conjure one up. This method gives the user control // over the tokens returned for missing tokens. Mostly, // you will want to create something special for identifier // tokens. For literals such as '{' and ',', the default // action in the parser or tree parser works. It simply creates -// a CommonToken of the appropriate type. The text will be the token. -// If you change what tokens must be created by the lexer, -// override d method to create the appropriate tokens. +// a [CommonToken] of the appropriate type. The text will be the token name. +// If you need to change which tokens must be created by the lexer, +// override this method to create the appropriate tokens. func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token { currentSymbol := recognizer.GetCurrentToken() expecting := d.GetExpectedTokens(recognizer) @@ -516,13 +483,13 @@ func (d *DefaultErrorStrategy) GetExpectedTokens(recognizer Parser) *IntervalSet return recognizer.GetExpectedTokens() } -// How should a token be displayed in an error message? The default -// is to display just the text, but during development you might -// want to have a lot of information spit out. Override in that case -// to use t.String() (which, for CommonToken, dumps everything about +// GetTokenErrorDisplay determines how a token should be displayed in an error message. +// The default is to display just the text, but during development you might +// want to have a lot of information spit out. Override this func in that case +// to use t.String() (which, for [CommonToken], dumps everything about // the token). This is better than forcing you to override a method in // your token objects because you don't have to go modify your lexer -// so that it creates a NewJava type. +// so that it creates a new type. func (d *DefaultErrorStrategy) GetTokenErrorDisplay(t Token) string { if t == nil { return "" @@ -545,52 +512,57 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { return "'" + s + "'" } -// Compute the error recovery set for the current rule. During +// GetErrorRecoverySet computes the error recovery set for the current rule. During // rule invocation, the parser pushes the set of tokens that can -// follow that rule reference on the stack d amounts to +// follow that rule reference on the stack. This amounts to // computing FIRST of what follows the rule reference in the // enclosing rule. See LinearApproximator.FIRST(). +// // This local follow set only includes tokens // from within the rule i.e., the FIRST computation done by // ANTLR stops at the end of a rule. // -// # EXAMPLE +// # Example // // When you find a "no viable alt exception", the input is not // consistent with any of the alternatives for rule r. The best // thing to do is to consume tokens until you see something that -// can legally follow a call to r//or* any rule that called r. +// can legally follow a call to r or any rule that called r. // You don't want the exact set of viable next tokens because the // input might just be missing a token--you might consume the // rest of the input looking for one of the missing tokens. // -// Consider grammar: +// Consider the grammar: +// +// a : '[' b ']' +// | '(' b ')' +// ; // -// a : '[' b ']' -// | '(' b ')' +// b : c '^' INT +// ; // -// b : c '^' INT -// c : ID -// | INT +// c : ID +// | INT +// ; // // At each rule invocation, the set of tokens that could follow // that rule is pushed on a stack. Here are the various // context-sensitive follow sets: // -// FOLLOW(b1_in_a) = FIRST(']') = ']' -// FOLLOW(b2_in_a) = FIRST(')') = ')' -// FOLLOW(c_in_b) = FIRST('^') = '^' +// FOLLOW(b1_in_a) = FIRST(']') = ']' +// FOLLOW(b2_in_a) = FIRST(')') = ')' +// FOLLOW(c_in_b) = FIRST('^') = '^' // -// Upon erroneous input "[]", the call chain is +// Upon erroneous input “[]”, the call chain is // -// a -> b -> c +// a → b → c // // and, hence, the follow context stack is: // -// depth follow set start of rule execution -// 0 a (from main()) -// 1 ']' b -// 2 '^' c +// Depth Follow set Start of rule execution +// 0 a (from main()) +// 1 ']' b +// 2 '^' c // // Notice that ')' is not included, because b would have to have // been called from a different context in rule a for ')' to be @@ -598,11 +570,14 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { // // For error recovery, we cannot consider FOLLOW(c) // (context-sensitive or otherwise). We need the combined set of -// all context-sensitive FOLLOW sets--the set of all tokens that +// all context-sensitive FOLLOW sets - the set of all tokens that // could follow any reference in the call chain. We need to // reSync to one of those tokens. Note that FOLLOW(c)='^' and if // we reSync'd to that token, we'd consume until EOF. We need to -// Sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}. +// Sync to context-sensitive FOLLOWs for a, b, and c: +// +// {']','^'} +// // In this case, for input "[]", LA(1) is ']' and in the set, so we would // not consume anything. After printing an error, rule c would // return normally. Rule b would not find the required '^' though. @@ -620,22 +595,19 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { // // ANTLR's error recovery mechanism is based upon original ideas: // -// "Algorithms + Data Structures = Programs" by Niklaus Wirth -// -// and -// -// "A note on error recovery in recursive descent parsers": -// http://portal.acm.org/citation.cfm?id=947902.947905 +// [Algorithms + Data Structures = Programs] by Niklaus Wirth and +// [A note on error recovery in recursive descent parsers]. // -// Later, Josef Grosch had some good ideas: +// Later, Josef Grosch had some good ideas in [Efficient and Comfortable Error Recovery in Recursive Descent +// Parsers] // -// "Efficient and Comfortable Error Recovery in Recursive Descent -// Parsers": -// ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip +// Like Grosch I implement context-sensitive FOLLOW sets that are combined at run-time upon error to avoid overhead +// during parsing. Later, the runtime Sync was improved for loops/sub-rules see [Sync] docs // -// Like Grosch I implement context-sensitive FOLLOW sets that are combined -// at run-time upon error to avoid overhead during parsing. -func (d *DefaultErrorStrategy) getErrorRecoverySet(recognizer Parser) *IntervalSet { +// [A note on error recovery in recursive descent parsers]: http://portal.acm.org/citation.cfm?id=947902.947905 +// [Algorithms + Data Structures = Programs]: https://t.ly/5QzgE +// [Efficient and Comfortable Error Recovery in Recursive Descent Parsers]: ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip +func (d *DefaultErrorStrategy) GetErrorRecoverySet(recognizer Parser) *IntervalSet { atn := recognizer.GetInterpreter().atn ctx := recognizer.GetParserRuleContext() recoverSet := NewIntervalSet() @@ -660,40 +632,36 @@ func (d *DefaultErrorStrategy) consumeUntil(recognizer Parser, set *IntervalSet) } } -// -// This implementation of {@link ANTLRErrorStrategy} responds to syntax errors +// The BailErrorStrategy implementation of ANTLRErrorStrategy responds to syntax errors // by immediately canceling the parse operation with a -// {@link ParseCancellationException}. The implementation ensures that the -// {@link ParserRuleContext//exception} field is set for all parse tree nodes +// [ParseCancellationException]. The implementation ensures that the +// [ParserRuleContext//exception] field is set for all parse tree nodes // that were not completed prior to encountering the error. // -//

-// This error strategy is useful in the following scenarios.

+// This error strategy is useful in the following scenarios. // -//
    -//
  • Two-stage parsing: This error strategy allows the first -// stage of two-stage parsing to immediately terminate if an error is -// encountered, and immediately fall back to the second stage. In addition to -// avoiding wasted work by attempting to recover from errors here, the empty -// implementation of {@link BailErrorStrategy//Sync} improves the performance of -// the first stage.
  • -//
  • Silent validation: When syntax errors are not being -// Reported or logged, and the parse result is simply ignored if errors occur, -// the {@link BailErrorStrategy} avoids wasting work on recovering from errors -// when the result will be ignored either way.
  • -//
+// - Two-stage parsing: This error strategy allows the first +// stage of two-stage parsing to immediately terminate if an error is +// encountered, and immediately fall back to the second stage. In addition to +// avoiding wasted work by attempting to recover from errors here, the empty +// implementation of [BailErrorStrategy.Sync] improves the performance of +// the first stage. // -//

-// {@code myparser.setErrorHandler(NewBailErrorStrategy())}

+// - Silent validation: When syntax errors are not being +// Reported or logged, and the parse result is simply ignored if errors occur, +// the [BailErrorStrategy] avoids wasting work on recovering from errors +// when the result will be ignored either way. // -// @see Parser//setErrorHandler(ANTLRErrorStrategy) - +// myparser.SetErrorHandler(NewBailErrorStrategy()) +// +// See also: [Parser.SetErrorHandler(ANTLRErrorStrategy)] type BailErrorStrategy struct { *DefaultErrorStrategy } var _ ErrorStrategy = &BailErrorStrategy{} +//goland:noinspection GoUnusedExportedFunction func NewBailErrorStrategy() *BailErrorStrategy { b := new(BailErrorStrategy) @@ -703,10 +671,10 @@ func NewBailErrorStrategy() *BailErrorStrategy { return b } -// Instead of recovering from exception {@code e}, re-panic it wrapped -// in a {@link ParseCancellationException} so it is not caught by the -// rule func catches. Use {@link Exception//getCause()} to get the -// original {@link RecognitionException}. +// Recover Instead of recovering from exception e, re-panic it wrapped +// in a [ParseCancellationException] so it is not caught by the +// rule func catches. Use Exception.GetCause() to get the +// original [RecognitionException]. func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) { context := recognizer.GetParserRuleContext() for context != nil { @@ -720,7 +688,7 @@ func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) { panic(NewParseCancellationException()) // TODO we don't emit e properly } -// Make sure we don't attempt to recover inline if the parser +// RecoverInline makes sure we don't attempt to recover inline if the parser // successfully recovers, it won't panic an exception. func (b *BailErrorStrategy) RecoverInline(recognizer Parser) Token { b.Recover(recognizer, NewInputMisMatchException(recognizer)) @@ -728,7 +696,6 @@ func (b *BailErrorStrategy) RecoverInline(recognizer Parser) Token { return nil } -// Make sure we don't attempt to recover from problems in subrules.// -func (b *BailErrorStrategy) Sync(recognizer Parser) { - // pass +// Sync makes sure we don't attempt to recover from problems in sub-rules. +func (b *BailErrorStrategy) Sync(_ Parser) { } diff --git a/runtime/Go/antlr/v4/errors.go b/runtime/Go/antlr/v4/errors.go index 3954c13782..df2fc1c73a 100644 --- a/runtime/Go/antlr/v4/errors.go +++ b/runtime/Go/antlr/v4/errors.go @@ -43,15 +43,17 @@ func NewBaseRecognitionException(message string, recognizer Recognizer, input In t.recognizer = recognizer t.input = input t.ctx = ctx - // The current {@link Token} when an error occurred. Since not all streams + + // The current Token when an error occurred. Since not all streams // support accessing symbols by index, we have to track the {@link Token} // instance itself. + // t.offendingToken = nil + // Get the ATN state number the parser was in at the time the error - // occurred. For {@link NoViableAltException} and - // {@link LexerNoViableAltException} exceptions, this is the - // {@link DecisionState} number. For others, it is the state whose outgoing - // edge we couldn't Match. + // occurred. For NoViableAltException and LexerNoViableAltException exceptions, this is the + // DecisionState number. For others, it is the state whose outgoing edge we couldn't Match. + // t.offendingState = -1 if t.recognizer != nil { t.offendingState = t.recognizer.GetState() @@ -74,15 +76,14 @@ func (b *BaseRecognitionException) GetInputStream() IntStream { //

If the state number is not known, b method returns -1.

-// Gets the set of input symbols which could potentially follow the -// previously Matched symbol at the time b exception was panicn. +// getExpectedTokens gets the set of input symbols which could potentially follow the +// previously Matched symbol at the time this exception was raised. // -//

If the set of expected tokens is not known and could not be computed, -// b method returns {@code nil}.

+// If the set of expected tokens is not known and could not be computed, +// this method returns nil. // -// @return The set of token types that could potentially follow the current -// state in the ATN, or {@code nil} if the information is not available. -// / +// The func returns the set of token types that could potentially follow the current +// state in the {ATN}, or nil if the information is not available. func (b *BaseRecognitionException) getExpectedTokens() *IntervalSet { if b.recognizer != nil { return b.recognizer.GetATN().getExpectedTokens(b.offendingState, b.ctx) @@ -131,10 +132,12 @@ type NoViableAltException struct { deadEndConfigs ATNConfigSet } -// Indicates that the parser could not decide which of two or more paths +// NewNoViableAltException creates an exception indicating that the parser could not decide which of two or more paths // to take based upon the remaining input. It tracks the starting token // of the offending input and also knows where the parser was -// in the various paths when the error. Reported by ReportNoViableAlternative() +// 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 { if ctx == nil { @@ -157,12 +160,14 @@ func NewNoViableAltException(recognizer Parser, input TokenStream, startToken To n.BaseRecognitionException = NewBaseRecognitionException("", recognizer, input, ctx) // Which configurations did we try at input.Index() that couldn't Match - // input.LT(1)?// + // input.LT(1) n.deadEndConfigs = deadEndConfigs + // The token object at the start index the input stream might - // not be buffering tokens so get a reference to it. (At the - // time the error occurred, of course the stream needs to keep a - // buffer all of the tokens but later we might not have access to those.) + // not be buffering tokens so get a reference to it. + // + // At the time the error occurred, of course the stream needs to keep a + // buffer of all the tokens, but later we might not have access to those. n.startToken = startToken n.offendingToken = offendingToken @@ -173,7 +178,7 @@ type InputMisMatchException struct { *BaseRecognitionException } -// This signifies any kind of mismatched input exceptions such as +// NewInputMisMatchException creates an exception that signifies any kind of mismatched input exceptions such as // when the current input does not Match the expected token. func NewInputMisMatchException(recognizer Parser) *InputMisMatchException { @@ -186,11 +191,10 @@ func NewInputMisMatchException(recognizer Parser) *InputMisMatchException { } -// A semantic predicate failed during validation. Validation of predicates +// FailedPredicateException indicates that a semantic predicate failed during validation. Validation of predicates // occurs when normally parsing the alternative just like Matching a token. // Disambiguating predicate evaluation occurs when we test a predicate during // prediction. - type FailedPredicateException struct { *BaseRecognitionException @@ -199,6 +203,7 @@ type FailedPredicateException struct { predicate string } +//goland:noinspection GoUnusedExportedFunction func NewFailedPredicateException(recognizer Parser, predicate string, message string) *FailedPredicateException { f := new(FailedPredicateException) diff --git a/runtime/Go/antlr/v4/file_stream.go b/runtime/Go/antlr/v4/file_stream.go index bd6ad5efe3..e8d0efce47 100644 --- a/runtime/Go/antlr/v4/file_stream.go +++ b/runtime/Go/antlr/v4/file_stream.go @@ -19,6 +19,7 @@ type FileStream struct { filename string } +//goland:noinspection GoUnusedExportedFunction func NewFileStream(fileName string) (*FileStream, error) { buf := bytes.NewBuffer(nil) @@ -27,7 +28,11 @@ func NewFileStream(fileName string) (*FileStream, error) { if err != nil { return nil, err } - defer f.Close() + defer func(f *os.File) { + errF := f.Close() + if errF != nil { + } + }(f) _, err = io.Copy(buf, f) if err != nil { return nil, err diff --git a/runtime/Go/antlr/v4/input_stream.go b/runtime/Go/antlr/v4/input_stream.go index a8b889cedb..9b100fd3a0 100644 --- a/runtime/Go/antlr/v4/input_stream.go +++ b/runtime/Go/antlr/v4/input_stream.go @@ -11,6 +11,7 @@ type InputStream struct { size int } +// NewInputStream creates a new input stream from the given string func NewInputStream(data string) *InputStream { is := new(InputStream) @@ -27,6 +28,7 @@ func (is *InputStream) reset() { is.index = 0 } +// Consume moves the input pointer to the next character in the input stream func (is *InputStream) Consume() { if is.index >= is.size { // assert is.LA(1) == TokenEOF @@ -35,6 +37,7 @@ func (is *InputStream) Consume() { is.index++ } +// LA returns the character at the given offset from the start of the input stream func (is *InputStream) LA(offset int) int { if offset == 0 { @@ -52,26 +55,31 @@ func (is *InputStream) LA(offset int) int { return int(is.data[pos]) } +// LT returns the character at the given offset from the start of the input stream func (is *InputStream) LT(offset int) int { return is.LA(offset) } +// Index returns the current offset in to the input stream func (is *InputStream) Index() int { return is.index } +// Size returns the total number of characters in the input stream func (is *InputStream) Size() int { return is.size } -// mark/release do nothing we have entire buffer +// Mark does nothing here as we have entire buffer func (is *InputStream) Mark() int { return -1 } -func (is *InputStream) Release(marker int) { +// Release does nothing here as we have entire buffer +func (is *InputStream) Release(_ int) { } +// Seek the input point to the provided index offset func (is *InputStream) Seek(index int) { if index <= is.index { is.index = index // just jump don't update stream state (line,...) @@ -81,6 +89,7 @@ func (is *InputStream) Seek(index int) { is.index = intMin(index, is.size) } +// GetText returns the text from the input stream from the start to the stop index func (is *InputStream) GetText(start int, stop int) string { if stop >= is.size { stop = is.size - 1 @@ -92,6 +101,8 @@ func (is *InputStream) GetText(start int, stop int) string { return string(is.data[start : stop+1]) } +// GetTextFromTokens returns the text from the input stream from the first character of the start token to the last +// character of the stop token func (is *InputStream) GetTextFromTokens(start, stop Token) string { if start != nil && stop != nil { return is.GetTextFromInterval(NewInterval(start.GetTokenIndex(), stop.GetTokenIndex())) @@ -105,9 +116,10 @@ func (is *InputStream) GetTextFromInterval(i *Interval) string { } func (*InputStream) GetSourceName() string { - return "Obtained from string" + return "" } +// String returns the entire input stream as a string func (is *InputStream) String() string { return string(is.data) } diff --git a/runtime/Go/antlr/v4/interval_set.go b/runtime/Go/antlr/v4/interval_set.go index c1e155e818..c83daff75b 100644 --- a/runtime/Go/antlr/v4/interval_set.go +++ b/runtime/Go/antlr/v4/interval_set.go @@ -14,7 +14,7 @@ type Interval struct { Stop int } -/* stop is not included! */ +// NewInterval creates a new interval with the given start and stop values. func NewInterval(start, stop int) *Interval { i := new(Interval) @@ -23,10 +23,12 @@ func NewInterval(start, stop int) *Interval { return i } +// Contains returns true if the given item is contained within the interval. func (i *Interval) Contains(item int) bool { return item >= i.Start && item < i.Stop } +// String generates a string representation of the interval. func (i *Interval) String() string { if i.Start == i.Stop-1 { return strconv.Itoa(i.Start) @@ -35,15 +37,18 @@ func (i *Interval) String() string { return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop-1) } -func (i *Interval) length() int { +// Length returns the length of the interval. +func (i *Interval) Length() int { return i.Stop - i.Start } +// IntervalSet represents a collection of [Intervals], which may be read-only. type IntervalSet struct { intervals []*Interval readOnly bool } +// NewIntervalSet creates a new empty, writable, interval set. func NewIntervalSet() *IntervalSet { i := new(IntervalSet) @@ -139,13 +144,13 @@ func (i *IntervalSet) contains(item int) bool { } func (i *IntervalSet) length() int { - len := 0 + iLen := 0 for _, v := range i.intervals { - len += v.length() + iLen += v.Length() } - return len + return iLen } func (i *IntervalSet) removeRange(v *Interval) { diff --git a/runtime/Go/antlr/v4/jcollect.go b/runtime/Go/antlr/v4/jcollect.go index e5a74f0c6c..6f426ebd0a 100644 --- a/runtime/Go/antlr/v4/jcollect.go +++ b/runtime/Go/antlr/v4/jcollect.go @@ -61,7 +61,7 @@ func NewJStore[T any, C Comparator[T]](comparator Comparator[T]) *JStore[T, C] { // # If the given value is already present in the store, then the existing value is returned as v and exists is set to true // // If the given value is not present in the store, then the value is added to the store and returned as v and exists is set to false. -func (s *JStore[T, C]) Put(value T) (v T, exists bool) { //nolint:ireturn +func (s *JStore[T, C]) Put(value T) (v T, exists bool) { kh := s.comparator.Hash1(value) @@ -78,7 +78,7 @@ func (s *JStore[T, C]) Put(value T) (v T, exists bool) { //nolint:ireturn // Get will return the value associated with the key - the type of the key is the same type as the value // which would not generally be useful, but this is a specific thing for ANTLR where the key is // generated using the object we are going to store. -func (s *JStore[T, C]) Get(key T) (T, bool) { //nolint:ireturn +func (s *JStore[T, C]) Get(key T) (T, bool) { kh := s.comparator.Hash1(key) @@ -91,7 +91,7 @@ func (s *JStore[T, C]) Get(key T) (T, bool) { //nolint:ireturn } // Contains returns true if the given key is present in the store -func (s *JStore[T, C]) Contains(key T) bool { //nolint:ireturn +func (s *JStore[T, C]) Contains(key T) bool { _, present := s.Get(key) return present diff --git a/runtime/Go/antlr/v4/lexer.go b/runtime/Go/antlr/v4/lexer.go index 0d81c9d6ac..057e37f9e6 100644 --- a/runtime/Go/antlr/v4/lexer.go +++ b/runtime/Go/antlr/v4/lexer.go @@ -69,7 +69,7 @@ func NewBaseLexer(input CharStream) *BaseLexer { // create a single token. NextToken will return l object after // Matching lexer rule(s). If you subclass to allow multiple token // emissions, then set l to the last token to be Matched or - // something nonnil so that the auto token emit mechanism will not + // something non nil so that the auto token emit mechanism will not // emit another token. lexer.token = nil @@ -111,6 +111,7 @@ const ( LexerSkip = -3 ) +//goland:noinspection GoUnusedConst const ( LexerDefaultTokenChannel = TokenDefaultChannel LexerHidden = TokenHiddenChannel @@ -176,7 +177,7 @@ func (b *BaseLexer) safeMatch() (ret int) { return b.Interpreter.Match(b.input, b.mode) } -// Return a token from l source i.e., Match a token on the char stream. +// NextToken returns a token from the lexer input source i.e., Match a token on the source char stream. func (b *BaseLexer) NextToken() Token { if b.input == nil { panic("NextToken requires a non-nil input stream.") @@ -234,12 +235,11 @@ func (b *BaseLexer) NextToken() Token { } } -// Instruct the lexer to Skip creating a token for current lexer rule -// and look for another token. NextToken() knows to keep looking when -// a lexer rule finishes with token set to SKIPTOKEN. Recall that +// Skip instructs the lexer to Skip creating a token for current lexer rule +// and look for another token. [NextToken] knows to keep looking when +// a lexer rule finishes with token set to [SKIPTOKEN]. Recall that // if token==nil at end of any token rule, it creates one for you // and emits it. -// / func (b *BaseLexer) Skip() { b.thetype = LexerSkip } @@ -248,23 +248,31 @@ func (b *BaseLexer) More() { b.thetype = LexerMore } +// SetMode changes the lexer to a new mode. The lexer will use this mode from hereon in and the rules for that mode +// will be in force. func (b *BaseLexer) SetMode(m int) { b.mode = m } +// PushMode saves the current lexer mode so that it can be restored later. See [PopMode], then sets the +// current lexer mode to the supplied mode m. func (b *BaseLexer) PushMode(m int) { - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("pushMode " + strconv.Itoa(m)) } b.modeStack.Push(b.mode) b.mode = m } +// PopMode restores the lexer mode saved by a call to [PushMode]. It is a panic error if there is no saved mode to +// return to. func (b *BaseLexer) PopMode() int { if len(b.modeStack) == 0 { panic("Empty Stack") } - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("popMode back to " + fmt.Sprint(b.modeStack[0:len(b.modeStack)-1])) } i, _ := b.modeStack.Pop() @@ -289,20 +297,19 @@ func (b *BaseLexer) GetTokenSourceCharStreamPair() *TokenSourceCharStreamPair { return b.tokenFactorySourcePair } -// By default does not support multiple emits per NextToken invocation -// for efficiency reasons. Subclass and override l method, NextToken, -// and GetToken (to push tokens into a list and pull from that list -// rather than a single variable as l implementation does). -// / +// EmitToken by default does not support multiple emits per [NextToken] invocation +// for efficiency reasons. Subclass and override this func, [NextToken], +// and [GetToken] (to push tokens into a list and pull from that list +// rather than a single variable as this implementation does). func (b *BaseLexer) EmitToken(token Token) { b.token = token } -// The standard method called to automatically emit a token at the +// Emit is the standard method called to automatically emit a token at the // outermost lexical rule. The token object should point into the // char buffer start..stop. If there is a text override in 'text', -// use that to set the token's text. Override l method to emit -// custom Token objects or provide a Newfactory. +// use that to set the token's text. Override this method to emit +// custom [Token] objects or provide a new factory. // / func (b *BaseLexer) Emit() Token { t := b.factory.Create(b.tokenFactorySourcePair, b.thetype, b.text, b.channel, b.TokenStartCharIndex, b.GetCharIndex()-1, b.TokenStartLine, b.TokenStartColumn) @@ -310,6 +317,7 @@ func (b *BaseLexer) Emit() Token { return t } +// EmitEOF emits an EOF token. By default, this is the last token emitted func (b *BaseLexer) EmitEOF() Token { cpos := b.GetCharPositionInLine() lpos := b.GetLine() @@ -318,6 +326,7 @@ func (b *BaseLexer) EmitEOF() Token { return eof } +// GetCharPositionInLine returns the current position in the current line as far as the lexer is concerned. func (b *BaseLexer) GetCharPositionInLine() int { return b.Interpreter.GetCharPositionInLine() } @@ -334,13 +343,12 @@ func (b *BaseLexer) SetType(t int) { b.thetype = t } -// What is the index of the current character of lookahead?/// +// GetCharIndex returns the index of the current character of lookahead func (b *BaseLexer) GetCharIndex() int { return b.input.Index() } -// Return the text Matched so far for the current token or any text override. -// Set the complete text of l token it wipes any previous changes to the text. +// GetText returns the text Matched so far for the current token or any text override. func (b *BaseLexer) GetText() string { if b.text != "" { return b.text @@ -349,17 +357,20 @@ func (b *BaseLexer) GetText() string { return b.Interpreter.GetText(b.input) } +// SetText sets the complete text of this token; it wipes any previous changes to the text. func (b *BaseLexer) SetText(text string) { b.text = text } +// GetATN returns the ATN used by the lexer. func (b *BaseLexer) GetATN() *ATN { return b.Interpreter.ATN() } -// Return a list of all Token objects in input char stream. -// Forces load of all tokens. Does not include EOF token. -// / +// GetAllTokens returns a list of all [Token] objects in input char stream. +// Forces a load of all tokens that can be made from the input char stream. +// +// Does not include EOF token. func (b *BaseLexer) GetAllTokens() []Token { vl := b.Virt tokens := make([]Token, 0) @@ -398,11 +409,13 @@ func (b *BaseLexer) getCharErrorDisplay(c rune) string { return "'" + b.getErrorDisplayForChar(c) + "'" } -// Lexers can normally Match any char in it's vocabulary after Matching -// a token, so do the easy thing and just kill a character and hope +// Recover can normally Match any char in its vocabulary after Matching +// a token, so here we do the easy thing and just kill a character and hope // it all works out. You can instead use the rule invocation stack // to do sophisticated error recovery if you are in a fragment rule. -// / +// +// In general, lexers should not need to recover and should have rules that cover any eventuality, such as +// a character that makes no sense to the recognizer. func (b *BaseLexer) Recover(re RecognitionException) { if b.input.LA(1) != TokenEOF { if _, ok := re.(*LexerNoViableAltException); ok { diff --git a/runtime/Go/antlr/v4/lexer_action.go b/runtime/Go/antlr/v4/lexer_action.go index 111656c295..878855c9ab 100644 --- a/runtime/Go/antlr/v4/lexer_action.go +++ b/runtime/Go/antlr/v4/lexer_action.go @@ -7,14 +7,29 @@ package antlr import "strconv" const ( - LexerActionTypeChannel = 0 //The type of a {@link LexerChannelAction} action. - LexerActionTypeCustom = 1 //The type of a {@link LexerCustomAction} action. - LexerActionTypeMode = 2 //The type of a {@link LexerModeAction} action. - LexerActionTypeMore = 3 //The type of a {@link LexerMoreAction} action. - LexerActionTypePopMode = 4 //The type of a {@link LexerPopModeAction} action. - LexerActionTypePushMode = 5 //The type of a {@link LexerPushModeAction} action. - LexerActionTypeSkip = 6 //The type of a {@link LexerSkipAction} action. - LexerActionTypeType = 7 //The type of a {@link LexerTypeAction} action. + // LexerActionTypeChannel represents a [LexerChannelAction] action. + LexerActionTypeChannel = 0 + + // LexerActionTypeCustom represents a [LexerCustomAction] action. + LexerActionTypeCustom = 1 + + // LexerActionTypeMode represents a [LexerModeAction] action. + LexerActionTypeMode = 2 + + // LexerActionTypeMore represents a [LexerMoreAction] action. + LexerActionTypeMore = 3 + + // LexerActionTypePopMode represents a [LexerPopModeAction] action. + LexerActionTypePopMode = 4 + + // LexerActionTypePushMode represents a [LexerPushModeAction] action. + LexerActionTypePushMode = 5 + + // LexerActionTypeSkip represents a [LexerSkipAction] action. + LexerActionTypeSkip = 6 + + // LexerActionTypeType represents a [LexerTypeAction] action. + LexerActionTypeType = 7 ) type LexerAction interface { @@ -39,7 +54,7 @@ func NewBaseLexerAction(action int) *BaseLexerAction { return la } -func (b *BaseLexerAction) execute(lexer Lexer) { +func (b *BaseLexerAction) execute(_ Lexer) { panic("Not implemented") } @@ -59,10 +74,10 @@ func (b *BaseLexerAction) Equals(other LexerAction) bool { return b == other } -// Implements the {@code Skip} lexer action by calling {@link Lexer//Skip}. +// LexerSkipAction implements the [BaseLexerAction.Skip] lexer action by calling [Lexer.Skip]. // -//

The {@code Skip} command does not have any parameters, so l action is -// implemented as a singleton instance exposed by {@link //INSTANCE}.

+// The Skip command does not have any parameters, so this action is +// implemented as a singleton instance exposed by the [LexerSkipActionINSTANCE]. type LexerSkipAction struct { *BaseLexerAction } @@ -73,13 +88,14 @@ func NewLexerSkipAction() *LexerSkipAction { return la } -// Provides a singleton instance of l parameterless lexer action. +// LexerSkipActionINSTANCE provides a singleton instance of this parameterless lexer action. var LexerSkipActionINSTANCE = NewLexerSkipAction() func (l *LexerSkipAction) execute(lexer Lexer) { lexer.Skip() } +// String returns a string representation of the current [LexerSkipAction]. func (l *LexerSkipAction) String() string { return "skip" } @@ -125,11 +141,10 @@ func (l *LexerTypeAction) String() string { return "actionType(" + strconv.Itoa(l.thetype) + ")" } -// Implements the {@code pushMode} lexer action by calling -// {@link Lexer//pushMode} with the assigned mode. +// LexerPushModeAction implements the pushMode lexer action by calling +// [Lexer.pushMode] with the assigned mode. type LexerPushModeAction struct { *BaseLexerAction - mode int } @@ -169,10 +184,10 @@ func (l *LexerPushModeAction) String() string { return "pushMode(" + strconv.Itoa(l.mode) + ")" } -// Implements the {@code popMode} lexer action by calling {@link Lexer//popMode}. +// LexerPopModeAction implements the popMode lexer action by calling [Lexer.popMode]. // -//

The {@code popMode} command does not have any parameters, so l action is -// implemented as a singleton instance exposed by {@link //INSTANCE}.

+// The popMode command does not have any parameters, so this action is +// implemented as a singleton instance exposed by [LexerPopModeActionINSTANCE] type LexerPopModeAction struct { *BaseLexerAction } @@ -224,11 +239,10 @@ func (l *LexerMoreAction) String() string { return "more" } -// Implements the {@code mode} lexer action by calling {@link Lexer//mode} with +// LexerModeAction implements the mode lexer action by calling [Lexer.mode] with // the assigned mode. type LexerModeAction struct { *BaseLexerAction - mode int } @@ -322,16 +336,19 @@ func (l *LexerCustomAction) Equals(other LexerAction) bool { } } -// Implements the {@code channel} lexer action by calling -// {@link Lexer//setChannel} with the assigned channel. -// Constructs a New{@code channel} action with the specified channel value. -// @param channel The channel value to pass to {@link Lexer//setChannel}. +// LexerChannelAction implements the channel lexer action by calling +// [Lexer.setChannel] with the assigned channel. +// +// Constructs a new channel action with the specified channel value. type LexerChannelAction struct { *BaseLexerAction - channel int } +// NewLexerChannelAction creates a channel lexer action by calling +// [Lexer.setChannel] with the assigned channel. +// +// Constructs a new channel action with the specified channel value. func NewLexerChannelAction(channel int) *LexerChannelAction { l := new(LexerChannelAction) l.BaseLexerAction = NewBaseLexerAction(LexerActionTypeChannel) @@ -375,25 +392,22 @@ func (l *LexerChannelAction) String() string { // lexer actions, see {@link LexerActionExecutor//append} and // {@link LexerActionExecutor//fixOffsetBeforeMatch}.

-// Constructs a Newindexed custom action by associating a character offset -// with a {@link LexerAction}. -// -//

Note: This class is only required for lexer actions for which -// {@link LexerAction//isPositionDependent} returns {@code true}.

-// -// @param offset The offset into the input {@link CharStream}, relative to -// the token start index, at which the specified lexer action should be -// executed. -// @param action The lexer action to execute at a particular offset in the -// input {@link CharStream}. type LexerIndexedCustomAction struct { *BaseLexerAction - offset int lexerAction LexerAction isPositionDependent bool } +// NewLexerIndexedCustomAction constructs a new indexed custom action by associating a character offset +// with a [LexerAction]. +// +// Note: This class is only required for lexer actions for which +// [LexerAction.isPositionDependent] returns true. +// +// The offset points into the input [CharStream], relative to +// the token start index, at which the specified lexerAction should be +// executed. func NewLexerIndexedCustomAction(offset int, lexerAction LexerAction) *LexerIndexedCustomAction { l := new(LexerIndexedCustomAction) diff --git a/runtime/Go/antlr/v4/lexer_action_executor.go b/runtime/Go/antlr/v4/lexer_action_executor.go index be1ba7a7e3..05024a8e1b 100644 --- a/runtime/Go/antlr/v4/lexer_action_executor.go +++ b/runtime/Go/antlr/v4/lexer_action_executor.go @@ -38,19 +38,9 @@ func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor { return l } -// Creates a {@link LexerActionExecutor} which executes the actions for -// the input {@code lexerActionExecutor} followed by a specified -// {@code lexerAction}. -// -// @param lexerActionExecutor The executor for actions already traversed by -// the lexer while Matching a token within a particular -// {@link LexerATNConfig}. If this is {@code nil}, the method behaves as -// though it were an empty executor. -// @param lexerAction The lexer action to execute after the actions -// specified in {@code lexerActionExecutor}. -// -// @return A {@link LexerActionExecutor} for executing the combine actions -// of {@code lexerActionExecutor} and {@code lexerAction}. +// LexerActionExecutorappend creates a [LexerActionExecutor] which executes the actions for +// the input [LexerActionExecutor] followed by a specified +// [LexerAction]. func LexerActionExecutorappend(lexerActionExecutor *LexerActionExecutor, lexerAction LexerAction) *LexerActionExecutor { if lexerActionExecutor == nil { return NewLexerActionExecutor([]LexerAction{lexerAction}) @@ -59,34 +49,34 @@ func LexerActionExecutorappend(lexerActionExecutor *LexerActionExecutor, lexerAc return NewLexerActionExecutor(append(lexerActionExecutor.lexerActions, lexerAction)) } -// Creates a {@link LexerActionExecutor} which encodes the current offset +// fixOffsetBeforeMatch creates a [LexerActionExecutor] which encodes the current offset // for position-dependent lexer actions. // -//

Normally, when the executor encounters lexer actions where -// {@link LexerAction//isPositionDependent} returns {@code true}, it calls -// {@link IntStream//seek} on the input {@link CharStream} to set the input -// position to the end of the current token. This behavior provides -// for efficient DFA representation of lexer actions which appear at the end +// Normally, when the executor encounters lexer actions where +// [LexerAction.isPositionDependent] returns true, it calls +// [IntStream.Seek] on the input [CharStream] to set the input +// position to the end of the current token. This behavior provides +// for efficient [DFA] representation of lexer actions which appear at the end // of a lexer rule, even when the lexer rule Matches a variable number of -// characters.

+// characters. // -//

Prior to traversing a Match transition in the ATN, the current offset +// Prior to traversing a Match transition in the [ATN], the current offset // from the token start index is assigned to all position-dependent lexer // actions which have not already been assigned a fixed offset. By storing -// the offsets relative to the token start index, the DFA representation of +// the offsets relative to the token start index, the [DFA] representation of // lexer actions which appear in the middle of tokens remains efficient due -// to sharing among tokens of the same length, regardless of their absolute -// position in the input stream.

+// to sharing among tokens of the same Length, regardless of their absolute +// position in the input stream. // -//

If the current executor already has offsets assigned to all -// position-dependent lexer actions, the method returns {@code this}.

+// If the current executor already has offsets assigned to all +// position-dependent lexer actions, the method returns this instance. // -// @param offset The current offset to assign to all position-dependent +// The offset is assigned to all position-dependent // lexer actions which do not already have offsets assigned. // -// @return A {@link LexerActionExecutor} which stores input stream offsets +// The func returns a [LexerActionExecutor] that stores input stream offsets // for all position-dependent lexer actions. -// / +// func (l *LexerActionExecutor) fixOffsetBeforeMatch(offset int) *LexerActionExecutor { var updatedLexerActions []LexerAction for i := 0; i < len(l.lexerActions); i++ { diff --git a/runtime/Go/antlr/v4/lexer_atn_simulator.go b/runtime/Go/antlr/v4/lexer_atn_simulator.go index c573b75210..98cbb96814 100644 --- a/runtime/Go/antlr/v4/lexer_atn_simulator.go +++ b/runtime/Go/antlr/v4/lexer_atn_simulator.go @@ -10,6 +10,7 @@ import ( "strings" ) +//goland:noinspection GoUnusedGlobalVariable var ( LexerATNSimulatorDebug = false LexerATNSimulatorDFADebug = false @@ -114,7 +115,8 @@ func (l *LexerATNSimulator) reset() { func (l *LexerATNSimulator) MatchATN(input CharStream) int { startState := l.atn.modeToStartState[l.mode] - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("MatchATN mode " + strconv.Itoa(l.mode) + " start: " + startState.String()) } oldMode := l.mode @@ -126,7 +128,8 @@ func (l *LexerATNSimulator) MatchATN(input CharStream) int { predict := l.execATN(input, next) - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("DFA after MatchATN: " + l.decisionToDFA[oldMode].ToLexerString()) } return predict @@ -134,18 +137,20 @@ func (l *LexerATNSimulator) MatchATN(input CharStream) int { func (l *LexerATNSimulator) execATN(input CharStream, ds0 *DFAState) int { - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("start state closure=" + ds0.configs.String()) } if ds0.isAcceptState { - // allow zero-length tokens + // allow zero-Length tokens l.captureSimState(l.prevAccept, input, ds0) } t := input.LA(1) s := ds0 // s is current/from DFA state for { // while more work - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("execATN loop starting closure: " + s.configs.String()) } @@ -188,7 +193,7 @@ func (l *LexerATNSimulator) execATN(input CharStream, ds0 *DFAState) int { } } t = input.LA(1) - s = target // flip current DFA target becomes Newsrc/from state + s = target // flip current DFA target becomes new src/from state } return l.failOrAccept(l.prevAccept, input, s.configs, t) @@ -214,22 +219,19 @@ func (l *LexerATNSimulator) getExistingTargetState(s *DFAState, t int) *DFAState return nil } target := s.getIthEdge(t - LexerATNSimulatorMinDFAEdge) - if LexerATNSimulatorDebug && target != nil { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug && target != nil { fmt.Println("reuse state " + strconv.Itoa(s.stateNumber) + " edge to " + strconv.Itoa(target.stateNumber)) } return target } -// Compute a target state for an edge in the DFA, and attempt to add the -// computed state and corresponding edge to the DFA. +// computeTargetState computes a target state for an edge in the [DFA], and attempt to add the +// computed state and corresponding edge to the [DFA]. // -// @param input The input stream -// @param s The current DFA state -// @param t The next input symbol -// -// @return The computed target DFA state for the given input symbol -// {@code t}. If {@code t} does not lead to a valid DFA state, l method -// returns {@link //ERROR}. +// The func returns the computed target [DFA] state for the given input symbol t. +// If this does not lead to a valid [DFA] state, this method +// returns ATNSimulatorError. func (l *LexerATNSimulator) computeTargetState(input CharStream, s *DFAState, t int) *DFAState { reach := NewOrderedATNConfigSet() @@ -240,7 +242,7 @@ func (l *LexerATNSimulator) computeTargetState(input CharStream, s *DFAState, t if len(reach.configs) == 0 { // we got nowhere on t from s if !reach.hasSemanticContext { // we got nowhere on t, don't panic out l knowledge it'd - // cause a failover from DFA later. + // cause a fail-over from DFA later. l.addDFAEdge(s, t, ATNSimulatorError, nil) } // stop when we can't Match any more char @@ -265,23 +267,25 @@ func (l *LexerATNSimulator) failOrAccept(prevAccept *SimState, input CharStream, panic(NewLexerNoViableAltException(l.recog, input, l.startIndex, reach)) } -// Given a starting configuration set, figure out all ATN configurations -// we can reach upon input {@code t}. Parameter {@code reach} is a return -// parameter. +// getReachableConfigSet when given a starting configuration set, figures out all [ATN] configurations +// we can reach upon input t. +// +// Parameter reach is a return parameter. 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() { - currentAltReachedAcceptState := (cfg.GetAlt() == SkipAlt) + currentAltReachedAcceptState := cfg.GetAlt() == SkipAlt if currentAltReachedAcceptState && cfg.(*LexerATNConfig).passedThroughNonGreedyDecision { continue } - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { - fmt.Printf("testing %s at %s\n", l.GetTokenName(t), cfg.String()) // l.recog, true)) + fmt.Printf("testing %s at %s\n", l.GetTokenName(t), cfg.String()) } for _, trans := range cfg.GetState().GetTransitions() { @@ -291,7 +295,7 @@ func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNC if lexerActionExecutor != nil { lexerActionExecutor = lexerActionExecutor.fixOffsetBeforeMatch(input.Index() - l.startIndex) } - treatEOFAsEpsilon := (t == TokenEOF) + treatEOFAsEpsilon := t == TokenEOF config := NewLexerATNConfig3(cfg.(*LexerATNConfig), target, lexerActionExecutor) if l.closure(input, config, reach, currentAltReachedAcceptState, true, treatEOFAsEpsilon) { @@ -305,7 +309,8 @@ func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNC } func (l *LexerATNSimulator) accept(input CharStream, lexerActionExecutor *LexerActionExecutor, startIndex, index, line, charPos int) { - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Printf("ACTION %v\n", lexerActionExecutor) } // seek to after last char in token @@ -336,25 +341,26 @@ func (l *LexerATNSimulator) computeStartState(input CharStream, p ATNState) *Ord return configs } -// Since the alternatives within any lexer decision are ordered by -// preference, l method stops pursuing the closure as soon as an accept +// closure since the alternatives within any lexer decision are ordered by +// preference, this method stops pursuing the closure as soon as an accept // state is reached. After the first accept state is reached by depth-first -// search from {@code config}, all other (potentially reachable) states for -// l rule would have a lower priority. +// search from config, all other (potentially reachable) states for +// this rule would have a lower priority. // -// @return {@code true} if an accept state is reached, otherwise -// {@code false}. +// The func returns true if an accept state is reached. func (l *LexerATNSimulator) closure(input CharStream, config *LexerATNConfig, configs ATNConfigSet, currentAltReachedAcceptState, speculative, treatEOFAsEpsilon bool) bool { - if LexerATNSimulatorDebug { - fmt.Println("closure(" + config.String() + ")") // config.String(l.recog, true) + ")") + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { + fmt.Println("closure(" + config.String() + ")") } _, ok := config.state.(*RuleStopState) if ok { - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { if l.recog != nil { fmt.Printf("closure at %s rule stop %s\n", l.recog.GetRuleNames()[config.state.GetRuleIndex()], config) } else { @@ -435,7 +441,8 @@ func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNC pt := trans.(*PredicateTransition) - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("EVAL rule " + strconv.Itoa(trans.(*PredicateTransition).ruleIndex) + ":" + strconv.Itoa(pt.predIndex)) } configs.SetHasSemanticContext(true) @@ -476,26 +483,18 @@ func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNC return cfg } -// Evaluate a predicate specified in the lexer. -// -//

If {@code speculative} is {@code true}, l method was called before -// {@link //consume} for the Matched character. This method should call -// {@link //consume} before evaluating the predicate to ensure position -// sensitive values, including {@link Lexer//GetText}, {@link Lexer//GetLine}, -// and {@link Lexer//getcolumn}, properly reflect the current -// lexer state. This method should restore {@code input} and the simulator -// to the original state before returning (i.e. undo the actions made by the -// call to {@link //consume}.

+// evaluatePredicate eEvaluates a predicate specified in the lexer. // -// @param input The input stream. -// @param ruleIndex The rule containing the predicate. -// @param predIndex The index of the predicate within the rule. -// @param speculative {@code true} if the current index in {@code input} is -// one character before the predicate's location. +// If speculative is true, this method was called before +// [consume] for the Matched character. This method should call +// [consume] before evaluating the predicate to ensure position +// sensitive values, including [GetText], [GetLine], +// and [GetColumn], properly reflect the current +// lexer state. This method should restore input and the simulator +// to the original state before returning, i.e. undo the actions made by the +// call to [Consume]. // -// @return {@code true} if the specified predicate evaluates to -// {@code true}. -// / +// The func returns true if the specified predicate evaluates to true. func (l *LexerATNSimulator) evaluatePredicate(input CharStream, ruleIndex, predIndex int, speculative bool) bool { // assume true if no recognizer was provided if l.recog == nil { @@ -554,7 +553,8 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg // Only track edges within the DFA bounds return to } - if LexerATNSimulatorDebug { + if //goland:noinspection GoBoolExpressions + LexerATNSimulatorDebug { fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + strconv.Itoa(tk)) } l.atn.edgeMu.Lock() @@ -620,7 +620,7 @@ func (l *LexerATNSimulator) getDFA(mode int) *DFA { return l.decisionToDFA[mode] } -// Get the text Matched so far for the current token. +// GetText returns the text [Match]ed so far for the current token. func (l *LexerATNSimulator) GetText(input CharStream) string { // index is first lookahead char, don't include. return input.GetTextFromInterval(NewInterval(l.startIndex, input.Index()-1)) diff --git a/runtime/Go/antlr/v4/ll1_analyzer.go b/runtime/Go/antlr/v4/ll1_analyzer.go index 76689615a6..4b46396eff 100644 --- a/runtime/Go/antlr/v4/ll1_analyzer.go +++ b/runtime/Go/antlr/v4/ll1_analyzer.go @@ -14,11 +14,11 @@ func NewLL1Analyzer(atn *ATN) *LL1Analyzer { return la } -// - Special value added to the lookahead sets to indicate that we hit -// a predicate during analysis if {@code seeThruPreds==false}. -// -// / const ( + // LL1AnalyzerHitPred is a special value added to the lookahead sets to indicate that we hit + // a predicate during analysis if + // + // seeThruPreds==false LL1AnalyzerHitPred = TokenInvalidType ) @@ -38,11 +38,12 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { count := len(s.GetTransitions()) look := make([]*IntervalSet, count) for alt := 0; alt < count; alt++ { + look[alt] = NewIntervalSet() lookBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) - seeThruPreds := false // fail to get lookahead upon pred - la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false) - // Wipe out lookahead for la alternative if we found nothing + la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), false, false) + + // Wipe out lookahead for la alternative if we found nothing, // or we had a predicate when we !seeThruPreds if look[alt].length() == 0 || look[alt].contains(LL1AnalyzerHitPred) { look[alt] = nil @@ -51,32 +52,30 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { return look } -// * -// Compute set of tokens that can follow {@code s} in the ATN in the -// specified {@code ctx}. +// Look computes the set of tokens that can follow s in the [ATN] in the +// specified ctx. // -//

If {@code ctx} is {@code nil} and the end of the rule containing -// {@code s} is reached, {@link Token//EPSILON} is added to the result set. -// If {@code ctx} is not {@code nil} and the end of the outermost rule is -// reached, {@link Token//EOF} is added to the result set.

+// If ctx is nil and the end of the rule containing +// s is reached, [EPSILON] is added to the result set. // -// @param s the ATN state -// @param stopState the ATN state to stop at. This can be a -// {@link BlockEndState} to detect epsilon paths through a closure. -// @param ctx the complete parser context, or {@code nil} if the context +// If ctx is not nil and the end of the outermost rule is +// reached, [EOF] is added to the result set. +// +// Parameter s the ATN state, and stopState is the ATN state to stop at. This can be a +// [BlockEndState] to detect epsilon paths through a closure. +// +// Parameter ctx is the complete parser context, or nil if the context // should be ignored // -// @return The set of tokens that can follow {@code s} in the ATN in the -// specified {@code ctx}. -// / +// The func returns the set of tokens that can follow s in the [ATN] in the +// specified ctx. func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet { r := NewIntervalSet() - seeThruPreds := true // ignore preds get all lookahead var lookContext PredictionContext if ctx != nil { lookContext = predictionContextFromRuleContext(s.GetATN(), ctx) } - la.look1(s, stopState, lookContext, r, NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst), NewBitSet(), seeThruPreds, true) + la.look1(s, stopState, lookContext, r, NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst), NewBitSet(), true, true) return r } @@ -110,7 +109,7 @@ 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(s, 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) diff --git a/runtime/Go/antlr/v4/parser.go b/runtime/Go/antlr/v4/parser.go index d26bf06392..bdb11f2468 100644 --- a/runtime/Go/antlr/v4/parser.go +++ b/runtime/Go/antlr/v4/parser.go @@ -48,8 +48,10 @@ type BaseParser struct { _SyntaxErrors int } -// p.is all the parsing support code essentially most of it is error -// recovery stuff.// +// NewBaseParser contains all the parsing support code to embed in parsers. Essentially most of it is error +// recovery stuff. +// +//goland:noinspection GoUnusedExportedFunction func NewBaseParser(input TokenStream) *BaseParser { p := new(BaseParser) @@ -58,39 +60,46 @@ func NewBaseParser(input TokenStream) *BaseParser { // The input stream. p.input = nil + // The error handling strategy for the parser. The default value is a new // instance of {@link DefaultErrorStrategy}. p.errHandler = NewDefaultErrorStrategy() p.precedenceStack = make([]int, 0) p.precedenceStack.Push(0) - // The {@link ParserRuleContext} object for the currently executing rule. + + // The ParserRuleContext object for the currently executing rule. // p.is always non-nil during the parsing process. p.ctx = nil - // Specifies whether or not the parser should construct a parse tree during + + // Specifies whether the parser should construct a parse tree during // the parsing process. The default value is {@code true}. p.BuildParseTrees = true - // When {@link //setTrace}{@code (true)} is called, a reference to the - // {@link TraceListener} is stored here so it can be easily removed in a - // later call to {@link //setTrace}{@code (false)}. The listener itself is + + // When setTrace(true) is called, a reference to the + // TraceListener is stored here, so it can be easily removed in a + // later call to setTrace(false). The listener itself is // implemented as a parser listener so p.field is not directly used by // other parser methods. p.tracer = nil - // The list of {@link ParseTreeListener} listeners registered to receive + + // The list of ParseTreeListener listeners registered to receive // events during the parse. p.parseListeners = nil + // The number of syntax errors Reported during parsing. p.value is - // incremented each time {@link //NotifyErrorListeners} is called. + // incremented each time NotifyErrorListeners is called. p._SyntaxErrors = 0 p.SetInputStream(input) return p } -// p.field maps from the serialized ATN string to the deserialized {@link -// ATN} with +// This field maps from the serialized ATN string to the deserialized [ATN] with // bypass alternatives. // -// @see ATNDeserializationOptions//isGenerateRuleBypassTransitions() +// [ATNDeserializationOptions.isGenerateRuleBypassTransitions] +// +//goland:noinspection GoUnusedGlobalVariable var bypassAltsAtnCache = make(map[string]int) // reset the parser's state// @@ -144,9 +153,9 @@ func (p *BaseParser) Match(ttype int) Token { } else { t = p.errHandler.RecoverInline(p) if p.BuildParseTrees && t.GetTokenIndex() == -1 { - // we must have conjured up a Newtoken during single token - // insertion - // if it's not the current symbol + + // we must have conjured up a new token during single token + // insertion if it's not the current symbol p.ctx.AddErrorNode(t) } } @@ -178,9 +187,8 @@ func (p *BaseParser) MatchWildcard() Token { } else { t = p.errHandler.RecoverInline(p) if p.BuildParseTrees && t.GetTokenIndex() == -1 { - // we must have conjured up a Newtoken during single token - // insertion - // if it's not the current symbol + // we must have conjured up a new token during single token + // insertion if it's not the current symbol p.ctx.AddErrorNode(t) } } @@ -202,33 +210,27 @@ func (p *BaseParser) GetParseListeners() []ParseTreeListener { return p.parseListeners } -// Registers {@code listener} to receive events during the parsing process. +// AddParseListener registers listener to receive events during the parsing process. // -//

To support output-preserving grammar transformations (including but not +// To support output-preserving grammar transformations (including but not // limited to left-recursion removal, automated left-factoring, and // optimized code generation), calls to listener methods during the parse // may differ substantially from calls made by -// {@link ParseTreeWalker//DEFAULT} used after the parse is complete. In +// [ParseTreeWalker.DEFAULT] used after the parse is complete. In // particular, rule entry and exit events may occur in a different order // during the parse than after the parser. In addition, calls to certain -// rule entry methods may be omitted.

+// rule entry methods may be omitted. // -//

With the following specific exceptions, calls to listener events are -// deterministic, i.e. for identical input the calls to listener -// methods will be the same.

+// With the following specific exceptions, calls to listener events are +// deterministic, i.e. for identical input the calls to listener +// methods will be the same. // -//
    -//
  • Alterations to the grammar used to generate code may change the -// behavior of the listener calls.
  • -//
  • Alterations to the command line options passed to ANTLR 4 when -// generating the parser may change the behavior of the listener calls.
  • -//
  • Changing the version of the ANTLR Tool used to generate the parser -// may change the behavior of the listener calls.
  • -//
-// -// @param listener the listener to add -// -// @panics nilPointerException if {@code} listener is {@code nil} +// - Alterations to the grammar used to generate code may change the +// behavior of the listener calls. +// - Alterations to the command line options passed to ANTLR 4 when +// generating the parser may change the behavior of the listener calls. +// - Changing the version of the ANTLR Tool used to generate the parser +// may change the behavior of the listener calls. func (p *BaseParser) AddParseListener(listener ParseTreeListener) { if listener == nil { panic("listener") @@ -239,11 +241,10 @@ func (p *BaseParser) AddParseListener(listener ParseTreeListener) { p.parseListeners = append(p.parseListeners, listener) } -// Remove {@code listener} from the list of parse listeners. +// RemoveParseListener removes listener from the list of parse listeners. // -//

If {@code listener} is {@code nil} or has not been added as a parse -// listener, p.method does nothing.

-// @param listener the listener to remove +// If listener is nil or has not been added as a parse +// listener, this func does nothing. func (p *BaseParser) RemoveParseListener(listener ParseTreeListener) { if p.parseListeners != nil { @@ -274,7 +275,7 @@ func (p *BaseParser) removeParseListeners() { p.parseListeners = nil } -// Notify any parse listeners of an enter rule event. +// TriggerEnterRuleEvent notifies all parse listeners of an enter rule event. func (p *BaseParser) TriggerEnterRuleEvent() { if p.parseListeners != nil { ctx := p.ctx @@ -285,9 +286,7 @@ func (p *BaseParser) TriggerEnterRuleEvent() { } } -// Notify any parse listeners of an exit rule event. -// -// @see //addParseListener +// TriggerExitRuleEvent notifies any parse listeners of an exit rule event. func (p *BaseParser) TriggerExitRuleEvent() { if p.parseListeners != nil { // reverse order walk of listeners @@ -314,19 +313,16 @@ func (p *BaseParser) GetTokenFactory() TokenFactory { return p.input.GetTokenSource().GetTokenFactory() } -// Tell our token source and error strategy about a Newway to create tokens.// +// setTokenFactory is used to tell our token source and error strategy about a new way to create tokens. func (p *BaseParser) setTokenFactory(factory TokenFactory) { p.input.GetTokenSource().setTokenFactory(factory) } -// The ATN with bypass alternatives is expensive to create so we create it +// GetATNWithBypassAlts - the ATN with bypass alternatives is expensive to create, so we create it // lazily. -// -// @panics UnsupportedOperationException if the current parser does not -// implement the {@link //getSerializedATN()} method. func (p *BaseParser) GetATNWithBypassAlts() { - // TODO + // TODO - Implement this? panic("Not implemented!") // serializedAtn := p.getSerializedATN() @@ -354,6 +350,7 @@ func (p *BaseParser) GetATNWithBypassAlts() { // String id = m.Get("ID") // +//goland:noinspection GoUnusedParameter func (p *BaseParser) compileParseTreePattern(pattern, patternRuleIndex, lexer Lexer) { panic("NewParseTreePatternMatcher not implemented!") @@ -386,14 +383,16 @@ func (p *BaseParser) GetTokenStream() TokenStream { return p.input } -// Set the token stream and reset the parser.// +// SetTokenStream installs input as the token stream and resets the parser. func (p *BaseParser) SetTokenStream(input TokenStream) { p.input = nil p.reset() p.input = input } -// Match needs to return the current input symbol, which gets put +// GetCurrentToken returns the current token at LT(1). +// +// [Match] needs to return the current input symbol, which gets put // into the label for the associated token ref e.g., x=ID. func (p *BaseParser) GetCurrentToken() Token { return p.input.LT(1) @@ -446,7 +445,7 @@ func (p *BaseParser) addContextToParseTree() { } } -func (p *BaseParser) EnterRule(localctx ParserRuleContext, state, ruleIndex int) { +func (p *BaseParser) EnterRule(localctx ParserRuleContext, state, _ int) { p.SetState(state) p.ctx = localctx p.ctx.SetStart(p.input.LT(1)) @@ -474,7 +473,7 @@ func (p *BaseParser) ExitRule() { func (p *BaseParser) EnterOuterAlt(localctx ParserRuleContext, altNum int) { localctx.SetAltNumber(altNum) - // if we have Newlocalctx, make sure we replace existing ctx + // if we have a new localctx, make sure we replace existing ctx // that is previous child of parse tree if p.BuildParseTrees && p.ctx != localctx { if p.ctx.GetParent() != nil { @@ -498,7 +497,7 @@ func (p *BaseParser) GetPrecedence() int { return p.precedenceStack[len(p.precedenceStack)-1] } -func (p *BaseParser) EnterRecursionRule(localctx ParserRuleContext, state, ruleIndex, precedence int) { +func (p *BaseParser) EnterRecursionRule(localctx ParserRuleContext, state, _, precedence int) { p.SetState(state) p.precedenceStack.Push(precedence) p.ctx = localctx @@ -512,7 +511,7 @@ func (p *BaseParser) EnterRecursionRule(localctx ParserRuleContext, state, ruleI // // Like {@link //EnterRule} but for recursive rules. -func (p *BaseParser) PushNewRecursionContext(localctx ParserRuleContext, state, ruleIndex int) { +func (p *BaseParser) PushNewRecursionContext(localctx ParserRuleContext, state, _ int) { previous := p.ctx previous.SetParent(localctx) previous.SetInvokingState(state) @@ -530,7 +529,7 @@ func (p *BaseParser) PushNewRecursionContext(localctx ParserRuleContext, state, } func (p *BaseParser) UnrollRecursionContexts(parentCtx ParserRuleContext) { - p.precedenceStack.Pop() + _, _ = p.precedenceStack.Pop() p.ctx.SetStop(p.input.LT(-1)) retCtx := p.ctx // save current ctx (return value) // unroll so ctx is as it was before call to recursive method @@ -561,29 +560,22 @@ func (p *BaseParser) GetInvokingContext(ruleIndex int) ParserRuleContext { return nil } -func (p *BaseParser) Precpred(localctx RuleContext, precedence int) bool { +func (p *BaseParser) Precpred(_ RuleContext, precedence int) bool { return precedence >= p.precedenceStack[len(p.precedenceStack)-1] } +//goland:noinspection GoUnusedParameter func (p *BaseParser) inContext(context ParserRuleContext) bool { // TODO: useful in parser? return false } -// -// Checks whether or not {@code symbol} can follow the current state in the -// ATN. The behavior of p.method is equivalent to the following, but is +// IsExpectedToken checks whether symbol can follow the current state in the +// {ATN}. The behavior of p.method is equivalent to the following, but is // implemented such that the complete context-sensitive follow set does not // need to be explicitly constructed. // -//
-// return getExpectedTokens().contains(symbol)
-// 
-// -// @param symbol the symbol type to check -// @return {@code true} if {@code symbol} can follow the current state in -// the ATN, otherwise {@code false}. - +// return getExpectedTokens().contains(symbol) func (p *BaseParser) IsExpectedToken(symbol int) bool { atn := p.Interpreter.atn ctx := p.ctx @@ -611,11 +603,9 @@ func (p *BaseParser) IsExpectedToken(symbol int) bool { return false } -// Computes the set of input symbols which could follow the current parser -// state and context, as given by {@link //GetState} and {@link //GetContext}, +// GetExpectedTokens and returns the set of input symbols which could follow the current parser +// state and context, as given by [GetState] and [GetContext], // respectively. -// -// @see ATN//getExpectedTokens(int, RuleContext) func (p *BaseParser) GetExpectedTokens() *IntervalSet { return p.Interpreter.atn.getExpectedTokens(p.state, p.ctx) } @@ -626,7 +616,7 @@ func (p *BaseParser) GetExpectedTokensWithinCurrentRule() *IntervalSet { return atn.NextTokens(s, nil) } -// Get a rule's index (i.e., {@code RULE_ruleName} field) or -1 if not found.// +// GetRuleIndex get a rule's index (i.e., RULE_ruleName field) or -1 if not found. func (p *BaseParser) GetRuleIndex(ruleName string) int { var ruleIndex, ok = p.GetRuleIndexMap()[ruleName] if ok { @@ -636,13 +626,10 @@ func (p *BaseParser) GetRuleIndex(ruleName string) int { return -1 } -// Return List<String> of the rule names in your parser instance +// GetRuleInvocationStack returns a list of the rule names in your parser instance // leading up to a call to the current rule. You could override if // you want more details such as the file/line info of where // in the ATN a rule is invoked. -// -// this very useful for error messages. - func (p *BaseParser) GetRuleInvocationStack(c ParserRuleContext) []string { if c == nil { c = p.ctx @@ -668,12 +655,12 @@ func (p *BaseParser) GetRuleInvocationStack(c ParserRuleContext) []string { return stack } -// For debugging and other purposes.// +// GetDFAStrings returns a list of all DFA states used for debugging purposes func (p *BaseParser) GetDFAStrings() string { return fmt.Sprint(p.Interpreter.decisionToDFA) } -// For debugging and other purposes.// +// DumpDFA prints the whole of the DFA for debugging func (p *BaseParser) DumpDFA() { seenOne := false for _, dfa := range p.Interpreter.decisionToDFA { @@ -692,8 +679,10 @@ func (p *BaseParser) GetSourceName() string { return p.GrammarFileName } -// During a parse is sometimes useful to listen in on the rule entry and exit -// events as well as token Matches. p.is for quick and dirty debugging. +// SetTrace installs a trace listener for the parse. +// +// During a parse it is sometimes useful to listen in on the rule entry and exit +// events as well as token Matches. This is for quick and dirty debugging. func (p *BaseParser) SetTrace(trace *TraceListener) { if trace == nil { p.RemoveParseListener(p.tracer) diff --git a/runtime/Go/antlr/v4/parser_atn_simulator.go b/runtime/Go/antlr/v4/parser_atn_simulator.go index 8bcc46a0d9..0aea7c3eab 100644 --- a/runtime/Go/antlr/v4/parser_atn_simulator.go +++ b/runtime/Go/antlr/v4/parser_atn_simulator.go @@ -30,6 +30,7 @@ type ParserATNSimulator struct { outerContext ParserRuleContext } +//goland:noinspection GoUnusedExportedFunction func NewParserATNSimulator(parser Parser, atn *ATN, decisionToDFA []*DFA, sharedContextCache *PredictionContextCache) *ParserATNSimulator { p := new(ParserATNSimulator) @@ -46,12 +47,12 @@ 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 - // isn't Synchronized but we're ok since two threads shouldn't reuse same - // parser/atnsim object because it can only handle one input at a time. - // This maps graphs a and b to merged result c. (a,b)&rarrc. We can avoid - // the merge if we ever see a and b again. Note that (b,a)&rarrc should - // also be examined during cache lookup. + // Don't keep around as it wastes huge amounts of memory. DoubleKeyMap + // 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 + // the merge if we ever see a and b again. Note that (b,a) -> c should + // also be examined during cache lookup. // p.mergeCache = nil @@ -69,6 +70,7 @@ func (p *ParserATNSimulator) SetPredictionMode(v int) { func (p *ParserATNSimulator) reset() { } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, outerContext ParserRuleContext) int { if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("adaptivePredict decision " + strconv.Itoa(decision) + @@ -150,36 +152,40 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou } -// Performs ATN simulation to compute a predicted alternative based -// upon the remaining input, but also updates the DFA cache to avoid -// having to traverse the ATN again for the same input sequence. - +// execATN performs ATN simulation to compute a predicted alternative based +// upon the remaining input, but also updates the DFA cache to avoid +// having to traverse the ATN again for the same input sequence. +// // There are some key conditions we're looking for after computing a new // set of ATN configs (proposed DFA state): -// if the set is empty, there is no viable alternative for current symbol -// does the state uniquely predict an alternative? -// does the state have a conflict that would prevent us from -// putting it on the work list? - +// +// - If the set is empty, there is no viable alternative for current symbol +// - Does the state uniquely predict an alternative? +// - Does the state have a conflict that would prevent us from +// putting it on the work list? +// // We also have some key operations to do: -// add an edge from previous DFA state to potentially NewDFA state, D, -// upon current symbol but only if adding to work list, which means in all -// cases except no viable alternative (and possibly non-greedy decisions?) -// collecting predicates and adding semantic context to DFA accept states -// adding rule context to context-sensitive DFA accept states -// consuming an input symbol -// Reporting a conflict -// Reporting an ambiguity -// Reporting a context sensitivity -// Reporting insufficient predicates - -// cover these cases: // -// dead end -// single alt -// single alt + preds -// conflict -// conflict + preds +// - Add an edge from previous DFA state to potentially NewDFA state, D, +// - Upon current symbol but only if adding to work list, which means in all +// cases except no viable alternative (and possibly non-greedy decisions?) +// - Collecting predicates and adding semantic context to DFA accept states +// - adding rule context to context-sensitive DFA accept states +// - Consuming an input symbol +// - Reporting a conflict +// - Reporting an ambiguity +// - Reporting a context sensitivity +// - Reporting insufficient predicates +// +// Cover these cases: +// +// - dead end +// - single alt +// - single alt + predicates +// - conflict +// - conflict + predicates +// +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, startIndex int, outerContext ParserRuleContext) int { if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { @@ -224,7 +230,7 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, conflictingAlts := D.configs.GetConflictingAlts() if D.predicates != nil { if ParserATNSimulatorDebug { - fmt.Println("DFA state has preds in DFA sim LL failover") + fmt.Println("DFA state has preds in DFA sim LL fail-over") } conflictIndex := input.Index() if conflictIndex != startIndex { @@ -314,7 +320,8 @@ func (p *ParserATNSimulator) getExistingTargetState(previousD *DFAState, t int) // @return The computed target DFA state for the given input symbol // {@code t}. If {@code t} does not lead to a valid DFA state, p method // returns {@link //ERROR}. - +// +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) computeTargetState(dfa *DFA, previousD *DFAState, t int) *DFAState { reach := p.computeReachSet(previousD.configs, t, false) @@ -322,7 +329,7 @@ func (p *ParserATNSimulator) computeTargetState(dfa *DFA, previousD *DFAState, t p.addDFAEdge(dfa, previousD, t, ATNSimulatorError) return ATNSimulatorError } - // create Newtarget state we'll add to DFA after it's complete + // create new target state we'll add to DFA after it's complete D := NewDFAState(-1, reach) predictedAlt := p.getUniqueAlt(reach) @@ -381,6 +388,8 @@ 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 { if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { @@ -469,7 +478,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT // // For example, we might know that we have conflicting configurations. // But, that does not mean that there is no way forward without a - // conflict. It's possible to have nonconflicting alt subsets as in: + // conflict. It's possible to have non-conflicting alt subsets as in: // altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}] @@ -490,6 +499,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT return predictedAlt } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCtx bool) ATNConfigSet { if p.mergeCache == nil { p.mergeCache = NewDoubleDict() @@ -588,7 +598,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // // This is handled before the configurations in SkippedStopStates, // because any configurations potentially added from that list are - // already guaranteed to meet p condition whether or not it's + // already guaranteed to meet this condition whether it's // required. // reach = p.removeAllConfigsNotInRuleStopState(reach, reach == intermediate) @@ -618,24 +628,23 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt return reach } -// Return a configuration set containing only the configurations from -// {@code configs} which are in a {@link RuleStopState}. If all -// configurations in {@code configs} are already in a rule stop state, p -// method simply returns {@code configs}. +// removeAllConfigsNotInRuleStopState returns a configuration set containing only the configurations from +// configs which are in a [RuleStopState]. If all +// configurations in configs are already in a rule stop state, this +// method simply returns configs. // -//

When {@code lookToEndOfRule} is true, p method uses -// {@link ATN//NextTokens} for each configuration in {@code configs} which is +// When lookToEndOfRule is true, this method uses +// [ATN].[NextTokens] for each configuration in configs which is // not already in a rule stop state to see if a rule stop state is reachable -// from the configuration via epsilon-only transitions.

+// from the configuration via epsilon-only transitions. // -// @param configs the configuration set to update -// @param lookToEndOfRule when true, p method checks for rule stop states +// When lookToEndOfRule is true, this method checks for rule stop states // reachable by epsilon-only transitions from each configuration in -// {@code configs}. +// configs. // -// @return {@code configs} if all configurations in {@code configs} are in a -// rule stop state, otherwise return a Newconfiguration set containing only -// the configurations from {@code configs} which are in a rule stop state +// 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 { if PredictionModeallConfigsInRuleStopStates(configs) { return configs @@ -657,6 +666,7 @@ func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfi return result } +//goland:noinspection GoBoolExpressions 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) @@ -675,60 +685,49 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full return configs } -// This method transforms the start state computed by -// {@link //computeStartState} to the special start state used by a -// precedence DFA for a particular precedence value. The transformation +// applyPrecedenceFilter transforms the start state computed by +// [computeStartState] to the special start state used by a +// precedence [DFA] for a particular precedence value. The transformation // process applies the following changes to the start state's configuration // set. // -//
    -//
  1. Evaluate the precedence predicates for each configuration using -// {@link SemanticContext//evalPrecedence}.
  2. -//
  3. Remove all configurations which predict an alternative greater than -// 1, for which another configuration that predicts alternative 1 is in the -// same ATN state with the same prediction context. This transformation is -// valid for the following reasons: -//
      -//
    • The closure block cannot contain any epsilon transitions which bypass -// the body of the closure, so all states reachable via alternative 1 are -// part of the precedence alternatives of the transformed left-recursive -// rule.
    • -//
    • The "primary" portion of a left recursive rule cannot contain an -// epsilon transition, so the only way an alternative other than 1 can exist -// in a state that is also reachable via alternative 1 is by nesting calls -// to the left-recursive rule, with the outer calls not being at the -// preferred precedence level.
    • -//
    -//
  4. -//
+// 1. Evaluate the precedence predicates for each configuration using +// [SemanticContext].evalPrecedence. +// 2. Remove all configurations which predict an alternative greater than +// 1, for which another configuration that predicts alternative 1 is in the +// same ATN state with the same prediction context. +// +// Transformation 2 is valid for the following reasons: +// +// - The closure block cannot contain any epsilon transitions which bypass +// the body of the closure, so all states reachable via alternative 1 are +// part of the precedence alternatives of the transformed left-recursive +// rule. +// - The "primary" portion of a left recursive rule cannot contain an +// epsilon transition, so the only way an alternative other than 1 can exist +// in a state that is also reachable via alternative 1 is by nesting calls +// to the left-recursive rule, with the outer calls not being at the +// preferred precedence level. +// +// The prediction context must be considered by this filter to address +// situations like the following: +// +// grammar TA +// prog: statement* EOF +// statement: letterA | statement letterA 'b' +// letterA: 'a' // -//

-// The prediction context must be considered by p filter to address -// situations like the following. -//

-// -//
-// grammar TA
-// prog: statement* EOF
-// statement: letterA | statement letterA 'b'
-// letterA: 'a'
-// 
-//
-//

-// If the above grammar, the ATN state immediately before the token -// reference {@code 'a'} in {@code letterA} is reachable from the left edge +// In the above grammar, the [ATN] state immediately before the token +// reference 'a' in letterA is reachable from the left edge // of both the primary and closure blocks of the left-recursive rule -// {@code statement}. The prediction context associated with each of these +// statement. The prediction context associated with each of these // configurations distinguishes between them, and prevents the alternative -// which stepped out to {@code prog} (and then back in to {@code statement} +// which stepped out to prog, and then back in to statement // from being eliminated by the filter. -//

// -// @param configs The configuration set computed by -// {@link //computeStartState} as the start state for the DFA. -// @return The transformed configuration set representing the start state -// for a precedence DFA at a particular precedence level (determined by -// calling {@link Parser//getPrecedence}). +// 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 { statesFromAlt1 := make(map[int]PredictionContext) @@ -780,6 +779,7 @@ func (p *ParserATNSimulator) getReachableTarget(trans Transition, ttype int) ATN return nil } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs ATNConfigSet, nalts int) []SemanticContext { altToPred := make([]SemanticContext, nalts+1) @@ -797,7 +797,7 @@ func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs ATN nPredAlts++ } } - // nonambig alts are nil in altToPred + // unambiguous alts are nil in altToPred if nPredAlts == 0 { altToPred = nil } @@ -812,7 +812,7 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre containsPredicate := false for i := 1; i < len(altToPred); i++ { pred := altToPred[i] - // unpredicated is indicated by SemanticContextNONE + // un-predicated is indicated by SemanticContextNONE if ambigAlts != nil && ambigAlts.contains(i) { pairs = append(pairs, NewPredPrediction(pred, i)) } @@ -826,50 +826,41 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre return pairs } -// This method is used to improve the localization of error messages by -// choosing an alternative rather than panicing a -// {@link NoViableAltException} in particular prediction scenarios where the -// {@link //ERROR} state was reached during ATN simulation. +// getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule is used to improve the localization of error messages by +// choosing an alternative rather than panic a NoViableAltException in particular prediction scenarios where the +// Error state was reached during [ATN] simulation. // -//

-// The default implementation of p method uses the following -// algorithm to identify an ATN configuration which successfully parsed the +// The default implementation of this method uses the following +// algorithm to identify an [ATN] configuration which successfully parsed the // decision entry rule. Choosing such an alternative ensures that the -// {@link ParserRuleContext} returned by the calling rule will be complete +// [ParserRuleContext] returned by the calling rule will be complete // and valid, and the syntax error will be Reported later at a more -// localized location.

+// localized location. // -//
    -//
  • If a syntactically valid path or paths reach the end of the decision rule and -// they are semantically valid if predicated, return the min associated alt.
  • -//
  • Else, if a semantically invalid but syntactically valid path exist -// or paths exist, return the minimum associated alt. -//
  • -//
  • Otherwise, return {@link ATN//INVALID_ALT_NUMBER}.
  • -//
+// - If a syntactically valid path or paths reach the end of the decision rule, and +// they are semantically valid if predicated, return the min associated alt. +// - Else, if a semantically invalid but syntactically valid path exist +// or paths exist, return the minimum associated alt. +// - Otherwise, return [ATNInvalidAltNumber]. // -//

// In some scenarios, the algorithm described above could predict an -// alternative which will result in a {@link FailedPredicateException} in -// the parser. Specifically, p could occur if the only configuration +// alternative which will result in a [FailedPredicateException] in +// the parser. Specifically, this could occur if the only configuration // capable of successfully parsing to the end of the decision rule is -// blocked by a semantic predicate. By choosing p alternative within -// {@link //AdaptivePredict} instead of panicing a -// {@link NoViableAltException}, the resulting -// {@link FailedPredicateException} in the parser will identify the specific +// blocked by a semantic predicate. By choosing this alternative within +// [AdaptivePredict] instead of panic a [NoViableAltException], the resulting +// [FailedPredicateException] in the parser will identify the specific // predicate which is preventing the parser from successfully parsing the // decision rule, which helps developers identify and correct logic errors // in semantic predicates. -//

// -// @param configs The ATN configurations which were valid immediately before -// the {@link //ERROR} state was reached -// @param outerContext The is the \gamma_0 initial parser context from the paper +// pass in the configs holding ATN configurations which were valid immediately before +// the ERROR state was reached, outerContext as the initial parser context from the paper // or the parser stack at the instant before prediction commences. // -// @return The value to return from {@link //AdaptivePredict}, or -// {@link ATN//INVALID_ALT_NUMBER} if a suitable alternative was not -// identified and {@link //AdaptivePredict} should Report an error instead. +// 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 { cfgs := p.splitAccordingToSemanticValidity(configs, outerContext) semValidConfigs := cfgs[0] @@ -937,12 +928,13 @@ func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigS return []ATNConfigSet{succeeded, failed} } -// Look through a list of predicate/alt pairs, returning alts for the +// evalSemanticContext looks through a list of predicate/alt pairs, returning alts for the +// pairs that win. A [SemanticContextNone] predicate indicates an alt containing an +// un-predicated config which behaves as "always true." If !complete +// then we stop at the first predicate that evaluates to true. This +// includes pairs with nil predicates. // -// pairs that win. A {@code NONE} predicate indicates an alt containing an -// unpredicated config which behaves as "always true." If !complete -// then we stop at the first predicate that evaluates to true. This -// includes pairs with nil predicates. +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPrediction, outerContext ParserRuleContext, complete bool) *BitSet { predictions := NewBitSet() for i := 0; i < len(predPredictions); i++ { @@ -978,6 +970,7 @@ func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, clo 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) { if ParserATNSimulatorTraceATNSim { fmt.Println("closure(" + config.String() + ")") @@ -1030,7 +1023,9 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs p.closureWork(config, configs, closureBusy, collectPredicates, fullCtx, depth, treatEOFAsEpsilon) } -// Do the actual work of walking epsilon edges// +// 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) { state := config.GetState() // optimization @@ -1098,6 +1093,7 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, } } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNConfig) bool { if TurnOffLRLoopEntryBranchOpt { return false @@ -1223,6 +1219,7 @@ func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, co } } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) actionTransition(config ATNConfig, t *ActionTransition) *BaseATNConfig { if ParserATNSimulatorDebug { fmt.Println("ACTION edge " + strconv.Itoa(t.ruleIndex) + ":" + strconv.Itoa(t.actionIndex)) @@ -1230,6 +1227,7 @@ func (p *ParserATNSimulator) actionTransition(config ATNConfig, t *ActionTransit return NewBaseATNConfig4(config, t.getTarget()) } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, pt *PrecedencePredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { @@ -1267,6 +1265,7 @@ func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, return c } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { if ParserATNSimulatorDebug { @@ -1303,6 +1302,7 @@ func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTrans return c } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) ruleTransition(config ATNConfig, t *RuleTransition) *BaseATNConfig { if ParserATNSimulatorDebug { fmt.Println("CALL rule " + p.getRuleName(t.getTarget().GetRuleIndex()) + ", ctx=" + config.GetContext().String()) @@ -1317,42 +1317,55 @@ func (p *ParserATNSimulator) getConflictingAlts(configs ATNConfigSet) *BitSet { return PredictionModeGetAlts(altsets) } -// Sam pointed out a problem with the previous definition, v3, of +// getConflictingAltsOrUniqueAlt Sam pointed out a problem with the previous definition, v3, of // ambiguous states. If we have another state associated with conflicting // alternatives, we should keep going. For example, the following grammar // -// s : (ID | ID ID?) '' +// s : (ID | ID ID?) ; +// +// When the [ATN] simulation reaches the state before ;, it has a [DFA] +// state that looks like: +// +// [12|1|[], 6|2|[], 12|2|[]]. +// +// Naturally +// +// 12|1|[] and 12|2|[] +// +// conflict, but we cannot stop processing this node +// because alternative to has another way to continue, via +// +// [6|2|[]]. // -// When the ATN simulation reaches the state before '', it has a DFA -// state that looks like: [12|1|[], 6|2|[], 12|2|[]]. Naturally -// 12|1|[] and 12|2|[] conflict, but we cannot stop processing p node -// because alternative to has another way to continue, via [6|2|[]]. // The key is that we have a single state that has config's only associated // with a single alternative, 2, and crucially the state transitions // among the configurations are all non-epsilon transitions. That means // we don't consider any conflicts that include alternative 2. So, we // ignore the conflict between alts 1 and 2. We ignore a set of // conflicting alts when there is an intersection with an alternative -// associated with a single alt state in the state&rarrconfig-list map. +// associated with a single alt state in the state config-list map. // // It's also the case that we might have two conflicting configurations but -// also a 3rd nonconflicting configuration for a different alternative: -// [1|1|[], 1|2|[], 8|3|[]]. This can come about from grammar: +// also a 3rd non-conflicting configuration for a different alternative: +// +// [1|1|[], 1|2|[], 8|3|[]]. // -// a : A | A | A B +// This can come about from grammar: +// +// a : A | A | A B // // After Matching input A, we reach the stop state for rule A, state 1. // State 8 is the state right before B. Clearly alternatives 1 and 2 // conflict and no amount of further lookahead will separate the two. -// However, alternative 3 will be able to continue and so we do not -// stop working on p state. In the previous example, we're concerned +// However, alternative 3 will be able to continue, so we do not +// stop working on this state. +// +// In the previous example, we're concerned // with states associated with the conflicting alternatives. Here alt // 3 is not associated with the conflicting configs, but since we can continue // 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 { var conflictingAlts *BitSet if configs.GetUniqueAlt() != ATNInvalidAltNumber { @@ -1384,11 +1397,11 @@ func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string { return p.GetTokenName(input.LA(1)) } -// Used for debugging in AdaptivePredict around execATN but I cut +// 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. -func (p *ParserATNSimulator) dumpDeadEndConfigs(nvae *NoViableAltException) { +func (p *ParserATNSimulator) dumpDeadEndConfigs(_ *NoViableAltException) { panic("Not implemented") @@ -1452,6 +1465,8 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int { // @return If {@code to} is {@code nil}, p method returns {@code nil} // otherwise p method returns the result of calling {@link //addDFAState} // on {@code to} +// +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFAState) *DFAState { if ParserATNSimulatorDebug { fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + p.GetTokenName(t)) @@ -1483,19 +1498,15 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA return to } -// Add state {@code D} to the DFA if it is not already present, and return -// the actual instance stored in the DFA. If a state equivalent to {@code D} -// is already in the DFA, the existing state is returned. Otherwise p -// method returns {@code D} after adding it to the DFA. +// addDFAState adds state D to the [DFA] if it is not already present, and returns +// the actual instance stored in the [DFA]. If a state equivalent to D +// is already in the [DFA], the existing state is returned. Otherwise, this +// method returns D after adding it to the [DFA]. // -//

If {@code D} is {@link //ERROR}, p method returns {@link //ERROR} and -// does not change the DFA.

+// If D is [ATNSimulatorError], this method returns [ATNSimulatorError] and +// does not change the DFA. // -// @param dfa The dfa -// @param D The DFA state to add -// @return The state stored in the DFA. This will be either the existing -// state if {@code D} is already in the DFA, or {@code D} itself if the -// state was not already present. +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState { if d == ATNSimulatorError { return d @@ -1523,6 +1534,7 @@ func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState { return d } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) ReportAttemptingFullContext(dfa *DFA, conflictingAlts *BitSet, configs ATNConfigSet, startIndex, stopIndex int) { if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { interval := NewInterval(startIndex, stopIndex+1) @@ -1534,6 +1546,7 @@ func (p *ParserATNSimulator) ReportAttemptingFullContext(dfa *DFA, conflictingAl } } +//goland:noinspection GoBoolExpressions func (p *ParserATNSimulator) ReportContextSensitivity(dfa *DFA, prediction int, configs ATNConfigSet, startIndex, stopIndex int) { if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { interval := NewInterval(startIndex, stopIndex+1) @@ -1545,8 +1558,13 @@ func (p *ParserATNSimulator) ReportContextSensitivity(dfa *DFA, prediction int, } } -// If context sensitive parsing, we know it's ambiguity not conflict// -func (p *ParserATNSimulator) ReportAmbiguity(dfa *DFA, D *DFAState, startIndex, stopIndex int, +// ReportAmbiguity reports and ambiguity in the parse, which shows that the parser will explore a different route. +// +// If context-sensitive parsing, we know it's an ambiguity not a conflict or error, but we can report it to the developer +// so that they can see that this is happening and can take action if they want to. +// +//goland:noinspection GoBoolExpressions +func (p *ParserATNSimulator) ReportAmbiguity(dfa *DFA, _ *DFAState, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { interval := NewInterval(startIndex, stopIndex+1) diff --git a/runtime/Go/antlr/v4/parser_rule_context.go b/runtime/Go/antlr/v4/parser_rule_context.go index 1c8cee7479..2e37e1f022 100644 --- a/runtime/Go/antlr/v4/parser_rule_context.go +++ b/runtime/Go/antlr/v4/parser_rule_context.go @@ -90,14 +90,15 @@ func (prc *BaseParserRuleContext) GetText() string { return s } -// Double dispatch methods for listeners -func (prc *BaseParserRuleContext) EnterRule(listener ParseTreeListener) { +// EnterRule is called when any rule is entered. +func (prc *BaseParserRuleContext) EnterRule(_ ParseTreeListener) { } -func (prc *BaseParserRuleContext) ExitRule(listener ParseTreeListener) { +// ExitRule is called when any rule is exited. +func (prc *BaseParserRuleContext) ExitRule(_ ParseTreeListener) { } -// * Does not set parent link other add methods do that/// +// * Does not set parent link other add methods do that func (prc *BaseParserRuleContext) addTerminalNodeChild(child TerminalNode) TerminalNode { if prc.children == nil { prc.children = make([]Tree, 0) @@ -120,10 +121,9 @@ func (prc *BaseParserRuleContext) AddChild(child RuleContext) RuleContext { return child } -// * Used by EnterOuterAlt to toss out a RuleContext previously added as -// we entered a rule. If we have // label, we will need to remove -// generic ruleContext object. -// / +// RemoveLastChild is used by [EnterOuterAlt] to toss out a [RuleContext] previously added as +// we entered a rule. If we have a label, we will need to remove +// the generic ruleContext object. func (prc *BaseParserRuleContext) RemoveLastChild() { if prc.children != nil && len(prc.children) > 0 { prc.children = prc.children[0 : len(prc.children)-1] @@ -350,6 +350,7 @@ type BaseInterpreterRuleContext struct { *BaseParserRuleContext } +//goland:noinspection GoUnusedExportedFunction func NewBaseInterpreterRuleContext(parent BaseInterpreterRuleContext, invokingStateNumber, ruleIndex int) *BaseInterpreterRuleContext { prc := new(BaseInterpreterRuleContext) diff --git a/runtime/Go/antlr/v4/prediction_context.go b/runtime/Go/antlr/v4/prediction_context.go index ba62af3610..bed6d13675 100644 --- a/runtime/Go/antlr/v4/prediction_context.go +++ b/runtime/Go/antlr/v4/prediction_context.go @@ -10,10 +10,8 @@ import ( "strconv" ) -// Represents {@code $} in local context prediction, which means wildcard. -// {@code//+x =//}. -// / const ( + // BasePredictionContextEmptyReturnState represents '$' in local context prediction, which means wildcard. BasePredictionContextEmptyReturnState = 0x7FFFFFFF ) @@ -22,6 +20,7 @@ const ( // {@code $} = {@link //EmptyReturnState}. // / +//goland:noinspection GoUnusedGlobalVariable var ( BasePredictionContextglobalNodeCount = 1 BasePredictionContextid = BasePredictionContextglobalNodeCount @@ -86,7 +85,7 @@ func NewPredictionContextCache() *PredictionContextCache { } // Add a context to the cache and return it. If the context already exists, -// return that one instead and do not add a Newcontext to the cache. +// return that one instead and do not add a new context to the cache. // Protect shared cache from unsafe thread access. func (p *PredictionContextCache) add(ctx PredictionContext) PredictionContext { if ctx == BasePredictionContextEMPTY { @@ -149,11 +148,11 @@ func (b *BaseSingletonPredictionContext) length() int { return 1 } -func (b *BaseSingletonPredictionContext) GetParent(index int) PredictionContext { +func (b *BaseSingletonPredictionContext) GetParent(_ int) PredictionContext { return b.parentCtx } -func (b *BaseSingletonPredictionContext) getReturnState(index int) int { +func (b *BaseSingletonPredictionContext) getReturnState(_ int) int { return b.returnState } @@ -224,11 +223,11 @@ func (e *EmptyPredictionContext) isEmpty() bool { return true } -func (e *EmptyPredictionContext) GetParent(index int) PredictionContext { +func (e *EmptyPredictionContext) GetParent(_ int) PredictionContext { return nil } -func (e *EmptyPredictionContext) getReturnState(index int) int { +func (e *EmptyPredictionContext) getReturnState(_ int) int { return e.returnState } @@ -433,14 +432,14 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) return mergeArrays(arp, arb, rootIsWildcard, mergeCache) } -// Merge two {@link SingletonBasePredictionContext} instances. +// mergeSingletons merges two [SingletonBasePredictionContext] instances. // -//

Stack tops equal, parents merge is same return left graph.
+// Stack tops equal, parents merge is same return left graph. //

// //

Same stack top, parents differ merge parents giving array node, then -// remainders of those graphs. A Newroot node is created to point to the +// remainders of those graphs. A new root node is created to point to the // merged parents.
//

@@ -494,8 +493,8 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, } // else: ax + ay = a'[x,y] // merge parents x and y, giving array node with x,y then remainders - // of those graphs. dup a, a' points at merged array - // Newjoined parent so create Newsingleton pointing to it, a' + // of those graphs. dup a, a' points at merged array. + // 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) @@ -620,7 +619,8 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC //

Equal tops, merge parents and reduce top to // {@link SingletonBasePredictionContext}.
//

-// / +// +//goland:noinspection GoBoolExpressions func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { if mergeCache != nil { previous := mergeCache.Get(a.Hash(), b.Hash()) @@ -708,8 +708,8 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * M := NewArrayPredictionContext(mergedParents, mergedReturnStates) // if we created same array as a or b, return that instead - // TODO: track whether this is possible above during merge sort for speed - // TODO: In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems + // TODO: JI track whether this is possible above during merge sort for speed + // TODO: JI In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems if M == a { if mergeCache != nil { mergeCache.set(a.Hash(), b.Hash(), a) diff --git a/runtime/Go/antlr/v4/prediction_mode.go b/runtime/Go/antlr/v4/prediction_mode.go index 7b9b72fab1..625ad2974a 100644 --- a/runtime/Go/antlr/v4/prediction_mode.go +++ b/runtime/Go/antlr/v4/prediction_mode.go @@ -9,166 +9,173 @@ package antlr // ambiguities. const ( - // - // The SLL(*) prediction mode. This prediction mode ignores the current + // PredictionModeSLL represents the SLL(*) prediction mode. + // This prediction mode ignores the current // parser context when making predictions. This is the fastest prediction // mode, and provides correct results for many grammars. This prediction // mode is more powerful than the prediction mode provided by ANTLR 3, but // may result in syntax errors for grammar and input combinations which are // not SLL. // - //

// When using this prediction mode, the parser will either return a correct // parse tree (i.e. the same parse tree that would be returned with the - // {@link //LL} prediction mode), or it will Report a syntax error. If a - // syntax error is encountered when using the {@link //SLL} prediction mode, + // [PredictionModeLL] prediction mode), or it will Report a syntax error. If a + // syntax error is encountered when using the SLL prediction mode, // it may be due to either an actual syntax error in the input or indicate // that the particular combination of grammar and input requires the more - // powerful {@link //LL} prediction abilities to complete successfully.

+ // powerful LL prediction abilities to complete successfully. // - //

// This prediction mode does not provide any guarantees for prediction - // behavior for syntactically-incorrect inputs.

+ // behavior for syntactically-incorrect inputs. // PredictionModeSLL = 0 - // - // The LL(*) prediction mode. This prediction mode allows the current parser + + // PredictionModeLL represents the LL(*) prediction mode. + // This prediction mode allows the current parser // context to be used for resolving SLL conflicts that occur during // prediction. This is the fastest prediction mode that guarantees correct // parse results for all combinations of grammars with syntactically correct // inputs. // - //

// When using this prediction mode, the parser will make correct decisions // for all syntactically-correct grammar and input combinations. However, in // cases where the grammar is truly ambiguous this prediction mode might not - // Report a precise answer for exactly which alternatives are - // ambiguous.

+ // report a precise answer for exactly which alternatives are + // ambiguous. // - //

// This prediction mode does not provide any guarantees for prediction - // behavior for syntactically-incorrect inputs.

+ // behavior for syntactically-incorrect inputs. // PredictionModeLL = 1 + + // PredictionModeLLExactAmbigDetection represents the LL(*) prediction mode + // with exact ambiguity detection. // - // The LL(*) prediction mode with exact ambiguity detection. In addition to - // the correctness guarantees provided by the {@link //LL} prediction mode, + // In addition to the correctness guarantees provided by the [PredictionModeLL] prediction mode, // this prediction mode instructs the prediction algorithm to determine the // complete and exact set of ambiguous alternatives for every ambiguous // decision encountered while parsing. // - //

// This prediction mode may be used for diagnosing ambiguities during // grammar development. Due to the performance overhead of calculating sets // of ambiguous alternatives, this prediction mode should be avoided when - // the exact results are not necessary.

+ // the exact results are not necessary. // - //

// This prediction mode does not provide any guarantees for prediction - // behavior for syntactically-incorrect inputs.

+ // behavior for syntactically-incorrect inputs. // PredictionModeLLExactAmbigDetection = 2 ) -// Computes the SLL prediction termination condition. +// PredictionModehasSLLConflictTerminatingPrediction computes the SLL prediction termination condition. // -//

// This method computes the SLL prediction termination condition for both of -// the following cases.

+// the following cases: // -//
    -//
  • The usual SLL+LL fallback upon SLL conflict
  • -//
  • Pure SLL without LL fallback
  • -//
+// - The usual SLL+LL fallback upon SLL conflict +// - Pure SLL without LL fallback // -//

COMBINED SLL+LL PARSING

+// # Combined SLL+LL Parsing // -//

When LL-fallback is enabled upon SLL conflict, correct predictions are +// When LL-fallback is enabled upon SLL conflict, correct predictions are // ensured regardless of how the termination condition is computed by this // method. Due to the substantially higher cost of LL prediction, the // prediction should only fall back to LL when the additional lookahead -// cannot lead to a unique SLL prediction.

+// cannot lead to a unique SLL prediction. // -//

Assuming combined SLL+LL parsing, an SLL configuration set with only +// Assuming combined SLL+LL parsing, an SLL configuration set with only // conflicting subsets should fall back to full LL, even if the -// configuration sets don't resolve to the same alternative (e.g. -// {@code {1,2}} and {@code {3,4}}. If there is at least one non-conflicting +// configuration sets don't resolve to the same alternative, e.g. +// +// {1,2} and {3,4} +// +// If there is at least one non-conflicting // configuration, SLL could continue with the hopes that more lookahead will -// resolve via one of those non-conflicting configurations.

+// resolve via one of those non-conflicting configurations. // -//

Here's the prediction termination rule them: SLL (for SLL+LL parsing) +// Here's the prediction termination rule them: SLL (for SLL+LL parsing) // stops when it sees only conflicting configuration subsets. In contrast, -// full LL keeps going when there is uncertainty.

+// full LL keeps going when there is uncertainty. // -//

HEURISTIC

+// # Heuristic // -//

As a heuristic, we stop prediction when we see any conflicting subset +// As a heuristic, we stop prediction when we see any conflicting subset // unless we see a state that only has one alternative associated with it. // The single-alt-state thing lets prediction continue upon rules like -// (otherwise, it would admit defeat too soon):

+// (otherwise, it would admit defeat too soon): +// +// [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ; +// +// When the [ATN] simulation reaches the state before ';', it has a +// [DFA] state that looks like: +// +// [12|1|[], 6|2|[], 12|2|[]] +// +// Naturally // -//

{@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ” }

+// 12|1|[] and 12|2|[] // -//

When the ATN simulation reaches the state before {@code ”}, it has a -// DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally -// {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop -// processing this node because alternative to has another way to continue, -// via {@code [6|2|[]]}.

+// conflict, but we cannot stop processing this node because alternative to has another way to continue, +// via // -//

It also let's us continue for this rule:

+// [6|2|[]] // -//

{@code [1|1|[], 1|2|[], 8|3|[]] a : A | A | A B }

+// It also let's us continue for this rule: // -//

After Matching input A, we reach the stop state for rule A, state 1. -// State 8 is the state right before B. Clearly alternatives 1 and 2 +// [1|1|[], 1|2|[], 8|3|[]] a : A | A | A B ; +// +// After Matching input A, we reach the stop state for rule A, state 1. +// State 8 is the state immediately before B. Clearly alternatives 1 and 2 // conflict and no amount of further lookahead will separate the two. -// However, alternative 3 will be able to continue and so we do not stop +// However, alternative 3 will be able to continue, and so we do not stop // working on this state. In the previous example, we're concerned with // states associated with the conflicting alternatives. Here alt 3 is not // associated with the conflicting configs, but since we can continue -// looking for input reasonably, don't declare the state done.

+// looking for input reasonably, don't declare the state done. // -//

PURE SLL PARSING

+// # Pure SLL Parsing // -//

To handle pure SLL parsing, all we have to do is make sure that we +// To handle pure SLL parsing, all we have to do is make sure that we // combine stack contexts for configurations that differ only by semantic -// predicate. From there, we can do the usual SLL termination heuristic.

+// predicate. From there, we can do the usual SLL termination heuristic. // -//

PREDICATES IN SLL+LL PARSING

+// # Predicates in SLL+LL Parsing // -//

SLL decisions don't evaluate predicates until after they reach DFA stop -// states because they need to create the DFA cache that works in all +// SLL decisions don't evaluate predicates until after they reach [DFA] stop +// states because they need to create the [DFA] cache that works in all // semantic situations. In contrast, full LL evaluates predicates collected -// during start state computation so it can ignore predicates thereafter. +// during start state computation, so it can ignore predicates thereafter. // This means that SLL termination detection can totally ignore semantic -// predicates.

+// predicates. // -//

Implementation-wise, {@link ATNConfigSet} combines stack contexts but not -// semantic predicate contexts so we might see two configurations like the -// following.

+// Implementation-wise, [ATNConfigSet] combines stack contexts but not +// semantic predicate contexts, so we might see two configurations like the +// following: // -//

{@code (s, 1, x, {}), (s, 1, x', {p})}

+// (s, 1, x, {}), (s, 1, x', {p}) // -//

Before testing these configurations against others, we have to merge -// {@code x} and {@code x'} (without modifying the existing configurations). -// For example, we test {@code (x+x')==x”} when looking for conflicts in -// the following configurations.

+// Before testing these configurations against others, we have to merge +// x and x' (without modifying the existing configurations). +// For example, we test (x+x')==x” when looking for conflicts in +// the following configurations: // -//

{@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x”, {})}

+// (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x”, {}) // -//

If the configuration set has predicates (as indicated by -// {@link ATNConfigSet//hasSemanticContext}), this algorithm makes a copy of -// the configurations to strip out all of the predicates so that a standard -// {@link ATNConfigSet} will merge everything ignoring predicates.

+// If the configuration set has predicates (as indicated by +// [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 { + // 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 - // to Match additional input so we terminate prediction. + // to Match additional input, so we terminate prediction. // if PredictionModeallConfigsInRuleStopStates(configs) { return true } + // pure SLL mode parsing if mode == PredictionModeSLL { // Don't bother with combining configs from different semantic @@ -185,21 +192,19 @@ func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConf } configs = dup } - // now we have combined contexts for configs with dissimilar preds + // now we have combined contexts for configs with dissimilar predicates } // pure SLL or combined SLL+LL mode parsing altsets := PredictionModegetConflictingAltSubsets(configs) return PredictionModehasConflictingAltSet(altsets) && !PredictionModehasStateAssociatedWithOneAlt(configs) } -// Checks if any configuration in {@code configs} is in a -// {@link RuleStopState}. Configurations meeting this condition have reached +// PredictionModehasConfigInRuleStopState checks if any configuration in the given configs is in a +// [RuleStopState]. Configurations meeting this condition have reached // the end of the decision rule (local context) or end of start rule (full // context). // -// @param configs the configuration set to test -// @return {@code true} if any configuration in {@code configs} is in a -// {@link RuleStopState}, otherwise {@code false} +// 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() { if _, ok := c.GetState().(*RuleStopState); ok { @@ -209,14 +214,13 @@ func PredictionModehasConfigInRuleStopState(configs ATNConfigSet) bool { return false } -// Checks if all configurations in {@code configs} are in a -// {@link RuleStopState}. Configurations meeting this condition have reached +// PredictionModeallConfigsInRuleStopStates checks if all configurations in configs are in a +// [RuleStopState]. Configurations meeting this condition have reached // the end of the decision rule (local context) or end of start rule (full // context). // -// @param configs the configuration set to test -// @return {@code true} if all configurations in {@code configs} are in a -// {@link RuleStopState}, otherwise {@code false} +// the func returns true if all configurations in configs are in a +// [RuleStopState] func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { for _, c := range configs.GetItems() { @@ -227,165 +231,175 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { return true } -// Full LL prediction termination. +// PredictionModeresolvesToJustOneViableAlt checks full LL prediction termination. // -//

Can we stop looking ahead during ATN simulation or is there some +// Can we stop looking ahead during [ATN] simulation or is there some // uncertainty as to which alternative we will ultimately pick, after // consuming more input? Even if there are partial conflicts, we might know // that everything is going to resolve to the same minimum alternative. That // means we can stop since no more lookahead will change that fact. On the // other hand, there might be multiple conflicts that resolve to different // minimums. That means we need more look ahead to decide which of those -// alternatives we should predict.

+// alternatives we should predict. // -//

The basic idea is to split the set of configurations {@code C}, into -// conflicting subsets {@code (s, _, ctx, _)} and singleton subsets with +// The basic idea is to split the set of configurations 'C', into +// conflicting subsets (s, _, ctx, _) and singleton subsets with // non-conflicting configurations. Two configurations conflict if they have -// identical {@link ATNConfig//state} and {@link ATNConfig//context} values -// but different {@link ATNConfig//alt} value, e.g. {@code (s, i, ctx, _)} -// and {@code (s, j, ctx, _)} for {@code i!=j}.

+// identical [ATNConfig].state and [ATNConfig].context values +// but a different [ATNConfig].alt value, e.g. +// +// (s, i, ctx, _) +// +// and +// +// (s, j, ctx, _) ; for i != j +// +// Reduce these configuration subsets to the set of possible alternatives. +// You can compute the alternative subsets in one pass as follows: +// +// A_s,ctx = {i | (s, i, ctx, _)} +// +// for each configuration in C holding s and ctx fixed. // -//

Reduce these configuration subsets to the set of possible alternatives. -// You can compute the alternative subsets in one pass as follows:

+// Or in pseudo-code: // -//

{@code A_s,ctx = {i | (s, i, ctx, _)}} for each configuration in -// {@code C} holding {@code s} and {@code ctx} fixed.

+// for each configuration c in C: +// map[c] U = c.ATNConfig.alt alt // map hash/equals uses s and x, not alt and not pred // -//

Or in pseudo-code, for each configuration {@code c} in {@code C}:

+// The values in map are the set of // -//
-// map[c] U= c.{@link ATNConfig//alt alt} // map hash/equals uses s and x, not
-// alt and not pred
-// 
+// A_s,ctx // -//

The values in {@code map} are the set of {@code A_s,ctx} sets.

+// sets. // -//

If {@code |A_s,ctx|=1} then there is no conflict associated with -// {@code s} and {@code ctx}.

+// If // -//

Reduce the subsets to singletons by choosing a minimum of each subset. If +// |A_s,ctx| = 1 +// +// then there is no conflict associated with s and ctx. +// +// Reduce the subsets to singletons by choosing a minimum of each subset. If // the union of these alternative subsets is a singleton, then no amount of -// more lookahead will help us. We will always pick that alternative. If, +// further lookahead will help us. We will always pick that alternative. If, // however, there is more than one alternative, then we are uncertain which // alternative to predict and must continue looking for resolution. We may // or may not discover an ambiguity in the future, even if there are no -// conflicting subsets this round.

+// conflicting subsets this round. // -//

The biggest sin is to terminate early because it means we've made a +// The biggest sin is to terminate early because it means we've made a // decision but were uncertain as to the eventual outcome. We haven't used // enough lookahead. On the other hand, announcing a conflict too late is no -// big deal you will still have the conflict. It's just inefficient. It -// might even look until the end of file.

+// big deal; you will still have the conflict. It's just inefficient. It +// might even look until the end of file. // -//

No special consideration for semantic predicates is required because +// No special consideration for semantic predicates is required because // predicates are evaluated on-the-fly for full LL prediction, ensuring that // no configuration contains a semantic context during the termination -// check.

-// -//

CONFLICTING CONFIGS

-// -//

Two configurations {@code (s, i, x)} and {@code (s, j, x')}, conflict -// when {@code i!=j} but {@code x=x'}. Because we merge all -// {@code (s, i, _)} configurations together, that means that there are at -// most {@code n} configurations associated with state {@code s} for -// {@code n} possible alternatives in the decision. The merged stacks -// complicate the comparison of configuration contexts {@code x} and -// {@code x'}. Sam checks to see if one is a subset of the other by calling -// merge and checking to see if the merged result is either {@code x} or -// {@code x'}. If the {@code x} associated with lowest alternative {@code i} -// is the superset, then {@code i} is the only possible prediction since the -// others resolve to {@code min(i)} as well. However, if {@code x} is -// associated with {@code j>i} then at least one stack configuration for -// {@code j} is not in conflict with alternative {@code i}. The algorithm -// should keep going, looking for more lookahead due to the uncertainty.

-// -//

For simplicity, I'm doing a equality check between {@code x} and -// {@code x'} that lets the algorithm continue to consume lookahead longer +// check. +// +// # Conflicting Configs +// +// Two configurations: +// +// (s, i, x) and (s, j, x') +// +// conflict when i != j but x = x'. Because we merge all +// (s, i, _) configurations together, that means that there are at +// most n configurations associated with state s for +// n possible alternatives in the decision. The merged stacks +// complicate the comparison of configuration contexts x and x'. +// +// Sam checks to see if one is a subset of the other by calling +// merge and checking to see if the merged result is either x or x'. +// If the x associated with lowest alternative i +// is the superset, then i is the only possible prediction since the +// others resolve to min(i) as well. However, if x is +// associated with j > i then at least one stack configuration for +// j is not in conflict with alternative i. The algorithm +// should keep going, looking for more lookahead due to the uncertainty. +// +// For simplicity, I'm doing an equality check between x and +// x', which lets the algorithm continue to consume lookahead longer // than necessary. The reason I like the equality is of course the // simplicity but also because that is the test you need to detect the -// alternatives that are actually in conflict.

+// alternatives that are actually in conflict. // -//

CONTINUE/STOP RULE

+// # Continue/Stop Rule // -//

Continue if union of resolved alternative sets from non-conflicting and +// Continue if the union of resolved alternative sets from non-conflicting and // conflicting alternative subsets has more than one alternative. We are -// uncertain about which alternative to predict.

+// uncertain about which alternative to predict. +// +// The complete set of alternatives, +// +// [i for (_, i, _)] // -//

The complete set of alternatives, {@code [i for (_,i,_)]}, tells us which -// alternatives are still in the running for the amount of input we've +// tells us which alternatives are still in the running for the amount of input we've // consumed at this point. The conflicting sets let us to strip away // configurations that won't lead to more states because we resolve // conflicts to the configuration with a minimum alternate for the -// conflicting set.

+// conflicting set. // -//

CASES

+// Cases // -//
    +// - no conflicts and more than 1 alternative in set => continue +// - (s, 1, x), (s, 2, x), (s, 3, z), (s', 1, y), (s', 2, y) yields non-conflicting set +// {3} ∪ conflicting sets min({1,2}) ∪ min({1,2}) = {1,3} => continue +// - (s, 1, x), (s, 2, x), (s', 1, y), (s', 2, y), (s”, 1, z) yields non-conflicting set +// {1} ∪ conflicting sets min({1,2}) ∪ min({1,2}) = {1} => stop and predict 1 +// - (s, 1, x), (s, 2, x), (s', 1, y), (s', 2, y) yields conflicting, reduced sets +// {1} ∪ {1} = {1} => stop and predict 1, can announce ambiguity {1,2} +// - (s, 1, x), (s, 2, x), (s', 2, y), (s', 3, y) yields conflicting, reduced sets +// {1} ∪ {2} = {1,2} => continue +// - (s, 1, x), (s, 2, x), (s', 2, y), (s', 3, y) yields conflicting, reduced sets +// {1} ∪ {2} = {1,2} => continue +// - (s, 1, x), (s, 2, x), (s', 3, y), (s', 4, y) yields conflicting, reduced sets +// {1} ∪ {3} = {1,3} => continue // -//
  • no conflicts and more than 1 alternative in set => continue
  • +// # Exact Ambiguity Detection // -//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s, 3, z)}, -// {@code (s', 1, y)}, {@code (s', 2, y)} yields non-conflicting set -// {@code {3}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = -// {@code {1,3}} => continue -//
  • +// If all states report the same conflicting set of alternatives, then we +// know we have the exact ambiguity set: // -//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)}, -// {@code (s', 2, y)}, {@code (s”, 1, z)} yields non-conflicting set -// {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = -// {@code {1}} => stop and predict 1
  • +// |A_i| > 1 // -//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)}, -// {@code (s', 2, y)} yields conflicting, reduced sets {@code {1}} U -// {@code {1}} = {@code {1}} => stop and predict 1, can announce -// ambiguity {@code {1,2}}
  • +// and // -//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 2, y)}, -// {@code (s', 3, y)} yields conflicting, reduced sets {@code {1}} U -// {@code {2}} = {@code {1,2}} => continue
  • +// A_i = A_j ; for all i, j // -//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 3, y)}, -// {@code (s', 4, y)} yields conflicting, reduced sets {@code {1}} U -// {@code {3}} = {@code {1,3}} => continue
  • +// In other words, we continue examining lookahead until all A_i +// have more than one alternative and all A_i are the same. If // -//
+// A={{1,2}, {1,3}} // -//

EXACT AMBIGUITY DETECTION

+// then regular LL prediction would terminate because the resolved set is {1}. +// To determine what the real ambiguity is, we have to know whether the ambiguity is between one and +// two or one and three so we keep going. We can only stop prediction when +// we need exact ambiguity detection when the sets look like: // -//

If all states Report the same conflicting set of alternatives, then we -// know we have the exact ambiguity set.

+// A={{1,2}} // -//

|A_i|>1 and -// A_i = A_j for all i, j.

+// or // -//

In other words, we continue examining lookahead until all {@code A_i} -// have more than one alternative and all {@code A_i} are the same. If -// {@code A={{1,2}, {1,3}}}, then regular LL prediction would terminate -// because the resolved set is {@code {1}}. To determine what the real -// ambiguity is, we have to know whether the ambiguity is between one and -// two or one and three so we keep going. We can only stop prediction when -// we need exact ambiguity detection when the sets look like -// {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...

+// {{1,2},{1,2}}, etc... func PredictionModeresolvesToJustOneViableAlt(altsets []*BitSet) int { return PredictionModegetSingleViableAlt(altsets) } -// Determines if every alternative subset in {@code altsets} contains more +// PredictionModeallSubsetsConflict determines if every alternative subset in altsets contains more // than one alternative. // -// @param altsets a collection of alternative subsets -// @return {@code true} if every {@link BitSet} in {@code altsets} has -// {@link BitSet//cardinality cardinality} > 1, otherwise {@code false} +// The func returns true if every [BitSet] in altsets has +// [BitSet].cardinality cardinality > 1 func PredictionModeallSubsetsConflict(altsets []*BitSet) bool { return !PredictionModehasNonConflictingAltSet(altsets) } -// Determines if any single alternative subset in {@code altsets} contains +// PredictionModehasNonConflictingAltSet determines if any single alternative subset in altsets contains // exactly one alternative. // -// @param altsets a collection of alternative subsets -// @return {@code true} if {@code altsets} contains a {@link BitSet} with -// {@link BitSet//cardinality cardinality} 1, otherwise {@code false} +// The func returns true if altsets contains at least one [BitSet] with +// [BitSet].cardinality cardinality 1 func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool { for i := 0; i < len(altsets); i++ { alts := altsets[i] @@ -396,12 +410,11 @@ func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool { return false } -// Determines if any single alternative subset in {@code altsets} contains +// PredictionModehasConflictingAltSet determines if any single alternative subset in altsets contains // more than one alternative. // -// @param altsets a collection of alternative subsets -// @return {@code true} if {@code altsets} contains a {@link BitSet} with -// {@link BitSet//cardinality cardinality} > 1, otherwise {@code false} +// The func returns true if altsets contains a [BitSet] with +// [BitSet].cardinality cardinality > 1, otherwise false func PredictionModehasConflictingAltSet(altsets []*BitSet) bool { for i := 0; i < len(altsets); i++ { alts := altsets[i] @@ -412,11 +425,9 @@ func PredictionModehasConflictingAltSet(altsets []*BitSet) bool { return false } -// Determines if every alternative subset in {@code altsets} is equivalent. +// PredictionModeallSubsetsEqual determines if every alternative subset in altsets is equivalent. // -// @param altsets a collection of alternative subsets -// @return {@code true} if every member of {@code altsets} is equal to the -// others, otherwise {@code false} +// The func returns true if every member of altsets is equal to the others. func PredictionModeallSubsetsEqual(altsets []*BitSet) bool { var first *BitSet @@ -432,9 +443,9 @@ func PredictionModeallSubsetsEqual(altsets []*BitSet) bool { return true } -// Returns the unique alternative predicted by all alternative subsets in -// {@code altsets}. If no such alternative exists, this method returns -// {@link ATN//INVALID_ALT_NUMBER}. +// PredictionModegetUniqueAlt returns the unique alternative predicted by all alternative subsets in +// altsets. If no such alternative exists, this method returns +// [ATNInvalidAltNumber]. // // @param altsets a collection of alternative subsets func PredictionModegetUniqueAlt(altsets []*BitSet) int { @@ -446,12 +457,9 @@ func PredictionModegetUniqueAlt(altsets []*BitSet) int { return ATNInvalidAltNumber } -// Gets the complete set of represented alternatives for a collection of -// alternative subsets. This method returns the union of each {@link BitSet} -// in {@code altsets}. -// -// @param altsets a collection of alternative subsets -// @return the set of represented alternatives in {@code altsets} +// PredictionModeGetAlts returns the complete set of represented alternatives for a collection of +// alternative subsets. This method returns the union of each [BitSet] +// in altsets, being the set of represented alternatives in altsets. func PredictionModeGetAlts(altsets []*BitSet) *BitSet { all := NewBitSet() for _, alts := range altsets { @@ -461,12 +469,9 @@ func PredictionModeGetAlts(altsets []*BitSet) *BitSet { } // PredictionModegetConflictingAltSubsets gets the conflicting alt subsets from a configuration set. -// For each configuration {@code c} in {@code configs}: // -//
-// map[c] U= c.{@link ATNConfig//alt alt} // map hash/equals uses s and x, not
-// alt and not pred
-// 
+// 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) @@ -483,12 +488,10 @@ func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet { return configToAlts.Values() } -// PredictionModeGetStateToAltMap gets a map from state to alt subset from a configuration set. For each -// configuration {@code c} in {@code configs}: +// PredictionModeGetStateToAltMap gets a map from state to alt subset from a configuration set. // -//
-// map[c.{@link ATNConfig//state state}] U= c.{@link ATNConfig//alt alt}
-// 
+// for each configuration c in configs: +// map[c.ATNConfig.state] U= c.ATNConfig.alt} func PredictionModeGetStateToAltMap(configs ATNConfigSet) *AltDict { m := NewAltDict() @@ -513,6 +516,10 @@ func PredictionModehasStateAssociatedWithOneAlt(configs ATNConfigSet) bool { return false } +// PredictionModegetSingleViableAlt gets the single alternative predicted by all alternative subsets in altsets +// if there is one. +// +// 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 diff --git a/runtime/Go/antlr/v4/recognizer.go b/runtime/Go/antlr/v4/recognizer.go index bfe542d091..467ba0b1c8 100644 --- a/runtime/Go/antlr/v4/recognizer.go +++ b/runtime/Go/antlr/v4/recognizer.go @@ -45,7 +45,10 @@ func NewBaseRecognizer() *BaseRecognizer { return rec } +//goland:noinspection GoUnusedGlobalVariable var tokenTypeMapCache = make(map[string]int) + +//goland:noinspection GoUnusedGlobalVariable var ruleIndexMapCache = make(map[string]int) func (b *BaseRecognizer) checkVersion(toolVersion string) { @@ -55,7 +58,7 @@ func (b *BaseRecognizer) checkVersion(toolVersion string) { } } -func (b *BaseRecognizer) Action(context RuleContext, ruleIndex, actionIndex int) { +func (b *BaseRecognizer) Action(_ RuleContext, _, _ int) { panic("action not implemented on Recognizer!") } @@ -105,9 +108,11 @@ func (b *BaseRecognizer) SetState(v int) { // return result //} -// Get a map from rule names to rule indexes. +// GetRuleIndexMap Get a map from rule names to rule indexes. +// +// Used for XPath and tree pattern compilation. // -//

Used for XPath and tree pattern compilation.

+// TODO: JI This is not yet implemented in the Go runtime. Maybe not needed. func (b *BaseRecognizer) GetRuleIndexMap() map[string]int { panic("Method not defined!") @@ -124,7 +129,8 @@ func (b *BaseRecognizer) GetRuleIndexMap() map[string]int { // return result } -func (b *BaseRecognizer) GetTokenType(tokenName string) int { +// GetTokenType get the token type based upon its name +func (b *BaseRecognizer) GetTokenType(_ string) int { panic("Method not defined!") // var ttype = b.GetTokenTypeMap()[tokenName] // if (ttype !=nil) { @@ -162,26 +168,27 @@ func (b *BaseRecognizer) GetTokenType(tokenName string) int { // } //} -// What is the error header, normally line/character position information?// +// GetErrorHeader returns the error header, normally line/character position information. +// +// Can be overridden in sub structs embedding BaseRecognizer. func (b *BaseRecognizer) GetErrorHeader(e RecognitionException) string { line := e.GetOffendingToken().GetLine() column := e.GetOffendingToken().GetColumn() return "line " + strconv.Itoa(line) + ":" + strconv.Itoa(column) } -// How should a token be displayed in an error message? The default +// GetTokenErrorDisplay shows how a token should be displayed in an error message. // -// is to display just the text, but during development you might -// want to have a lot of information spit out. Override in that case -// to use t.String() (which, for CommonToken, dumps everything about -// the token). This is better than forcing you to override a method in -// your token objects because you don't have to go modify your lexer -// so that it creates a NewJava type. +// The default is to display just the text, but during development you might +// want to have a lot of information spit out. Override in that case +// to use t.String() (which, for CommonToken, dumps everything about +// the token). This is better than forcing you to override a method in +// your token objects because you don't have to go modify your lexer +// so that it creates a NewJava type. // -// @deprecated This method is not called by the ANTLR 4 Runtime. Specific -// implementations of {@link ANTLRErrorStrategy} may provide a similar -// feature when necessary. For example, see -// {@link DefaultErrorStrategy//GetTokenErrorDisplay}. +// Deprecated: This method is not called by the ANTLR 4 Runtime. Specific +// implementations of [ANTLRErrorStrategy] may provide a similar +// feature when necessary. For example, see [DefaultErrorStrategy].GetTokenErrorDisplay() func (b *BaseRecognizer) GetTokenErrorDisplay(t Token) string { if t == nil { return "" @@ -205,12 +212,14 @@ func (b *BaseRecognizer) GetErrorListenerDispatch() ErrorListener { return NewProxyErrorListener(b.listeners) } -// subclass needs to override these if there are sempreds or actions -// that the ATN interp needs to execute -func (b *BaseRecognizer) Sempred(localctx RuleContext, ruleIndex int, actionIndex int) bool { +// Sempred embedding structs need to override this if there are sempreds or actions +// that the ATN interpreter needs to execute +func (b *BaseRecognizer) Sempred(_ RuleContext, _ int, _ int) bool { return true } -func (b *BaseRecognizer) Precpred(localctx RuleContext, precedence int) bool { +// Precpred embedding structs need to override this if there are preceding predicates +// that the ATN interpreter needs to execute +func (b *BaseRecognizer) Precpred(_ RuleContext, _ int) bool { return true } diff --git a/runtime/Go/antlr/v4/rule_context.go b/runtime/Go/antlr/v4/rule_context.go index 210699ba23..73771db8f8 100644 --- a/runtime/Go/antlr/v4/rule_context.go +++ b/runtime/Go/antlr/v4/rule_context.go @@ -4,27 +4,26 @@ package antlr -// A rule context is a record of a single rule invocation. It knows -// which context invoked it, if any. If there is no parent context, then -// naturally the invoking state is not valid. The parent link -// provides a chain upwards from the current rule invocation to the root -// of the invocation tree, forming a stack. We actually carry no -// information about the rule associated with b context (except -// when parsing). We keep only the state number of the invoking state from -// the ATN submachine that invoked b. Contrast b with the s -// pointer inside ParserRuleContext that tracks the current state -// being "executed" for the current rule. +// RuleContext is a record of a single rule invocation. It knows +// which context invoked it, if any. If there is no parent context, then +// naturally the invoking state is not valid. The parent link +// provides a chain upwards from the current rule invocation to the root +// of the invocation tree, forming a stack. // -// The parent contexts are useful for computing lookahead sets and -// getting error information. +// We actually carry no information about the rule associated with this context (except +// when parsing). We keep only the state number of the invoking state from +// the [ATN] submachine that invoked this. Contrast this with the s +// pointer inside [ParserRuleContext] that tracks the current state +// being "executed" for the current rule. // -// These objects are used during parsing and prediction. -// For the special case of parsers, we use the subclass -// ParserRuleContext. +// The parent contexts are useful for computing lookahead sets and +// getting error information. // -// @see ParserRuleContext +// These objects are used during parsing and prediction. +// For the special case of parsers, we use the struct +// [ParserRuleContext], which embeds a RuleContext. // - +// @see ParserRuleContext type RuleContext interface { RuleNode @@ -93,22 +92,22 @@ func (b *BaseRuleContext) GetAltNumber() int { return ATNInvalidAltNumber } -func (b *BaseRuleContext) SetAltNumber(altNumber int) {} +func (b *BaseRuleContext) SetAltNumber(_ int) {} -// A context is empty if there is no invoking state meaning nobody call +// IsEmpty returns true if the context of b is empty. +// +// A context is empty if there is no invoking state, meaning nobody calls // current context. func (b *BaseRuleContext) IsEmpty() bool { return b.invokingState == -1 } -// Return the combined text of all child nodes. This method only considers +// GetParent returns the combined text of all child nodes. This method only considers // tokens which have been added to the parse tree. -//

+// // Since tokens on hidden channels (e.g. whitespace or comments) are not -// added to the parse trees, they will not appear in the output of b +// added to the parse trees, they will not appear in the output of this // method. -// - func (b *BaseRuleContext) GetParent() Tree { return b.parentCtx } diff --git a/runtime/Go/antlr/v4/semantic_context.go b/runtime/Go/antlr/v4/semantic_context.go index a702e99def..503294ff79 100644 --- a/runtime/Go/antlr/v4/semantic_context.go +++ b/runtime/Go/antlr/v4/semantic_context.go @@ -9,14 +9,13 @@ import ( "strconv" ) -// A tree structure used to record the semantic context in which -// an ATN configuration is valid. It's either a single predicate, -// a conjunction {@code p1&&p2}, or a sum of products {@code p1||p2}. +// SemanticContext is a tree structure used to record the semantic context in which // -//

I have scoped the {@link AND}, {@link OR}, and {@link Predicate} subclasses of -// {@link SemanticContext} within the scope of this outer class.

+// an ATN configuration is valid. It's either a single predicate, +// a conjunction p1 && p2, or a sum of products p1 || p2. // - +// I have scoped the AND, OR, and Predicate subclasses of +// [SemanticContext] within the scope of this outer ``class'' type SemanticContext interface { Equals(other Collectable[SemanticContext]) bool Hash() int @@ -80,7 +79,7 @@ func NewPredicate(ruleIndex, predIndex int, isCtxDependent bool) *Predicate { var SemanticContextNone = NewPredicate(-1, -1, false) -func (p *Predicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { +func (p *Predicate) evalPrecedence(_ Recognizer, _ RuleContext) SemanticContext { return p } @@ -316,12 +315,12 @@ func (a *AND) Hash() int { return murmurFinish(h, len(a.opnds)) } -func (a *OR) Hash() int { - h := murmurInit(41) // Init with a value different from AND - for _, op := range a.opnds { +func (o *OR) Hash() int { + h := murmurInit(41) // Init with o value different from AND + for _, op := range o.opnds { h = murmurUpdate(h, op.Hash()) } - return murmurFinish(h, len(a.opnds)) + return murmurFinish(h, len(o.opnds)) } func (a *AND) String() string { diff --git a/runtime/Go/antlr/v4/testing_lexer_b_test.go b/runtime/Go/antlr/v4/testing_lexer_b_test.go index 2485abf780..f3e22d7a69 100644 --- a/runtime/Go/antlr/v4/testing_lexer_b_test.go +++ b/runtime/Go/antlr/v4/testing_lexer_b_test.go @@ -7,7 +7,7 @@ package antlr /* LexerB is a lexer for testing purpose. -This file is generated from this grammer. +This file is generated from this grammar. lexer grammar LexerB; @@ -97,7 +97,7 @@ func lexerbLexerInit() { } } -// LexerBInit initializes any static state used to implement LexerB. By default the +// LexerBInit initializes any static state used to implement LexerB. By default, the // static state used to implement the lexer is lazily initialized during the first call to // NewLexerB(). You can call this function if you wish to initialize the static state ahead // of time. @@ -126,6 +126,8 @@ func NewLexerB(input CharStream) *LexerB { } // LexerB tokens. +// +//goland:noinspection GoUnusedConst const ( LexerBID = 1 LexerBINT = 2 diff --git a/runtime/Go/antlr/v4/testing_util_test.go b/runtime/Go/antlr/v4/testing_util_test.go index 20428831b3..a0fbd0f164 100644 --- a/runtime/Go/antlr/v4/testing_util_test.go +++ b/runtime/Go/antlr/v4/testing_util_test.go @@ -5,7 +5,7 @@ import ( "strings" ) -// newTestCommonToken create common token with tokentype, text and channel +// newTestCommonToken create common token with tokenType, text and channel // notice: test purpose only func newTestCommonToken(tokenType int, text string, channel int) *CommonToken { t := new(CommonToken) @@ -18,7 +18,7 @@ func newTestCommonToken(tokenType int, text string, channel int) *CommonToken { return t } -// tokensToString returnes []Tokens string +// tokensToString returns []Tokens string // notice: test purpose only func tokensToString(tokens []Token) string { buf := make([]string, len(tokens)) diff --git a/runtime/Go/antlr/v4/token.go b/runtime/Go/antlr/v4/token.go index a77b941427..fcb8e66d8c 100644 --- a/runtime/Go/antlr/v4/token.go +++ b/runtime/Go/antlr/v4/token.go @@ -55,7 +55,7 @@ type BaseToken struct { const ( TokenInvalidType = 0 - // During lookahead operations, this "token" signifies we hit rule end ATN state + // TokenEpsilon - during lookahead operations, this "token" signifies we hit the rule end [ATN] state // and did not follow it despite needing to. TokenEpsilon = -2 @@ -63,15 +63,16 @@ const ( TokenEOF = -1 - // All tokens go to the parser (unless Skip() is called in that rule) + // TokenDefaultChannel is the default channel upon which tokens are sent to the parser. + // + // All tokens go to the parser (unless [Skip] is called in the lexer rule) // on a particular "channel". The parser tunes to a particular channel // so that whitespace etc... can go to the parser on a "hidden" channel. - TokenDefaultChannel = 0 - // Anything on different channel than DEFAULT_CHANNEL is not parsed - // by parser. - + // TokenHiddenChannel defines the normal hidden channel - the parser wil not see tokens that are not on [TokenDefaultChannel]. + // + // Anything on a different channel than TokenDefaultChannel is not parsed by parser. TokenHiddenChannel = 1 ) diff --git a/runtime/Go/antlr/v4/tokenstream_rewriter.go b/runtime/Go/antlr/v4/tokenstream_rewriter.go index b3e38af344..980717050e 100644 --- a/runtime/Go/antlr/v4/tokenstream_rewriter.go +++ b/runtime/Go/antlr/v4/tokenstream_rewriter.go @@ -86,14 +86,15 @@ import ( // first example shows.

const ( - Default_Program_Name = "default" - Program_Init_Size = 100 - Min_Token_Index = 0 + DefaultProgramName = "default" + ProgramInitSize = 100 + MinTokenIndex = 0 ) // Define the rewrite operation hierarchy type RewriteOperation interface { + // Execute the rewrite operation by possibly adding to the buffer. // Return the index of the next token to operate on. Execute(buffer *bytes.Buffer) int @@ -112,19 +113,19 @@ type RewriteOperation interface { type BaseRewriteOperation struct { //Current index of rewrites list - instruction_index int + instructionIndex int //Token buffer index index int //Substitution text text string //Actual operation name - op_name string + opName string //Pointer to token steam tokens TokenStream } func (op *BaseRewriteOperation) GetInstructionIndex() int { - return op.instruction_index + return op.instructionIndex } func (op *BaseRewriteOperation) GetIndex() int { @@ -136,7 +137,7 @@ func (op *BaseRewriteOperation) GetText() string { } func (op *BaseRewriteOperation) GetOpName() string { - return op.op_name + return op.opName } func (op *BaseRewriteOperation) GetTokens() TokenStream { @@ -144,7 +145,7 @@ func (op *BaseRewriteOperation) GetTokens() TokenStream { } func (op *BaseRewriteOperation) SetInstructionIndex(val int) { - op.instruction_index = val + op.instructionIndex = val } func (op *BaseRewriteOperation) SetIndex(val int) { @@ -156,20 +157,20 @@ func (op *BaseRewriteOperation) SetText(val string) { } func (op *BaseRewriteOperation) SetOpName(val string) { - op.op_name = val + op.opName = val } func (op *BaseRewriteOperation) SetTokens(val TokenStream) { op.tokens = val } -func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int { +func (op *BaseRewriteOperation) Execute(_ *bytes.Buffer) int { return op.index } func (op *BaseRewriteOperation) String() string { return fmt.Sprintf("<%s@%d:\"%s\">", - op.op_name, + op.opName, op.tokens.Get(op.GetIndex()), op.text, ) @@ -182,10 +183,10 @@ type InsertBeforeOp struct { func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp { return &InsertBeforeOp{BaseRewriteOperation: BaseRewriteOperation{ - index: index, - text: text, - op_name: "InsertBeforeOp", - tokens: stream, + index: index, + text: text, + opName: "InsertBeforeOp", + tokens: stream, }} } @@ -201,20 +202,21 @@ func (op *InsertBeforeOp) String() string { return op.BaseRewriteOperation.String() } -// Distinguish between insert after/before to do the "insert afters" -// first and then the "insert befores" at same index. Implementation -// of "insert after" is "insert before index+1". - +// InsertAfterOp distinguishes between insert after/before to do the "insert after" instructions +// first and then the "insert before" instructions at same index. Implementation +// of "insert after" is "insert before index+1". type InsertAfterOp struct { BaseRewriteOperation } func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp { - return &InsertAfterOp{BaseRewriteOperation: BaseRewriteOperation{ - index: index + 1, - text: text, - tokens: stream, - }} + return &InsertAfterOp{ + BaseRewriteOperation: BaseRewriteOperation{ + index: index + 1, + text: text, + tokens: stream, + }, + } } func (op *InsertAfterOp) Execute(buffer *bytes.Buffer) int { @@ -229,7 +231,7 @@ func (op *InsertAfterOp) String() string { return op.BaseRewriteOperation.String() } -// I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp +// ReplaceOp tries to replace range from x..y with (y-x)+1 ReplaceOp // instructions. type ReplaceOp struct { BaseRewriteOperation @@ -239,10 +241,10 @@ type ReplaceOp struct { func NewReplaceOp(from, to int, text string, stream TokenStream) *ReplaceOp { return &ReplaceOp{ BaseRewriteOperation: BaseRewriteOperation{ - index: from, - text: text, - op_name: "ReplaceOp", - tokens: stream, + index: from, + text: text, + opName: "ReplaceOp", + tokens: stream, }, LastIndex: to, } @@ -270,17 +272,17 @@ type TokenStreamRewriter struct { // You may have multiple, named streams of rewrite operations. // I'm calling these things "programs." // Maps String (name) → rewrite (List) - programs map[string][]RewriteOperation - last_rewrite_token_indexes map[string]int + programs map[string][]RewriteOperation + lastRewriteTokenIndexes map[string]int } func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter { return &TokenStreamRewriter{ tokens: tokens, programs: map[string][]RewriteOperation{ - Default_Program_Name: make([]RewriteOperation, 0, Program_Init_Size), + DefaultProgramName: make([]RewriteOperation, 0, ProgramInitSize), }, - last_rewrite_token_indexes: map[string]int{}, + lastRewriteTokenIndexes: map[string]int{}, } } @@ -291,110 +293,110 @@ func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream { // Rollback the instruction stream for a program so that // the indicated instruction (via instructionIndex) is no // longer in the stream. UNTESTED! -func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int) { - is, ok := tsr.programs[program_name] +func (tsr *TokenStreamRewriter) Rollback(programName string, instructionIndex int) { + is, ok := tsr.programs[programName] if ok { - tsr.programs[program_name] = is[Min_Token_Index:instruction_index] + tsr.programs[programName] = is[MinTokenIndex:instructionIndex] } } -func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int) { - tsr.Rollback(Default_Program_Name, instruction_index) +func (tsr *TokenStreamRewriter) RollbackDefault(instructionIndex int) { + tsr.Rollback(DefaultProgramName, instructionIndex) } -// Reset the program so that no instructions exist -func (tsr *TokenStreamRewriter) DeleteProgram(program_name string) { - tsr.Rollback(program_name, Min_Token_Index) //TODO: double test on that cause lower bound is not included +// DeleteProgram reset the program so that no instructions exist +func (tsr *TokenStreamRewriter) DeleteProgram(programName string) { + tsr.Rollback(programName, MinTokenIndex) //TODO: double test on that cause lower bound is not included } func (tsr *TokenStreamRewriter) DeleteProgramDefault() { - tsr.DeleteProgram(Default_Program_Name) + tsr.DeleteProgram(DefaultProgramName) } -func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string) { +func (tsr *TokenStreamRewriter) InsertAfter(programName string, index int, text string) { // to insert after, just insert before next index (even if past end) var op RewriteOperation = NewInsertAfterOp(index, text, tsr.tokens) - rewrites := tsr.GetProgram(program_name) + rewrites := tsr.GetProgram(programName) op.SetInstructionIndex(len(rewrites)) - tsr.AddToProgram(program_name, op) + tsr.AddToProgram(programName, op) } func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string) { - tsr.InsertAfter(Default_Program_Name, index, text) + tsr.InsertAfter(DefaultProgramName, index, text) } -func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string) { - tsr.InsertAfter(program_name, token.GetTokenIndex(), text) +func (tsr *TokenStreamRewriter) InsertAfterToken(programName string, token Token, text string) { + tsr.InsertAfter(programName, token.GetTokenIndex(), text) } -func (tsr *TokenStreamRewriter) InsertBefore(program_name string, index int, text string) { +func (tsr *TokenStreamRewriter) InsertBefore(programName string, index int, text string) { var op RewriteOperation = NewInsertBeforeOp(index, text, tsr.tokens) - rewrites := tsr.GetProgram(program_name) + rewrites := tsr.GetProgram(programName) op.SetInstructionIndex(len(rewrites)) - tsr.AddToProgram(program_name, op) + tsr.AddToProgram(programName, op) } func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string) { - tsr.InsertBefore(Default_Program_Name, index, text) + tsr.InsertBefore(DefaultProgramName, index, text) } -func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string, token Token, text string) { - tsr.InsertBefore(program_name, token.GetTokenIndex(), text) +func (tsr *TokenStreamRewriter) InsertBeforeToken(programName string, token Token, text string) { + tsr.InsertBefore(programName, token.GetTokenIndex(), text) } -func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string) { +func (tsr *TokenStreamRewriter) Replace(programName string, from, to int, text string) { if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size() { panic(fmt.Sprintf("replace: range invalid: %d..%d(size=%d)", from, to, tsr.tokens.Size())) } var op RewriteOperation = NewReplaceOp(from, to, text, tsr.tokens) - rewrites := tsr.GetProgram(program_name) + rewrites := tsr.GetProgram(programName) op.SetInstructionIndex(len(rewrites)) - tsr.AddToProgram(program_name, op) + tsr.AddToProgram(programName, op) } func (tsr *TokenStreamRewriter) ReplaceDefault(from, to int, text string) { - tsr.Replace(Default_Program_Name, from, to, text) + tsr.Replace(DefaultProgramName, from, to, text) } func (tsr *TokenStreamRewriter) ReplaceDefaultPos(index int, text string) { tsr.ReplaceDefault(index, index, text) } -func (tsr *TokenStreamRewriter) ReplaceToken(program_name string, from, to Token, text string) { - tsr.Replace(program_name, from.GetTokenIndex(), to.GetTokenIndex(), text) +func (tsr *TokenStreamRewriter) ReplaceToken(programName string, from, to Token, text string) { + tsr.Replace(programName, from.GetTokenIndex(), to.GetTokenIndex(), text) } func (tsr *TokenStreamRewriter) ReplaceTokenDefault(from, to Token, text string) { - tsr.ReplaceToken(Default_Program_Name, from, to, text) + tsr.ReplaceToken(DefaultProgramName, from, to, text) } func (tsr *TokenStreamRewriter) ReplaceTokenDefaultPos(index Token, text string) { tsr.ReplaceTokenDefault(index, index, text) } -func (tsr *TokenStreamRewriter) Delete(program_name string, from, to int) { - tsr.Replace(program_name, from, to, "") +func (tsr *TokenStreamRewriter) Delete(programName string, from, to int) { + tsr.Replace(programName, from, to, "") } func (tsr *TokenStreamRewriter) DeleteDefault(from, to int) { - tsr.Delete(Default_Program_Name, from, to) + tsr.Delete(DefaultProgramName, from, to) } func (tsr *TokenStreamRewriter) DeleteDefaultPos(index int) { tsr.DeleteDefault(index, index) } -func (tsr *TokenStreamRewriter) DeleteToken(program_name string, from, to Token) { - tsr.ReplaceToken(program_name, from, to, "") +func (tsr *TokenStreamRewriter) DeleteToken(programName string, from, to Token) { + tsr.ReplaceToken(programName, from, to, "") } func (tsr *TokenStreamRewriter) DeleteTokenDefault(from, to Token) { - tsr.DeleteToken(Default_Program_Name, from, to) + tsr.DeleteToken(DefaultProgramName, from, to) } -func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndex(program_name string) int { - i, ok := tsr.last_rewrite_token_indexes[program_name] +func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndex(programName string) int { + i, ok := tsr.lastRewriteTokenIndexes[programName] if !ok { return -1 } @@ -402,15 +404,15 @@ func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndex(program_name string) in } func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndexDefault() int { - return tsr.GetLastRewriteTokenIndex(Default_Program_Name) + return tsr.GetLastRewriteTokenIndex(DefaultProgramName) } -func (tsr *TokenStreamRewriter) SetLastRewriteTokenIndex(program_name string, i int) { - tsr.last_rewrite_token_indexes[program_name] = i +func (tsr *TokenStreamRewriter) SetLastRewriteTokenIndex(programName string, i int) { + tsr.lastRewriteTokenIndexes[programName] = i } func (tsr *TokenStreamRewriter) InitializeProgram(name string) []RewriteOperation { - is := make([]RewriteOperation, 0, Program_Init_Size) + is := make([]RewriteOperation, 0, ProgramInitSize) tsr.programs[name] = is return is } @@ -429,18 +431,18 @@ func (tsr *TokenStreamRewriter) GetProgram(name string) []RewriteOperation { return is } -// Return the text from the original tokens altered per the +// GetTextDefault returns the text from the original tokens altered per the // instructions given to this rewriter. func (tsr *TokenStreamRewriter) GetTextDefault() string { return tsr.GetText( - Default_Program_Name, + DefaultProgramName, NewInterval(0, tsr.tokens.Size()-1)) } -// Return the text from the original tokens altered per the +// GetText returns the text from the original tokens altered per the // instructions given to this rewriter. -func (tsr *TokenStreamRewriter) GetText(program_name string, interval *Interval) string { - rewrites := tsr.programs[program_name] +func (tsr *TokenStreamRewriter) GetText(programName string, interval *Interval) string { + rewrites := tsr.programs[programName] start := interval.Start stop := interval.Stop // ensure start/end are in range @@ -482,11 +484,13 @@ func (tsr *TokenStreamRewriter) GetText(program_name string, interval *Interval) return buf.String() } -// We need to combine operations and report invalid operations (like -// overlapping replaces that are not completed nested). Inserts to -// same index need to be combined etc... Here are the cases: +// reduceToSingleOperationPerIndex combines operations and report invalid operations (like +// overlapping replaces that are not completed nested). Inserts to +// same index need to be combined etc... +// +// Here are the cases: // -// I.i.u I.j.v leave alone, nonoverlapping +// I.i.u I.j.v leave alone, non-overlapping // I.i.u I.i.v combine: Iivu // // R.i-j.u R.x-y.v | i-j in x-y delete first R @@ -498,38 +502,38 @@ func (tsr *TokenStreamRewriter) GetText(program_name string, interval *Interval) // D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right) // // I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before -// we're not deleting i) -// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping +// we're not deleting i) +// I.i.u R.x-y.v | i not in (x+1)-y leave alone, non-overlapping // R.x-y.v I.i.u | i in x-y ERROR // R.x-y.v I.x.u R.x-y.uv (combine, delete I) -// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping +// R.x-y.v I.i.u | i not in x-y leave alone, non-overlapping // // I.i.u = insert u before op @ index i // R.x-y.u = replace x-y indexed tokens with u // -// First we need to examine replaces. For any replace op: +// First we need to examine replaces. For any replace op: // -// 1. wipe out any insertions before op within that range. -// 2. Drop any replace op before that is contained completely within -// that range. -// 3. Throw exception upon boundary overlap with any previous replace. +// 1. wipe out any insertions before op within that range. +// 2. Drop any replace op before that is contained completely within +// that range. +// 3. Throw exception upon boundary overlap with any previous replace. // -// Then we can deal with inserts: +// Then we can deal with inserts: // -// 1. for any inserts to same index, combine even if not adjacent. -// 2. for any prior replace with same left boundary, combine this -// insert with replace and delete this replace. -// 3. throw exception if index in same range as previous replace +// 1. for any inserts to same index, combine even if not adjacent. +// 2. for any prior replace with same left boundary, combine this +// insert with replace and delete this 'replace'. +// 3. throw exception if index in same range as previous replace // -// Don't actually delete; make op null in list. Easier to walk list. -// Later we can throw as we add to index → op map. +// Don't actually delete; make op null in list. Easier to walk list. +// Later we can throw as we add to index → op map. // -// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the -// inserted stuff would be before the replace range. But, if you -// add tokens in front of a method body '{' and then delete the method -// body, I think the stuff before the '{' you added should disappear too. +// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the +// inserted stuff would be before the 'replace' range. But, if you +// add tokens in front of a method body '{' and then delete the method +// body, I think the stuff before the '{' you added should disappear too. // -// Return a map from token index to operation. +// The func returns a map from token index to operation. func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation { // WALK REPLACES for i := 0; i < len(rewrites); i++ { @@ -547,7 +551,7 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit if iop.index == rop.index { // E.g., insert before 2, delete 2..2; update replace // text to include insert before, kill insert - rewrites[iop.instruction_index] = nil + rewrites[iop.instructionIndex] = nil if rop.text != "" { rop.text = iop.text + rop.text } else { @@ -555,7 +559,7 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit } } else if iop.index > rop.index && iop.index <= rop.LastIndex { // delete insert as it's a no-op. - rewrites[iop.instruction_index] = nil + rewrites[iop.instructionIndex] = nil } } } @@ -564,7 +568,7 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit if prevop, ok := rewrites[j].(*ReplaceOp); ok { if prevop.index >= rop.index && prevop.LastIndex <= rop.LastIndex { // delete replace as it's a no-op. - rewrites[prevop.instruction_index] = nil + rewrites[prevop.instructionIndex] = nil continue } // throw exception unless disjoint or identical @@ -572,7 +576,7 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit // Delete special case of replace (text==null): // D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right) if prevop.text == "" && rop.text == "" && !disjoint { - rewrites[prevop.instruction_index] = nil + rewrites[prevop.instructionIndex] = nil rop.index = min(prevop.index, rop.index) rop.LastIndex = max(prevop.LastIndex, rop.LastIndex) println("new rop" + rop.String()) //TODO: remove console write, taken from Java version @@ -607,7 +611,7 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit if prevIop, ok := rewrites[j].(*InsertBeforeOp); ok { if prevIop.index == iop.GetIndex() { iop.SetText(iop.GetText() + prevIop.text) - rewrites[prevIop.instruction_index] = nil + rewrites[prevIop.instructionIndex] = nil } } } diff --git a/runtime/Go/antlr/v4/tokenstream_rewriter_test.go b/runtime/Go/antlr/v4/tokenstream_rewriter_test.go index a00265128a..5acfbb2aef 100644 --- a/runtime/Go/antlr/v4/tokenstream_rewriter_test.go +++ b/runtime/Go/antlr/v4/tokenstream_rewriter_test.go @@ -33,7 +33,7 @@ func TestInsertBeforeIndex0(t *testing.T) { } } -func prepare_rewriter(str string) *TokenStreamRewriter { +func prepareRewriter(str string) *TokenStreamRewriter { input := NewInputStream(str) lexer := NewLexerA(input) stream := NewCommonTokenStream(lexer, 0) @@ -42,31 +42,31 @@ func prepare_rewriter(str string) *TokenStreamRewriter { } type LexerTest struct { - input string - expected string - description string - expected_exception []string - ops func(*TokenStreamRewriter) + input string + expected string + description string + expectedException []string + ops func(*TokenStreamRewriter) } func NewLexerTest(input, expected, desc string, ops func(*TokenStreamRewriter)) LexerTest { return LexerTest{input: input, expected: expected, description: desc, ops: ops} } -func NewLexerExceptionTest(input string, expected_err []string, desc string, ops func(*TokenStreamRewriter)) LexerTest { - return LexerTest{input: input, expected_exception: expected_err, description: desc, ops: ops} +func NewLexerExceptionTest(input string, expectedErr []string, desc string, ops func(*TokenStreamRewriter)) LexerTest { + return LexerTest{input: input, expectedException: expectedErr, description: desc, ops: ops} } -func panic_tester(t *testing.T, expected_msg []string, r *TokenStreamRewriter) { +func panicTester(t *testing.T, expectedMsg []string, r *TokenStreamRewriter) { defer func() { r := recover() if r == nil { t.Errorf("Panic is expected, but finished normally") } else { - s_e := r.(string) - for _, e := range expected_msg { - if !strings.Contains(s_e, e) { - t.Errorf("Element [%s] is not in error message: [%s]", e, s_e) + sE := r.(string) + for _, e := range expectedMsg { + if !strings.Contains(sE, e) { + t.Errorf("Element [%s] is not in error message: [%s]", e, sE) } } } @@ -74,6 +74,7 @@ func panic_tester(t *testing.T, expected_msg []string, r *TokenStreamRewriter) { r.GetTextDefault() } +//goland:noinspection ALL func TestLexerA(t *testing.T) { tests := []LexerTest{ NewLexerTest("abc", "0abc", "InsertBeforeIndex0", @@ -307,10 +308,10 @@ func TestLexerA(t *testing.T) { for _, c := range tests { t.Run(c.description, func(t *testing.T) { - rewriter := prepare_rewriter(c.input) + rewriter := prepareRewriter(c.input) c.ops(rewriter) - if len(c.expected_exception) > 0 { - panic_tester(t, c.expected_exception, rewriter) + if len(c.expectedException) > 0 { + panicTester(t, c.expectedException, rewriter) } else { result := rewriter.GetTextDefault() if result != c.expected { @@ -382,7 +383,7 @@ func lexeraLexerInit() { } } -// LexerAInit initializes any static state used to implement LexerA. By default the +// LexerAInit initializes any static state used to implement LexerA. By default, the // static state used to implement the lexer is lazily initialized during the first call to // NewLexerA(). You can call this function if you wish to initialize the static state ahead // of time. @@ -410,6 +411,8 @@ func NewLexerA(input CharStream) *LexerA { } // LexerA tokens. +// +//goland:noinspection GoUnusedConst const ( LexerAA = 1 LexerAB = 2 diff --git a/runtime/Go/antlr/v4/transition.go b/runtime/Go/antlr/v4/transition.go index 36be4f7331..aad094cd15 100644 --- a/runtime/Go/antlr/v4/transition.go +++ b/runtime/Go/antlr/v4/transition.go @@ -37,18 +37,18 @@ type BaseTransition struct { } func NewBaseTransition(target ATNState) *BaseTransition { - + if target == nil { panic("target cannot be nil.") } - + t := new(BaseTransition) - + t.target = target // Are we epsilon, action, sempred? t.isEpsilon = false t.intervalSet = nil - + return t } @@ -72,7 +72,7 @@ func (t *BaseTransition) getSerializationType() int { return t.serializationType } -func (t *BaseTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *BaseTransition) Matches(_, _, _ int) bool { panic("Not implemented") } @@ -89,6 +89,7 @@ const ( TransitionPRECEDENCE = 10 ) +//goland:noinspection GoUnusedGlobalVariable var TransitionserializationNames = []string{ "INVALID", "EPSILON", @@ -127,20 +128,21 @@ var TransitionserializationNames = []string{ // TransitionPRECEDENCE //} +// AtomTransition // TODO: make all transitions sets? no, should remove set edges type AtomTransition struct { *BaseTransition } func NewAtomTransition(target ATNState, intervalSet int) *AtomTransition { - + t := new(AtomTransition) t.BaseTransition = NewBaseTransition(target) - + t.label = intervalSet // The token type or character value or, signifies special intervalSet. t.intervalSet = t.makeLabel() t.serializationType = TransitionATOM - + return t } @@ -150,7 +152,7 @@ func (t *AtomTransition) makeLabel() *IntervalSet { return s } -func (t *AtomTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *AtomTransition) Matches(symbol, _, _ int) bool { return t.label == symbol } @@ -160,47 +162,47 @@ func (t *AtomTransition) String() string { type RuleTransition struct { *BaseTransition - + followState ATNState ruleIndex, precedence int } func NewRuleTransition(ruleStart ATNState, ruleIndex, precedence int, followState ATNState) *RuleTransition { - + t := new(RuleTransition) t.BaseTransition = NewBaseTransition(ruleStart) - + t.ruleIndex = ruleIndex t.precedence = precedence t.followState = followState t.serializationType = TransitionRULE t.isEpsilon = true - + return t } -func (t *RuleTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *RuleTransition) Matches(_, _, _ int) bool { return false } type EpsilonTransition struct { *BaseTransition - + outermostPrecedenceReturn int } func NewEpsilonTransition(target ATNState, outermostPrecedenceReturn int) *EpsilonTransition { - + t := new(EpsilonTransition) t.BaseTransition = NewBaseTransition(target) - + t.serializationType = TransitionEPSILON t.isEpsilon = true t.outermostPrecedenceReturn = outermostPrecedenceReturn return t } -func (t *EpsilonTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *EpsilonTransition) Matches(_, _, _ int) bool { return false } @@ -210,15 +212,15 @@ func (t *EpsilonTransition) String() string { type RangeTransition struct { *BaseTransition - + start, stop int } func NewRangeTransition(target ATNState, start, stop int) *RangeTransition { - + t := new(RangeTransition) t.BaseTransition = NewBaseTransition(target) - + t.serializationType = TransitionRANGE t.start = start t.stop = stop @@ -232,7 +234,7 @@ func (t *RangeTransition) makeLabel() *IntervalSet { return s } -func (t *RangeTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *RangeTransition) Matches(symbol, _, _ int) bool { return symbol >= t.start && symbol <= t.stop } @@ -256,10 +258,10 @@ type BaseAbstractPredicateTransition struct { } func NewBasePredicateTransition(target ATNState) *BaseAbstractPredicateTransition { - + t := new(BaseAbstractPredicateTransition) t.BaseTransition = NewBaseTransition(target) - + return t } @@ -267,16 +269,16 @@ func (a *BaseAbstractPredicateTransition) IAbstractPredicateTransitionFoo() {} type PredicateTransition struct { *BaseAbstractPredicateTransition - + isCtxDependent bool ruleIndex, predIndex int } func NewPredicateTransition(target ATNState, ruleIndex, predIndex int, isCtxDependent bool) *PredicateTransition { - + t := new(PredicateTransition) t.BaseAbstractPredicateTransition = NewBasePredicateTransition(target) - + t.serializationType = TransitionPREDICATE t.ruleIndex = ruleIndex t.predIndex = predIndex @@ -285,7 +287,7 @@ func NewPredicateTransition(target ATNState, ruleIndex, predIndex int, isCtxDepe return t } -func (t *PredicateTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *PredicateTransition) Matches(_, _, _ int) bool { return false } @@ -299,16 +301,16 @@ func (t *PredicateTransition) String() string { type ActionTransition struct { *BaseTransition - + isCtxDependent bool ruleIndex, actionIndex, predIndex int } func NewActionTransition(target ATNState, ruleIndex, actionIndex int, isCtxDependent bool) *ActionTransition { - + t := new(ActionTransition) t.BaseTransition = NewBaseTransition(target) - + t.serializationType = TransitionACTION t.ruleIndex = ruleIndex t.actionIndex = actionIndex @@ -317,7 +319,7 @@ func NewActionTransition(target ATNState, ruleIndex, actionIndex int, isCtxDepen return t } -func (t *ActionTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *ActionTransition) Matches(_, _, _ int) bool { return false } @@ -330,10 +332,10 @@ type SetTransition struct { } func NewSetTransition(target ATNState, set *IntervalSet) *SetTransition { - + t := new(SetTransition) t.BaseTransition = NewBaseTransition(target) - + t.serializationType = TransitionSET if set != nil { t.intervalSet = set @@ -341,11 +343,11 @@ func NewSetTransition(target ATNState, set *IntervalSet) *SetTransition { t.intervalSet = NewIntervalSet() t.intervalSet.addOne(TokenInvalidType) } - + return t } -func (t *SetTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *SetTransition) Matches(symbol, _, _ int) bool { return t.intervalSet.contains(symbol) } @@ -358,13 +360,13 @@ type NotSetTransition struct { } func NewNotSetTransition(target ATNState, set *IntervalSet) *NotSetTransition { - + t := new(NotSetTransition) - + t.SetTransition = NewSetTransition(target, set) - + t.serializationType = TransitionNOTSET - + return t } @@ -381,10 +383,10 @@ type WildcardTransition struct { } func NewWildcardTransition(target ATNState) *WildcardTransition { - + t := new(WildcardTransition) t.BaseTransition = NewBaseTransition(target) - + t.serializationType = TransitionWILDCARD return t } @@ -399,23 +401,23 @@ func (t *WildcardTransition) String() string { type PrecedencePredicateTransition struct { *BaseAbstractPredicateTransition - + precedence int } func NewPrecedencePredicateTransition(target ATNState, precedence int) *PrecedencePredicateTransition { - + t := new(PrecedencePredicateTransition) t.BaseAbstractPredicateTransition = NewBasePredicateTransition(target) - + t.serializationType = TransitionPRECEDENCE t.precedence = precedence t.isEpsilon = true - + return t } -func (t *PrecedencePredicateTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { +func (t *PrecedencePredicateTransition) Matches(_, _, _ int) bool { return false } diff --git a/runtime/Go/antlr/v4/tree.go b/runtime/Go/antlr/v4/tree.go index 756f3092e6..26efc993e9 100644 --- a/runtime/Go/antlr/v4/tree.go +++ b/runtime/Go/antlr/v4/tree.go @@ -64,10 +64,10 @@ type BaseParseTreeVisitor struct{} var _ ParseTreeVisitor = &BaseParseTreeVisitor{} -func (v *BaseParseTreeVisitor) Visit(tree ParseTree) interface{} { return tree.Accept(v) } -func (v *BaseParseTreeVisitor) VisitChildren(node RuleNode) interface{} { return nil } -func (v *BaseParseTreeVisitor) VisitTerminal(node TerminalNode) interface{} { return nil } -func (v *BaseParseTreeVisitor) VisitErrorNode(node ErrorNode) interface{} { return nil } +func (v *BaseParseTreeVisitor) Visit(tree ParseTree) interface{} { return tree.Accept(v) } +func (v *BaseParseTreeVisitor) VisitChildren(_ RuleNode) interface{} { return nil } +func (v *BaseParseTreeVisitor) VisitTerminal(_ TerminalNode) interface{} { return nil } +func (v *BaseParseTreeVisitor) VisitErrorNode(_ ErrorNode) interface{} { return nil } // TODO //func (this ParseTreeVisitor) Visit(ctx) { @@ -101,10 +101,10 @@ type BaseParseTreeListener struct{} var _ ParseTreeListener = &BaseParseTreeListener{} -func (l *BaseParseTreeListener) VisitTerminal(node TerminalNode) {} -func (l *BaseParseTreeListener) VisitErrorNode(node ErrorNode) {} -func (l *BaseParseTreeListener) EnterEveryRule(ctx ParserRuleContext) {} -func (l *BaseParseTreeListener) ExitEveryRule(ctx ParserRuleContext) {} +func (l *BaseParseTreeListener) VisitTerminal(_ TerminalNode) {} +func (l *BaseParseTreeListener) VisitErrorNode(_ ErrorNode) {} +func (l *BaseParseTreeListener) EnterEveryRule(_ ParserRuleContext) {} +func (l *BaseParseTreeListener) ExitEveryRule(_ ParserRuleContext) {} type TerminalNodeImpl struct { parentCtx RuleContext @@ -123,7 +123,7 @@ func NewTerminalNodeImpl(symbol Token) *TerminalNodeImpl { return tn } -func (t *TerminalNodeImpl) GetChild(i int) Tree { +func (t *TerminalNodeImpl) GetChild(_ int) Tree { return nil } @@ -131,7 +131,7 @@ func (t *TerminalNodeImpl) GetChildren() []Tree { return nil } -func (t *TerminalNodeImpl) SetChildren(tree []Tree) { +func (t *TerminalNodeImpl) SetChildren(_ []Tree) { panic("Cannot set children on terminal node") } @@ -179,7 +179,7 @@ func (t *TerminalNodeImpl) String() string { return t.symbol.GetText() } -func (t *TerminalNodeImpl) ToStringTree(s []string, r Recognizer) string { +func (t *TerminalNodeImpl) ToStringTree(_ []string, _ Recognizer) string { return t.String() } @@ -214,10 +214,9 @@ func NewParseTreeWalker() *ParseTreeWalker { return new(ParseTreeWalker) } -// Performs a walk on the given parse tree starting at the root and going down recursively -// with depth-first search. On each node, EnterRule is called before -// recursively walking down into child nodes, then -// ExitRule is called after the recursive call to wind up. +// Walk performs a walk on the given parse tree starting at the root and going down recursively +// with depth-first search. On each node, [EnterRule] is called before +// recursively walking down into child nodes, then [ExitRule] is called after the recursive call to wind up. func (p *ParseTreeWalker) Walk(listener ParseTreeListener, t Tree) { switch tt := t.(type) { case ErrorNode: @@ -234,7 +233,7 @@ func (p *ParseTreeWalker) Walk(listener ParseTreeListener, t Tree) { } } -// Enters a grammar rule by first triggering the generic event {@link ParseTreeListener//EnterEveryRule} +// EnterRule enters a grammar rule by first triggering the generic event [ParseTreeListener].[EnterEveryRule] // then by triggering the event specific to the given parse tree node func (p *ParseTreeWalker) EnterRule(listener ParseTreeListener, r RuleNode) { ctx := r.GetRuleContext().(ParserRuleContext) @@ -242,8 +241,8 @@ func (p *ParseTreeWalker) EnterRule(listener ParseTreeListener, r RuleNode) { ctx.EnterRule(listener) } -// Exits a grammar rule by first triggering the event specific to the given parse tree node -// then by triggering the generic event {@link ParseTreeListener//ExitEveryRule} +// ExitRule exits a grammar rule by first triggering the event specific to the given parse tree node +// then by triggering the generic event [ParseTreeListener].ExitEveryRule func (p *ParseTreeWalker) ExitRule(listener ParseTreeListener, r RuleNode) { ctx := r.GetRuleContext().(ParserRuleContext) ctx.ExitRule(listener) @@ -257,6 +256,7 @@ type IterativeParseTreeWalker struct { *ParseTreeWalker } +//goland:noinspection GoUnusedExportedFunction func NewIterativeParseTreeWalker() *IterativeParseTreeWalker { return new(IterativeParseTreeWalker) } diff --git a/runtime/Go/antlr/v4/trees.go b/runtime/Go/antlr/v4/trees.go index d7dbb03228..f44c05d811 100644 --- a/runtime/Go/antlr/v4/trees.go +++ b/runtime/Go/antlr/v4/trees.go @@ -8,10 +8,8 @@ import "fmt" /** A set of utility routines useful for all kinds of ANTLR trees. */ -// Print out a whole tree in LISP form. {@link //getNodeText} is used on the -// -// node payloads to get the text for the nodes. Detect -// parse trees and extract data appropriately. +// TreesStringTree prints out a whole tree in LISP form. [getNodeText] is used on the +// node payloads to get the text for the nodes. Detects parse trees and extracts data appropriately. func TreesStringTree(tree Tree, ruleNames []string, recog Recognizer) string { if recog != nil { @@ -32,7 +30,7 @@ func TreesStringTree(tree Tree, ruleNames []string, recog Recognizer) string { } for i := 1; i < c; i++ { s = TreesStringTree(tree.GetChild(i), ruleNames, nil) - res += (" " + s) + res += " " + s } res += ")" return res @@ -62,7 +60,7 @@ func TreesGetNodeText(t Tree, ruleNames []string, recog Parser) string { } } - // no recog for rule names + // no recognition for rule names payload := t.GetPayload() if p2, ok := payload.(Token); ok { return p2.GetText() @@ -71,7 +69,9 @@ func TreesGetNodeText(t Tree, ruleNames []string, recog Parser) string { return fmt.Sprint(t.GetPayload()) } -// Return ordered list of all children of this node +// TreesGetChildren returns am ordered list of all children of this node +// +//goland:noinspection GoUnusedExportedFunction func TreesGetChildren(t Tree) []Tree { list := make([]Tree, 0) for i := 0; i < t.GetChildCount(); i++ { @@ -80,9 +80,10 @@ func TreesGetChildren(t Tree) []Tree { return list } -// Return a list of all ancestors of this node. The first node of +// TreesgetAncestors returns a list of all ancestors of this node. The first node of list is the root +// and the last node is the parent of this node. // -// list is the root and the last is the parent of this node. +//goland:noinspection GoUnusedExportedFunction func TreesgetAncestors(t Tree) []Tree { ancestors := make([]Tree, 0) t = t.GetParent() @@ -94,10 +95,12 @@ func TreesgetAncestors(t Tree) []Tree { return ancestors } +//goland:noinspection GoUnusedExportedFunction func TreesFindAllTokenNodes(t ParseTree, ttype int) []ParseTree { return TreesfindAllNodes(t, ttype, true) } +//goland:noinspection GoUnusedExportedFunction func TreesfindAllRuleNodes(t ParseTree, ruleIndex int) []ParseTree { return TreesfindAllNodes(t, ruleIndex, false) } @@ -129,6 +132,7 @@ func treesFindAllNodes(t ParseTree, index int, findTokens bool, nodes *[]ParseTr } } +//goland:noinspection GoUnusedExportedFunction func TreesDescendants(t ParseTree) []ParseTree { nodes := []ParseTree{t} for i := 0; i < t.GetChildCount(); i++ { diff --git a/runtime/Go/antlr/v4/utils.go b/runtime/Go/antlr/v4/utils.go index 9fad5d916b..900e0449aa 100644 --- a/runtime/Go/antlr/v4/utils.go +++ b/runtime/Go/antlr/v4/utils.go @@ -31,7 +31,7 @@ func intMax(a, b int) int { type IntStack []int -var ErrEmptyStack = errors.New("Stack is empty") +var ErrEmptyStack = errors.New("stack is empty") func (s *IntStack) Pop() (int, error) { l := len(*s) - 1 @@ -47,10 +47,6 @@ func (s *IntStack) Push(e int) { *s = append(*s, e) } -type comparable interface { - Equals(other Collectable[any]) bool -} - func standardEqualsFunction(a Collectable[any], b Collectable[any]) bool { return a.Equals(b) @@ -61,7 +57,7 @@ func standardHashFunction(a interface{}) int { return h.Hash() } - panic("Not Hasher") + panic("Not 'Hasher'") } type hasher interface { @@ -74,6 +70,7 @@ func indexForBit(bit int) int { return bit / bitsPerWord } +//goland:noinspection GoUnusedExportedFunction,GoUnusedFunction func wordForBit(data []uint64, bit int) uint64 { idx := indexForBit(bit) if idx >= len(data) { @@ -94,6 +91,8 @@ type BitSet struct { data []uint64 } +// NewBitSet creates a new bitwise set +// TODO: See if we can replace with the standard library's BitSet func NewBitSet() *BitSet { return &BitSet{} } @@ -123,7 +122,7 @@ func (b *BitSet) or(set *BitSet) { setLen := set.minLen() maxLen := intMax(bLen, setLen) if maxLen > len(b.data) { - // Increase the size of len(b.data) to repesent the bits in both sets. + // Increase the size of len(b.data) to represent the bits in both sets. data := make([]uint64, maxLen) copy(data, b.data) b.data = data @@ -288,6 +287,7 @@ func EscapeWhitespace(s string, escapeSpaces bool) string { return s } +//goland:noinspection GoUnusedExportedFunction func TerminalNodeToStringArray(sa []TerminalNode) []string { st := make([]string, len(sa)) @@ -298,6 +298,7 @@ func TerminalNodeToStringArray(sa []TerminalNode) []string { return st } +//goland:noinspection GoUnusedExportedFunction func PrintArrayJavaStyle(sa []string) string { var buffer bytes.Buffer diff --git a/runtime/Go/antlr/v4/utils_set.go b/runtime/Go/antlr/v4/utils_set.go index c9bd6751e3..9c361e078c 100644 --- a/runtime/Go/antlr/v4/utils_set.go +++ b/runtime/Go/antlr/v4/utils_set.go @@ -227,6 +227,7 @@ func newArray2DHashSetWithCap( return ret } +//goland:noinspection GoUnusedExportedFunction,GoUnusedFunction func newArray2DHashSet( hashcodeFunction func(interface{}) int, equalsFunction func(Collectable[any], Collectable[any]) bool, diff --git a/runtime/Go/antlr/v4/utils_test.go b/runtime/Go/antlr/v4/utils_test.go index ed274ef339..17bb240daf 100644 --- a/runtime/Go/antlr/v4/utils_test.go +++ b/runtime/Go/antlr/v4/utils_test.go @@ -8,7 +8,7 @@ func testBitSet(t *testing.T, bs *BitSet, str string, length int, contains []int t.Errorf("%+v.String() = %q, want %q", bs, got, want) } if got, want := bs.length(), length; got != want { - t.Errorf("%+v.length() = %q, want %q", bs, got, want) + t.Errorf("%+v.Length() = %q, want %q", bs, got, want) } for i := 0; i < len(bs.data)*bitsPerWord; i++ { var want bool @@ -30,6 +30,7 @@ func testBitSet(t *testing.T, bs *BitSet, str string, length int, contains []int } } +//goland:noinspection GoBoolExpressions func TestBitSet(t *testing.T) { bs1 := NewBitSet() testBitSet(t, bs1, "{}", 0, []int{}, 2147483647, 0)