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
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// PredPrediction maps a predicate to a predicted alternative.
|
|
|
|
type PredPrediction struct {
|
|
|
|
alt int
|
|
|
|
pred SemanticContext
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPredPrediction(pred SemanticContext, alt int) *PredPrediction {
|
|
|
|
return &PredPrediction{alt: alt, pred: pred}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PredPrediction) String() string {
|
|
|
|
return "(" + fmt.Sprint(p.pred) + ", " + fmt.Sprint(p.alt) + ")"
|
|
|
|
}
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
// DFAState represents a set of possible [ATN] configurations. As Aho, Sethi,
|
2023-05-29 21:03:29 +00:00
|
|
|
// 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,
|
2024-08-19 08:01:33 +00:00
|
|
|
// after reading input a1, a2,..an, the DFA is in a state that represents the
|
2023-05-29 21:03:29 +00:00
|
|
|
// subset T of the states of the ATN that are reachable from the ATN's start
|
2024-08-19 08:01:33 +00:00
|
|
|
// 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
|
2023-05-29 21:03:29 +00:00
|
|
|
// 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.
|
|
|
|
//
|
2024-08-19 08:01:33 +00:00
|
|
|
// 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
|
2023-05-29 21:03:29 +00:00
|
|
|
// (if any) followed to arrive at that state.
|
|
|
|
//
|
2024-08-19 08:01:33 +00:00
|
|
|
// A [DFAState] may have multiple references to a particular state, but with
|
|
|
|
// different [ATN] contexts (with same or different alts) meaning that state was
|
2023-05-29 21:03:29 +00:00
|
|
|
// reached via a different set of rule invocations.
|
|
|
|
type DFAState struct {
|
|
|
|
stateNumber int
|
2024-08-19 08:01:33 +00:00
|
|
|
configs *ATNConfigSet
|
2023-05-29 21:03:29 +00:00
|
|
|
|
|
|
|
// edges elements point to the target of the symbol. Shift up by 1 so (-1)
|
|
|
|
// Token.EOF maps to the first element.
|
|
|
|
edges []*DFAState
|
|
|
|
|
|
|
|
isAcceptState bool
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
// prediction is the 'ttype' we match or alt we predict if the state is 'accept'.
|
2023-05-29 21:03:29 +00:00
|
|
|
// Set to ATN.INVALID_ALT_NUMBER when predicates != nil or
|
|
|
|
// requiresFullContext.
|
|
|
|
prediction int
|
|
|
|
|
|
|
|
lexerActionExecutor *LexerActionExecutor
|
|
|
|
|
|
|
|
// requiresFullContext indicates it was created during an SLL prediction that
|
|
|
|
// discovered a conflict between the configurations in the state. Future
|
|
|
|
// ParserATNSimulator.execATN invocations immediately jump doing
|
|
|
|
// full context prediction if true.
|
|
|
|
requiresFullContext bool
|
|
|
|
|
|
|
|
// predicates is the predicates associated with the ATN configurations of the
|
|
|
|
// DFA state during SLL parsing. When we have predicates, requiresFullContext
|
|
|
|
// is false, since full context prediction evaluates predicates on-the-fly. If
|
|
|
|
// d is
|
|
|
|
// not nil, then prediction is ATN.INVALID_ALT_NUMBER.
|
|
|
|
//
|
|
|
|
// We only use these for non-requiresFullContext but conflicting states. That
|
|
|
|
// means we know from the context (it's $ or we don't dip into outer context)
|
|
|
|
// that it's an ambiguity not a conflict.
|
|
|
|
//
|
|
|
|
// This list is computed by
|
|
|
|
// ParserATNSimulator.predicateDFAState.
|
|
|
|
predicates []*PredPrediction
|
|
|
|
}
|
|
|
|
|
2024-08-19 08:01:33 +00:00
|
|
|
func NewDFAState(stateNumber int, configs *ATNConfigSet) *DFAState {
|
2023-05-29 21:03:29 +00:00
|
|
|
if configs == nil {
|
2024-08-19 08:01:33 +00:00
|
|
|
configs = NewATNConfigSet(false)
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &DFAState{configs: configs, stateNumber: stateNumber}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAltSet gets the set of all alts mentioned by all ATN configurations in d.
|
2023-08-17 05:15:28 +00:00
|
|
|
func (d *DFAState) GetAltSet() []int {
|
|
|
|
var alts []int
|
2023-05-29 21:03:29 +00:00
|
|
|
|
|
|
|
if d.configs != nil {
|
2024-08-19 08:01:33 +00:00
|
|
|
for _, c := range d.configs.configs {
|
2023-08-17 05:15:28 +00:00
|
|
|
alts = append(alts, c.GetAlt())
|
2023-05-29 21:03:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-17 05:15:28 +00:00
|
|
|
if len(alts) == 0 {
|
2023-05-29 21:03:29 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return alts
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) getEdges() []*DFAState {
|
|
|
|
return d.edges
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) numEdges() int {
|
|
|
|
return len(d.edges)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) getIthEdge(i int) *DFAState {
|
|
|
|
return d.edges[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) setEdges(newEdges []*DFAState) {
|
|
|
|
d.edges = newEdges
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) setIthEdge(i int, edge *DFAState) {
|
|
|
|
d.edges[i] = edge
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) setPrediction(v int) {
|
|
|
|
d.prediction = v
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DFAState) String() string {
|
|
|
|
var s string
|
|
|
|
if d.isAcceptState {
|
|
|
|
if d.predicates != nil {
|
|
|
|
s = "=>" + fmt.Sprint(d.predicates)
|
|
|
|
} else {
|
|
|
|
s = "=>" + fmt.Sprint(d.prediction)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("%d:%s%s", d.stateNumber, fmt.Sprint(d.configs), s)
|
|
|
|
}
|
|
|
|
|
2023-08-17 05:15:28 +00:00
|
|
|
func (d *DFAState) Hash() int {
|
2023-05-29 21:03:29 +00:00
|
|
|
h := murmurInit(7)
|
2023-08-17 05:15:28 +00:00
|
|
|
h = murmurUpdate(h, d.configs.Hash())
|
2023-05-29 21:03:29 +00:00
|
|
|
return murmurFinish(h, 1)
|
|
|
|
}
|
2023-08-17 05:15:28 +00:00
|
|
|
|
|
|
|
// Equals returns whether d equals other. Two DFAStates are equal if their ATN
|
|
|
|
// configuration sets are the same. This method is used to see if a state
|
|
|
|
// already exists.
|
|
|
|
//
|
|
|
|
// Because the number of alternatives and number of ATN configurations are
|
|
|
|
// finite, there is a finite number of DFA states that can be processed. This is
|
|
|
|
// necessary to show that the algorithm terminates.
|
|
|
|
//
|
|
|
|
// Cannot test the DFA state numbers here because in
|
|
|
|
// ParserATNSimulator.addDFAState we need to know if any other state exists that
|
|
|
|
// has d exact set of ATN configurations. The stateNumber is irrelevant.
|
|
|
|
func (d *DFAState) Equals(o Collectable[*DFAState]) bool {
|
|
|
|
if d == o {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return d.configs.Equals(o.(*DFAState).configs)
|
|
|
|
}
|