/**
* Add an edge to the DFA, if possible. This method calls
* {@link #addDFAState} to ensure the {@code to} state is present in the
* DFA. If {@code from} is {@code null}, or if {@code t} is outside the
* range of edges that can be represented in the DFA tables, this method
* returns without adding the edge to the DFA.
*
* <p>If {@code to} is {@code null}, this method returns {@code null}.
* Otherwise, this method returns the {@link DFAState} returned by calling
* {@link #addDFAState} for the {@code to} state.</p>
*
* @param dfa The DFA
* @param from The source state for the edge
* @param t The input symbol
* @param to The target state for the edge
*
* @return If {@code to} is {@code null}, this method returns {@code null};
* otherwise this method returns the result of calling {@link #addDFAState}
* on {@code to}
*/
protected DFAState AddDFAEdge(DFA dfa,
DFAState from,
int t,
DFAState to)
{
if (debug)
{
Console.WriteLine("EDGE " + from + " -> " + to + " upon " + GetTokenName(t));
}
if (to == null)
{
return null;
}
to = AddDFAState(dfa, to); // used existing if possible not incoming
if (from == null || t < -1 || t > atn.maxTokenType)
{
return to;
}
lock (from)
{
if (from.edges == null)
{
from.edges = new DFAState[atn.maxTokenType + 1 + 1];
}
from.edges[t + 1] = to; // connect
}
if (debug)
{
Console.WriteLine("DFA=\n" + dfa.ToString(parser != null ? parser.Vocabulary : Vocabulary.EmptyVocabulary));
}
return to;
}