2023-08-17 05:15:28 +00:00
|
|
|
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
2023-05-29 21:03:29 +00:00
|
|
|
// Use of this file is governed by the BSD 3-clause license that
|
|
|
|
// can be found in the LICENSE.txt file in the project root.
|
|
|
|
|
|
|
|
package antlr
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
)
|
2023-05-29 21:03:29 +00:00
|
|
|
|
|
|
|
// Constants for serialization.
|
|
|
|
const (
|
|
|
|
ATNStateInvalidType = 0
|
|
|
|
ATNStateBasic = 1
|
|
|
|
ATNStateRuleStart = 2
|
|
|
|
ATNStateBlockStart = 3
|
|
|
|
ATNStatePlusBlockStart = 4
|
|
|
|
ATNStateStarBlockStart = 5
|
|
|
|
ATNStateTokenStart = 6
|
|
|
|
ATNStateRuleStop = 7
|
|
|
|
ATNStateBlockEnd = 8
|
|
|
|
ATNStateStarLoopBack = 9
|
|
|
|
ATNStateStarLoopEntry = 10
|
|
|
|
ATNStatePlusLoopBack = 11
|
|
|
|
ATNStateLoopEnd = 12
|
|
|
|
|
|
|
|
ATNStateInvalidStateNumber = -1
|
|
|
|
)
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
//goland:noinspection GoUnusedGlobalVariable
|
2023-05-29 21:03:29 +00:00
|
|
|
var ATNStateInitialNumTransitions = 4
|
|
|
|
|
|
|
|
type ATNState interface {
|
|
|
|
GetEpsilonOnlyTransitions() bool
|
|
|
|
|
|
|
|
GetRuleIndex() int
|
|
|
|
SetRuleIndex(int)
|
|
|
|
|
|
|
|
GetNextTokenWithinRule() *IntervalSet
|
|
|
|
SetNextTokenWithinRule(*IntervalSet)
|
|
|
|
|
|
|
|
GetATN() *ATN
|
|
|
|
SetATN(*ATN)
|
|
|
|
|
|
|
|
GetStateType() int
|
|
|
|
|
|
|
|
GetStateNumber() int
|
|
|
|
SetStateNumber(int)
|
|
|
|
|
|
|
|
GetTransitions() []Transition
|
|
|
|
SetTransitions([]Transition)
|
|
|
|
AddTransition(Transition, int)
|
|
|
|
|
|
|
|
String() string
|
2023-08-17 05:15:28 +00:00
|
|
|
Hash() int
|
|
|
|
Equals(Collectable[ATNState]) bool
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type BaseATNState struct {
|
|
|
|
// NextTokenWithinRule caches lookahead during parsing. Not used during construction.
|
|
|
|
NextTokenWithinRule *IntervalSet
|
|
|
|
|
|
|
|
// atn is the current ATN.
|
|
|
|
atn *ATN
|
|
|
|
|
|
|
|
epsilonOnlyTransitions bool
|
|
|
|
|
|
|
|
// ruleIndex tracks the Rule index because there are no Rule objects at runtime.
|
|
|
|
ruleIndex int
|
|
|
|
|
|
|
|
stateNumber int
|
|
|
|
|
|
|
|
stateType int
|
|
|
|
|
|
|
|
// Track the transitions emanating from this ATN state.
|
|
|
|
transitions []Transition
|
|
|
|
}
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
func NewATNState() *BaseATNState {
|
2023-05-29 21:03:29 +00:00
|
|
|
return &BaseATNState{stateNumber: ATNStateInvalidStateNumber, stateType: ATNStateInvalidType}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) GetRuleIndex() int {
|
|
|
|
return as.ruleIndex
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) SetRuleIndex(v int) {
|
|
|
|
as.ruleIndex = v
|
|
|
|
}
|
|
|
|
func (as *BaseATNState) GetEpsilonOnlyTransitions() bool {
|
|
|
|
return as.epsilonOnlyTransitions
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) GetATN() *ATN {
|
|
|
|
return as.atn
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) SetATN(atn *ATN) {
|
|
|
|
as.atn = atn
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) GetTransitions() []Transition {
|
|
|
|
return as.transitions
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) SetTransitions(t []Transition) {
|
|
|
|
as.transitions = t
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) GetStateType() int {
|
|
|
|
return as.stateType
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) GetStateNumber() int {
|
|
|
|
return as.stateNumber
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) SetStateNumber(stateNumber int) {
|
|
|
|
as.stateNumber = stateNumber
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) GetNextTokenWithinRule() *IntervalSet {
|
|
|
|
return as.NextTokenWithinRule
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) SetNextTokenWithinRule(v *IntervalSet) {
|
|
|
|
as.NextTokenWithinRule = v
|
|
|
|
}
|
|
|
|
|
2023-08-17 05:15:28 +00:00
|
|
|
func (as *BaseATNState) Hash() int {
|
2023-05-29 21:03:29 +00:00
|
|
|
return as.stateNumber
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) String() string {
|
|
|
|
return strconv.Itoa(as.stateNumber)
|
|
|
|
}
|
|
|
|
|
2023-08-17 05:15:28 +00:00
|
|
|
func (as *BaseATNState) Equals(other Collectable[ATNState]) bool {
|
2023-05-29 21:03:29 +00:00
|
|
|
if ot, ok := other.(ATNState); ok {
|
|
|
|
return as.stateNumber == ot.GetStateNumber()
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) isNonGreedyExitState() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (as *BaseATNState) AddTransition(trans Transition, index int) {
|
|
|
|
if len(as.transitions) == 0 {
|
|
|
|
as.epsilonOnlyTransitions = trans.getIsEpsilon()
|
|
|
|
} else if as.epsilonOnlyTransitions != trans.getIsEpsilon() {
|
2024-08-19 08:01:33 +00:00
|
|
|
_, _ = fmt.Fprintf(os.Stdin, "ATN state %d has both epsilon and non-epsilon transitions.\n", as.stateNumber)
|
2023-05-29 21:03:29 +00:00
|
|
|
as.epsilonOnlyTransitions = false
|
|
|
|
}
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
// TODO: Check code for already present compared to the Java equivalent
|
|
|
|
//alreadyPresent := false
|
|
|
|
//for _, t := range as.transitions {
|
|
|
|
// if t.getTarget().GetStateNumber() == trans.getTarget().GetStateNumber() {
|
|
|
|
// if t.getLabel() != nil && trans.getLabel() != nil && trans.getLabel().Equals(t.getLabel()) {
|
|
|
|
// alreadyPresent = true
|
|
|
|
// break
|
|
|
|
// }
|
|
|
|
// } else if t.getIsEpsilon() && trans.getIsEpsilon() {
|
|
|
|
// alreadyPresent = true
|
|
|
|
// break
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//if !alreadyPresent {
|
2023-05-29 21:03:29 +00:00
|
|
|
if index == -1 {
|
|
|
|
as.transitions = append(as.transitions, trans)
|
|
|
|
} else {
|
|
|
|
as.transitions = append(as.transitions[:index], append([]Transition{trans}, as.transitions[index:]...)...)
|
|
|
|
// TODO: as.transitions.splice(index, 1, trans)
|
|
|
|
}
|
2024-08-19 08:01:33 +00:00
|
|
|
//} else {
|
|
|
|
// _, _ = fmt.Fprintf(os.Stderr, "Transition already present in state %d\n", as.stateNumber)
|
|
|
|
//}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type BasicState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewBasicState() *BasicState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &BasicState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateBasic,
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type DecisionState interface {
|
|
|
|
ATNState
|
|
|
|
|
|
|
|
getDecision() int
|
|
|
|
setDecision(int)
|
|
|
|
|
|
|
|
getNonGreedy() bool
|
|
|
|
setNonGreedy(bool)
|
|
|
|
}
|
|
|
|
|
|
|
|
type BaseDecisionState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
decision int
|
|
|
|
nonGreedy bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewBaseDecisionState() *BaseDecisionState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateBasic,
|
|
|
|
},
|
|
|
|
decision: -1,
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BaseDecisionState) getDecision() int {
|
|
|
|
return s.decision
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BaseDecisionState) setDecision(b int) {
|
|
|
|
s.decision = b
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BaseDecisionState) getNonGreedy() bool {
|
|
|
|
return s.nonGreedy
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BaseDecisionState) setNonGreedy(b bool) {
|
|
|
|
s.nonGreedy = b
|
|
|
|
}
|
|
|
|
|
|
|
|
type BlockStartState interface {
|
|
|
|
DecisionState
|
|
|
|
|
|
|
|
getEndState() *BlockEndState
|
|
|
|
setEndState(*BlockEndState)
|
|
|
|
}
|
|
|
|
|
|
|
|
// BaseBlockStartState is the start of a regular (...) block.
|
|
|
|
type BaseBlockStartState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseDecisionState
|
2023-05-29 21:03:29 +00:00
|
|
|
endState *BlockEndState
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewBlockStartState() *BaseBlockStartState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &BaseBlockStartState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateBasic,
|
|
|
|
},
|
|
|
|
decision: -1,
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BaseBlockStartState) getEndState() *BlockEndState {
|
|
|
|
return s.endState
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BaseBlockStartState) setEndState(b *BlockEndState) {
|
|
|
|
s.endState = b
|
|
|
|
}
|
|
|
|
|
|
|
|
type BasicBlockStartState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseBlockStartState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewBasicBlockStartState() *BasicBlockStartState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &BasicBlockStartState{
|
|
|
|
BaseBlockStartState: BaseBlockStartState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateBlockStart,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ BlockStartState = &BasicBlockStartState{}
|
|
|
|
|
|
|
|
// BlockEndState is a terminal node of a simple (a|b|c) block.
|
|
|
|
type BlockEndState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
startState ATNState
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewBlockEndState() *BlockEndState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &BlockEndState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateBlockEnd,
|
|
|
|
},
|
|
|
|
startState: nil,
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RuleStopState is the last node in the ATN for a rule, unless that rule is the
|
|
|
|
// start symbol. In that case, there is one transition to EOF. Later, we might
|
|
|
|
// encode references to all calls to this rule to compute FOLLOW sets for error
|
|
|
|
// handling.
|
|
|
|
type RuleStopState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewRuleStopState() *RuleStopState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &RuleStopState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateRuleStop,
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type RuleStartState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
stopState ATNState
|
|
|
|
isPrecedenceRule bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRuleStartState() *RuleStartState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &RuleStartState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateRuleStart,
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PlusLoopbackState is a decision state for A+ and (A|B)+. It has two
|
|
|
|
// transitions: one to the loop back to start of the block, and one to exit.
|
|
|
|
type PlusLoopbackState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseDecisionState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewPlusLoopbackState() *PlusLoopbackState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &PlusLoopbackState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStatePlusLoopBack,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PlusBlockStartState is the start of a (A|B|...)+ loop. Technically it is a
|
|
|
|
// decision state; we don't use it for code generation. Somebody might need it,
|
|
|
|
// it is included for completeness. In reality, PlusLoopbackState is the real
|
|
|
|
// decision-making node for A+.
|
|
|
|
type PlusBlockStartState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseBlockStartState
|
2023-05-29 21:03:29 +00:00
|
|
|
loopBackState ATNState
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPlusBlockStartState() *PlusBlockStartState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &PlusBlockStartState{
|
|
|
|
BaseBlockStartState: BaseBlockStartState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStatePlusBlockStart,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ BlockStartState = &PlusBlockStartState{}
|
|
|
|
|
|
|
|
// StarBlockStartState is the block that begins a closure loop.
|
|
|
|
type StarBlockStartState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseBlockStartState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewStarBlockStartState() *StarBlockStartState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &StarBlockStartState{
|
|
|
|
BaseBlockStartState: BaseBlockStartState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateStarBlockStart,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ BlockStartState = &StarBlockStartState{}
|
|
|
|
|
|
|
|
type StarLoopbackState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewStarLoopbackState() *StarLoopbackState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &StarLoopbackState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateStarLoopBack,
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type StarLoopEntryState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseDecisionState
|
2023-05-29 21:03:29 +00:00
|
|
|
loopBackState ATNState
|
|
|
|
precedenceRuleDecision bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewStarLoopEntryState() *StarLoopEntryState {
|
|
|
|
// False precedenceRuleDecision indicates whether s state can benefit from a precedence DFA during SLL decision making.
|
2024-08-19 08:01:33 +00:00
|
|
|
return &StarLoopEntryState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateStarLoopEntry,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// LoopEndState marks the end of a * or + loop.
|
|
|
|
type LoopEndState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseATNState
|
2023-05-29 21:03:29 +00:00
|
|
|
loopBackState ATNState
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewLoopEndState() *LoopEndState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &LoopEndState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateLoopEnd,
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TokensStartState is the Tokens rule start state linking to each lexer rule start state.
|
|
|
|
type TokensStartState struct {
|
2024-08-19 08:01:33 +00:00
|
|
|
BaseDecisionState
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewTokensStartState() *TokensStartState {
|
2024-08-19 08:01:33 +00:00
|
|
|
return &TokensStartState{
|
|
|
|
BaseDecisionState: BaseDecisionState{
|
|
|
|
BaseATNState: BaseATNState{
|
|
|
|
stateNumber: ATNStateInvalidStateNumber,
|
|
|
|
stateType: ATNStateTokenStart,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|