antlr/antlr4 · error · UnsupportedOperationException

The current parser does not support an ATN with bypass alter

Error message

The current parser does not support an ATN with bypass alternatives.

What it means

Parser.getATNWithBypassAlts() builds a special ATN where each rule gets a bypass alternative, needed for parse-tree pattern matching (trees that skip parts of a rule). It requires the parser to expose its serialized ATN via getSerializedATN(); if that method returns null (the base Parser default), it throws UnsupportedOperationException. Hand-written Parser subclasses that don't implement getSerializedATN() therefore cannot support pattern matching with bypass alts.

Source

Thrown at runtime/Java/src/org/antlr/v4/runtime/Parser.java:447

	/** Tell our token source and error strategy about a new way to create tokens. */
	@Override
	public void setTokenFactory(TokenFactory<?> factory) {
		_input.getTokenSource().setTokenFactory(factory);
	}

	/**
	 * The ATN with bypass alternatives is expensive to create so we create it
	 * lazily.
	 *
	 * @throws UnsupportedOperationException if the current parser does not
	 * implement the {@link #getSerializedATN()} method.
	 */

	public ATN getATNWithBypassAlts() {
		String serializedAtn = getSerializedATN();
		if (serializedAtn == null) {
			throw new UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives.");
		}

		synchronized (this) {
			if ( bypassAltsAtnCache!=null ) {
				return bypassAltsAtnCache;
			}
			ATNDeserializationOptions deserializationOptions = new ATNDeserializationOptions();
			deserializationOptions.setGenerateRuleBypassTransitions(true);
			bypassAltsAtnCache = new ATNDeserializer(deserializationOptions).deserialize(serializedAtn.toCharArray());
			return bypassAltsAtnCache;
		}
	}

	/**
	 * The preferred method of getting a tree pattern. For example, here's a
	 * sample use:
	 *
	 * <pre>

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Use a normally generated parser: generated classes implement getSerializedATN() with the static _SERIALIZED_ATN data
  2. If you subclass a generated parser, inherit (don't hide) getSerializedATN()
  3. For custom parsers, implement getSerializedATN() to return the serialized ATN data so the bypass ATN can be built

Example fix

// before
class MyParser extends Parser { /* no getSerializedATN() */ }
myParser.getATNWithBypassAlts(); // throws

// after
class MyParser extends Parser {
  @Override public String getSerializedATN() { return _SERIALIZED_ATN; }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (parser.getSerializedATN() != null) {
  ATN bypass = parser.getATNWithBypassAlts();
}

Type guard

boolean supportsBypassAlts(Parser p) { return p.getSerializedATN() != null; }

Prevention

When it happens

Trigger: Calling getATNWithBypassAlts() on a custom Parser subclass that does not override getSerializedATN(); using ParseTreePatternMatcher machinery that internally requests the bypass ATN on such a parser; partially generated parsers where the serialized ATN field was stripped.

Common situations: Advanced tooling built on parse-tree patterns (e.g. custom refactoring or lint rules); parsers hand-instantiated instead of generated; environments where generated code was minimized/obfuscated, dropping the serialized ATN.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/8b67bcd49c37f8ef. Report an issue: GitHub.