Class DFAState

java.lang.Object
org.antlr.v4.runtime.dfa.DFAState

public class DFAState extends Object
A DFA state 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 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→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 (if any) followed to arrive at that state.

A DFA state 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.

  • Field Details

  • Constructor Details

    • DFAState

      public DFAState(@NotNull DFA dfa, @NotNull ATNConfigSet configs)
      Constructs a new DFAState for a DFA.

      This constructor initializes the DFA state using empty edge maps provided by the specified DFA.

      Parameters:
      dfa - The DFA.
      configs - The set of ATN configurations defining this state.
    • DFAState

      public DFAState(@NotNull EmptyEdgeMap<DFAState> emptyEdges, @NotNull EmptyEdgeMap<DFAState> emptyContextEdges, @NotNull ATNConfigSet configs)
      Constructs a new DFAState with explicit initial values for the outgoing edge and context edge maps.

      The empty maps provided to this constructor contain information about the range of edge values which are allowed to be stored in the map. Since edges outside the allowed range are simply dropped from the DFA, this offers several potential benefits:

      • In the general case, empty edge maps are initialized to support the range of values expected to be seen during prediction, which is in turn used to minimize the memory overhead associated with a dynamically-constructed DFA.
      • As a special case, empty edge maps can be intentionally constructed so the DFA will not store edges with specific values. In the limit, a range which does not contain any allowed edges can be used to prevent the DFA from storing any edges, forcing the prediction algorithm to recompute all transitions as they are needed.
      Parameters:
      emptyEdges - The empty edge map.
      emptyContextEdges - The empty context edge map.
      configs - The set of ATN configurations defining this state.
  • Method Details

    • isContextSensitive

      public final boolean isContextSensitive()
    • isContextSymbol

      public final boolean isContextSymbol(int symbol)
    • contextSymbolAfterEdge

      public final boolean contextSymbolAfterEdge(int symbol)
      Same test as isContextSymbol(int) for a caller that has already read edges (the warm LL loop, which would otherwise load the map twice).
    • setContextSymbol

      public final void setContextSymbol(int symbol)
    • setContextSensitive

      public void setContextSensitive(ATN atn)
    • getAcceptStateInfo

      public final AcceptStateInfo getAcceptStateInfo()
    • setAcceptState

      public final void setAcceptState(AcceptStateInfo acceptStateInfo)
    • isAcceptState

      public final boolean isAcceptState()
    • getPrediction

      public final int getPrediction()
    • getLexerActionExecutor

      public final LexerActionExecutor getLexerActionExecutor()
    • getTarget

      public final DFAState getTarget(int symbol)
      PERF: final so warm execDFA edge walks can monomorphically inline through to EdgeMap.get(int) (Hash/Array) without a virtual call at this layer.
    • getLexerTarget

      public final DFAState getLexerTarget(int symbol)
      Lexer edge lookup. ASCII symbols hit asciiEdges (one volatile read and an array load). Wider code points use an identity table when one has been published, otherwise EdgeMap.get(int). HashEdgeMap.get(int) stays branch-free so parser edge walks do not pay a layout test.
    • setTarget

      public final void setTarget(int symbol, DFAState target)
    • directValuesOf

      private static Object[] directValuesOf(AbstractEdgeMap<DFAState> edgeMap)
    • isEdgesEmpty

      public final boolean isEdgesEmpty()
      Returns true if this state has no outgoing symbol edges.

      PERF: Prefer this over getEdgeMap().isEmpty() on hot paths. getEdgeMap() materializes a boxed Map (historically a TreeMap for HashEdgeMap) solely to answer a boolean question — profiled at ~17% of end-to-end Java parse CPU when DFA.isEmpty() used that pattern for every precedence-DFA prediction.

      Returns:
      true if there are no symbol edges from this state
    • isContextEdgesEmpty

      public final boolean isContextEdgesEmpty()
      Returns true if this state has no context edges.

      Same allocation-avoidance rationale as isEdgesEmpty().

      Returns:
      true if there are no context edges from this state
    • getEdgeMap

      public Map<Integer,DFAState> getEdgeMap()
    • getContextTarget

      public DFAState getContextTarget(int invokingState)
    • setContextTarget

      public void setContextTarget(int invokingState, DFAState target)
    • getContextEdgeMap

      public Map<Integer,DFAState> getContextEdgeMap()
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object o)
      Two DFAState instances 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(org.antlr.v4.runtime.dfa.DFA, org.antlr.v4.runtime.atn.ATNConfigSet, org.antlr.v4.runtime.atn.PredictionContextCache) we need to know if any other state exists that has this exact set of ATN configurations. The stateNumber is irrelevant.

      Overrides:
      equals in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object