antlr/antlr4 · error · IllegalArgumentException
expected {} to be prefixed with {}
Error message
expected {} to be prefixed with {} What it means
After counts balance, split(pattern) pairs each start with its stop in order and requires starts.get(i) < stops.get(i). A start delimiter appearing at or after its paired stop (e.g. '> <' with swapped custom delimiters) means the delimiters enclose nothing or are inverted, so 'tag delimiters out of order' IllegalArgumentException is thrown.
Source
Thrown at antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/MojoUtils.java:67
}
/**
* Given the source directory File object and the full PATH to a grammar, produce the
* path to the named grammar file in relative terms to the {@code sourceDirectory}.
* This will then allow ANTLR to produce output relative to the base of the output
* directory and reflect the input organization of the grammar files.
*
* @param sourceDirectory The source directory {@link File} object
* @param grammarFileName The full path to the input grammar file
*
* @return The path to the grammar file relative to the source directory
*/
public static String findSourceSubdir(File sourceDirectory, File grammarFile) {
String srcPath = sourceDirectory.getPath() + File.separator;
String path = grammarFile.getPath();
if (!path.startsWith(srcPath)) {
throw new IllegalArgumentException("expected " + path +
" to be prefixed with " + sourceDirectory);
}
File unprefixedGrammarFileName = new File(path.substring(srcPath.length()));
if (unprefixedGrammarFileName.getParent() == null) {
return "";
}
return unprefixedGrammarFileName.getParent() + File.separator;
}
}
View on GitHub (pinned to 7d5770395b)
Solutions
- Use distinct start and stop delimiters with start occurring before stop in each tag.
- Avoid identical start/stop delimiter strings.
- Re-inspect patterns after changing delimiters via setDelimiters.
Example fix
// before
matcher.setDelimiters("%", "%", "\\"); // same delimiter -> ordering breaks
m.compile("%id%", R.expr);
// after
matcher.setDelimiters("<<", ">>", "\\");
m.compile("<<id>>", R.expr); Defensive patterns
Strategy: try-catch
Validate before calling
// with custom delimiters, verify pairing order before compiling
List<Integer> s = indexOfAll(pattern, startDelim), t = indexOfAll(pattern, stopDelim);
boolean ordered = s.size() == t.size() && IntStream.range(0, s.size()).allMatch(i -> s.get(i) < t.get(i));
if (!ordered) throw new IllegalArgumentException("tag delimiters out of order: " + pattern); Try / catch
try {
pattern = matcher.compile(patternText, ruleIndex);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("tag delimiters out of order")) {
reportDelimiterMisconfiguration();
}
throw e;
} Prevention
- Use distinct start and stop delimiters that appear in order within each tag.
- Never configure identical start and stop delimiters.
- Re-validate all patterns whenever setDelimiters changes.
When it happens
Trigger: Custom delimiters where start and stop are swapped or identical (setDelimiters("%", "%")); patterns where an empty tag '<>' degenerates so the computed start offset is >= stop offset after ordering.
Common situations: Choosing symmetric custom delimiters; converting existing patterns when delimiters change and the ordering assumptions silently break.
Related errors
- Cannot handle relative paths containing '..'
- Could not create checksum {}
- index cannot be negative
- missing interface implementation
- Fatal error occured while evaluating the names of the gramma
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/35e36d155c39bb7d.
Report an issue: GitHub.