antlr/antlr4 · error · RuntimeException

Unexpected data entry

Error message

Unexpected data entry

What it means

InterpreterDataReader.parseFile reads the .interp file emitted by the ANTLR tool (via -atn/interp output) as a sequence of labeled sections. The very first line must be exactly 'token literal names:'. Anything else (BOM, wrong file, different section order, empty file) throws RuntimeException('Unexpected data entry').

Source

Thrown at runtime/Java/src/org/antlr/v4/runtime/misc/InterpreterDataReader.java:66

	 * ...
	 *
	 * atn:
	 * <a single line with comma separated int values> enclosed in a pair of squared brackets.
	 *
	 * Data for a parser does not contain channel and mode names.
	 */
	public static InterpreterData parseFile(String fileName) {
		InterpreterData result = new InterpreterData();
		result.ruleNames = new ArrayList<String>();

		try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
		    String line;
		  	List<String> literalNames = new ArrayList<String>();
		  	List<String> symbolicNames = new ArrayList<String>();

			line = br.readLine();
			if ( !line.equals("token literal names:") )
				throw new RuntimeException("Unexpected data entry");
		    while ((line = br.readLine()) != null) {
		       if ( line.isEmpty() )
					break;
				literalNames.add(line.equals("null") ? "" : line);
		    }

			line = br.readLine();
			if ( !line.equals("token symbolic names:") )
				throw new RuntimeException("Unexpected data entry");
		    while ((line = br.readLine()) != null) {
		       if ( line.isEmpty() )
					break;
				symbolicNames.add(line.equals("null") ? "" : line);
		    }

		  	result.vocabulary = new VocabularyImpl(literalNames.toArray(new String[0]), symbolicNames.toArray(new String[0]));

			line = br.readLine();

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Verify the file's first line is byte-exact 'token literal names:' with no BOM/whitespace (hexdump -C file | head)
  2. Regenerate the .interp with the same ANTLR tool version as the runtime (antlr4 -Dlanguage=Java ... emits .interp alongside generated sources)
  3. Point the reader at the correct file; .interp lives next to the generated Lexer/Parser .java files by default
  4. If the file came through Windows tooling, strip CR characters and re-save as UTF-8 without BOM

Example fix

// before
InterpreterData data = InterpreterDataReader.parseFile("MyLexer.tokens"); // wrong file -> throws
// after
InterpreterData data = InterpreterDataReader.parseFile("MyLexer.interp");
Defensive patterns

Strategy: validation

Validate before calling

List<String> head = Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8);
if (head.isEmpty() || !"token literal names:".equals(head.get(0))) {
    throw new IllegalArgumentException("not a valid .interp file: " + path);
}

Try / catch

catch (RuntimeException e) { if ("Unexpected data entry".equals(e.getMessage())) { /* wrong or corrupt .interp: regenerate */ } else throw e; }

Prevention

When it happens

Trigger: Passing a path that is not a .interp file (e.g. a .tokens, .java, or .g4 file), a file with a UTF-8 BOM or CRLF-prefixed first line, a file truncated to empty, or an .interp written by a tool version that emits a different first section.

Common situations: Wiring a ParserInterpreter/LexerInterpreter: new Grammar(fileName, tokens, rules, atn) built from InterpreterDataReader data but the wrong file path passed. Generating with an old/new ANTLR that changes the .interp layout. Files edited by hand or transferred with encoding conversion.

Related errors


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