antlr/antlr4 · warning · UnsupportedOperationException
The precedenceDfa field cannot change after a DFA is constru
Error message
The precedenceDfa field cannot change after a DFA is constructed.
What it means
DFA.setPrecedenceDfa(boolean) is deprecated and intentionally performs nothing except a consistency check: the precedence-ness of a DFA is fixed at construction. Passing a value different from the DFA's current isPrecedenceDfa() throws UnsupportedOperationException. The method exists only so old code that toggled this flag fails loudly instead of silently misbehaving.
Source
Thrown at runtime/Java/src/org/antlr/v4/runtime/dfa/DFA.java:153
s0.edges[precedence] = startState;
}
}
/**
* Sets whether this is a precedence DFA.
*
* @param precedenceDfa {@code true} if this is a precedence DFA; otherwise,
* {@code false}
*
* @throws UnsupportedOperationException if {@code precedenceDfa} does not
* match the value of {@link #isPrecedenceDfa} for the current DFA.
*
* @deprecated This method no longer performs any action.
*/
@Deprecated
public final void setPrecedenceDfa(boolean precedenceDfa) {
if (precedenceDfa != isPrecedenceDfa()) {
throw new UnsupportedOperationException("The precedenceDfa field cannot change after a DFA is constructed.");
}
}
/**
* Return a list of all states in this DFA, ordered by state number.
*/
public List<DFAState> getStates() {
List<DFAState> result = new ArrayList<DFAState>(states.keySet());
Collections.sort(result, new Comparator<DFAState>() {
@Override
public int compare(DFAState o1, DFAState o2) {
return o1.stateNumber - o2.stateNumber;
}
});
return result;
}View on GitHub (pinned to 7d5770395b)
Solutions
- Delete the setPrecedenceDfa call; pass precedence at construction: new DFA(atnStart, precedence) (precedence >= 0 marks a precedence DFA)
- If the call was a no-op consistency check in your code, replace it with an assertion on dfa.isPrecedenceDfa()
- Regenerate nothing here; fix runtime-side code only and re-run your parser tests
Example fix
// before (pre-4.6 style) DFA dfa = new DFA(atnStart); dfa.setPrecedenceDfa(true); // throws in 4.6+ // after DFA dfa = new DFA(atnStart, 0); // precedence DFA from construction assert dfa.isPrecedenceDfa();
Defensive patterns
Strategy: type-guard
Validate before calling
// replace the call with a construction-time choice DFA dfa = wantPrecedence ? new DFA(atnStart, 0) : new DFA(atnStart);
Type guard
static boolean precedenceFlagMatches(DFA dfa, boolean want) { return dfa.isPrecedenceDfa() == want; } Prevention
- Delete setPrecedenceDfa calls when upgrading past ANTLR 4.6
- Pass precedence to the DFA constructor instead
- Grep for setPrecedenceDfa during version upgrades
When it happens
Trigger: Calling dfa.setPrecedenceDfa(true) on a DFA constructed as a normal DFA, or setPrecedenceDfa(false) on a precedence DFA (created via new DFA(atnStart, -1)/precedence form or flagged during left-recursive rule simulation). Copy-pasted pre-4.6 code that 'converted' a DFA into a precedence DFA at runtime.
Common situations: Upgrading from ANTLR < 4.6 (where the field was mutable) to 4.6+: old workarounds that called setPrecedenceDfa now throw. Custom parser subclasses that mimic the old ParserATNSimulator init sequence.
Related errors
- Only precedence DFAs may contain a precedence start state.
- This set is readonly
- This ATN simulator does not support clearing the DFA.
- Precedence predicates are not supported in lexers.
- Only precedence DFAs may contain a precedence start state.
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/76d7660fc6d9b541.
Report an issue: GitHub.