gradle/gradle · warning
unable to locate grammar exporting specified import vocab [{
Error message
unable to locate grammar exporting specified import vocab [{}] What it means
For ANTLR 2 grammars, Gradle builds a GenerationPlan per grammar and cross-references each grammar's importVocab against the exportVocab declared by other grammar files in the same source set (metadataXRef.getGrammarFileByExportVocab). If no grammar exports the named vocabulary, the lookup returns null: Gradle warns and the importing grammar gets no importVocabTokenTypesDirectory, which usually surfaces as ANTLR generation errors (e.g. cannot find TokenTypes.txt) or mismatched token types.
Source
Thrown at platforms/jvm/antlr/src/main/java/org/gradle/api/plugins/antlr/internal/antlr2/GenerationPlanBuilder.java:101
.getAssociatedGrammarMetadata().getGrammarFile();
if (superGrammarGrammarFileMetadata != null) {
final GenerationPlan superGrammarGenerationPlan = locateOrBuildGenerationPlan(
superGrammarGrammarFileMetadata);
if (superGrammarGenerationPlan.isOutOfDate()) {
generationPlan.markOutOfDate();
} else if (superGrammarGenerationPlan.getSource().lastModified() > generatedParserFile
.lastModified()) {
generationPlan.markOutOfDate();
}
}
}
// see if the grammar if out-of-date by way of its importVocab
if (isNotEmpty(grammarMetadata.getImportVocab())) {
final GrammarFileMetadata importVocabGrammarFileMetadata = metadataXRef.getGrammarFileByExportVocab(
grammarMetadata.getImportVocab());
if (importVocabGrammarFileMetadata == null) {
LOGGER.warn("unable to locate grammar exporting specified import vocab ["
+ grammarMetadata.getImportVocab() + "]");
} else if (!importVocabGrammarFileMetadata.getFilePath().equals(grammarFileMetadata.getFilePath())) {
final GenerationPlan importVocabGrammarGenerationPlan = locateOrBuildGenerationPlan(
importVocabGrammarFileMetadata);
generationPlan.setImportVocabTokenTypesDirectory(
importVocabGrammarGenerationPlan.getGenerationDirectory());
if (importVocabGrammarGenerationPlan.isOutOfDate()) {
generationPlan.markOutOfDate();
} else if (importVocabGrammarGenerationPlan.getSource().lastModified() > generatedParserFile
.lastModified()) {
generationPlan.markOutOfDate();
}
}
}
}
generationPlans.put(generationPlan.getId(), generationPlan);
return generationPlan;View on GitHub (pinned to 534f27719b)
Solutions
- Diff every importVocab=X against an exportVocab=X in the same antlr source set - names are case-sensitive
- Make sure the exporting grammar is actually included in the AntlrTask's sources (check includes/excludes and source set layout)
- Run ./gradlew clean generateGrammarSource so all generation plans are rebuilt once the link resolves
- If the vocabulary was renamed intentionally, update both sides: exportVocab in the token grammar and importVocab in every importing parser grammar
Example fix
// before: vocab names do not match -> warning + broken generation
// MyTokensParser.g: options { importVocab=MyToken; } // typo
// MyTokens.g: options { exportVocab=MyTokens; }
// after: names match exactly (case-sensitive)
// MyTokensParser.g: options { importVocab=MyTokens; }
// MyTokens.g: options { exportVocab=MyTokens; } Defensive patterns
Strategy: validation
Validate before calling
// build.gradle: fail fast if an importVocab has no matching exportVocab
tasks.register('validateGrammars') {
doLast {
def grammars = fileTree('src/main/antlr').matching { include '**/*.g' }
def exports = grammars.files.collect { f ->
(f.text =~ /exportVocab\s*=\s*(\w+)/).collect { it[1] }
}.flatten().toSet()
grammars.each { f ->
(f.text =~ /importVocab\s*=\s*(\w+)/).each { m ->
if (!exports.contains(m[1])) {
throw new GradleException("${f.name}: importVocab '${m[1]}' has no matching exportVocab")
}
}
}
}
}
tasks.named('generateGrammarSource') { dependsOn 'validateGrammars' } Prevention
- Keep token-sharing grammar pairs (exporter + importer) in the same antlr source set
- Name the exportVocab after the token grammar file; never rename one side without the other
- Run a CI validation that every importVocab resolves to an exportVocab before generateGrammarSource
When it happens
Trigger: A grammar declares options { importVocab=MyTokens; } but no grammar passed to the same AntlrGenerateParserTask declares options { exportVocab=MyTokens; } - caused by a typo/case mismatch, a renamed vocab, or the exporting grammar living in a different source set or being excluded by the AntlrTask source filter.
Common situations: Typos or case mismatches between importVocab and exportVocab; multi-grammar token-sharing setups where one grammar file was moved, renamed, or excluded; migrating legacy AntlrPlugin configurations between projects or source sets.
Related errors
- Failed to load ANTLR
- Cannot process antlr sources
- The package has been set both in the arguments (i.e. '-packa
- Error accessing Antlr grammar metadata
- Unable to locate Antlr class [%s]
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/a2a294f2bfe14f31.
Report an issue: GitHub.