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
- Verify the file's first line is byte-exact 'token literal names:' with no BOM/whitespace (hexdump -C file | head)
- Regenerate the .interp with the same ANTLR tool version as the runtime (antlr4 -Dlanguage=Java ... emits .interp alongside generated sources)
- Point the reader at the correct file; .interp lives next to the generated Lexer/Parser .java files by default
- 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
- Pass the .interp file, not .tokens or generated .java
- Regenerate .interp whenever the tool version changes
- Keep .interp files UTF-8 without BOM, LF or CR-stripped
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
- A lexer interpreter can only be created for a lexer or combi
- A parser interpreter can only be created for a parser or com
- can't create parser to match incoming {parserClass}
- replace op boundaries of ${rop} overlap with previous ${prev
- insert op ${iop} within boundaries of previous ${rop}
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/8aca67d68b03935d.
Report an issue: GitHub.