antlr/antlr4 · error · UnsupportedOperationException
Cannot handle relative paths containing '..'
Error message
Cannot handle relative paths containing '..'
What it means
split(pattern) scans for start/stop delimiter positions; if it finds more start delimiters than stop delimiters, at least one tag was never closed, and chunk extraction cannot proceed, so IllegalArgumentException 'unterminated tag' is thrown. The message echoes the whole pattern to show the offending input.
Source
Thrown at antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java:480
SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet());
// What are the sets of includes (defaulted or otherwise).
Set<String> includes = getIncludesPatterns();
// Now, to the excludes, we need to add the imports directory
// as this is autoscanned for imported grammars and so is auto-excluded from the
// set of grammar fields we should be analyzing.
excludes.add("imports/**");
SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes);
scan.addSourceMapping(mapping);
return scan.getIncludedSources(sourceDirectory, null);
}
private static String getPackageName(String relativeFolderPath) {
if (relativeFolderPath.contains("..")) {
throw new UnsupportedOperationException("Cannot handle relative paths containing '..'");
}
List<String> parts = new ArrayList<String>(Arrays.asList(relativeFolderPath.split("[/\\\\\\.]+")));
while (parts.remove("")) {
// intentionally blank
}
return Utils.join(parts.iterator(), ".");
}
public Set<String> getIncludesPatterns() {
if (includes == null || includes.isEmpty()) {
return Collections.singleton("**/*.g4");
}
return includes;
}
private File getDependenciesStatusFile() {View on GitHub (pinned to 7d5770395b)
Solutions
- Balance every tag: each '<' needs a matching '>'.
- Escape literal delimiters in text chunks with the configured escape sequence (default '\\' passed as escapeLeft).
- If the target language is full of '<', switch delimiters via setDelimiters to something rare like %% %%.
Example fix
// before
ParseTreePattern p = m.compile("a < <ID>", R.expr); // first '<' unterminated
// after
ParseTreePattern p = m.compile("a \\< <ID>", R.expr); // escaped literal '<' Defensive patterns
Strategy: try-catch
Validate before calling
long starts = pattern.chars().filter(c -> c == '<').count();
long stops = pattern.chars().filter(c -> c == '>').count();
if (starts > stops) throw new IllegalArgumentException("unterminated tag: " + pattern); Type guard
boolean hasBalancedTags(String p) {
return p.chars().filter(c -> c=='<').count() == p.chars().filter(c -> c=='>').count();
} Try / catch
try {
pattern = matcher.compile(patternText, ruleIndex);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("unterminated tag")) {
patternText = fixUnescapedDelimiters(patternText);
pattern = matcher.compile(patternText, ruleIndex);
} else throw e;
} Prevention
- Escape literal '<' with the configured escape sequence.
- Balance every tag's delimiters when writing patterns.
- Switch to rare custom delimiters for XML-like target languages.
- Lint patterns for delimiter balance in CI.
When it happens
Trigger: Patterns like "<ID + <INT>" (first '<' unclosed), or custom delimiters where an escape sequence was forgotten; also a stop delimiter accidentally written with different characters than configured.
Common situations: Hand-written patterns in tests; patterns built by string concatenation that drop a closing delimiter; languages whose literal text contains the start delimiter (e.g. HTML/XML-like syntaxes with '<'), requiring the escape sequence.
Related errors
- Could not create checksum {}
- expected {} to be prefixed with {}
- 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/76628e5362947197.
Report an issue: GitHub.