Reputation: 50989
I created a file MyLexer.g4
inside myproject/src/main/antlr/com/mypackage
like:
lexer grammar MyLexer;
DIGIT : '0' .. '9' ;
...
WS : [ \t\r\n]+ -> skip ;
and then trying to write parser in MyParser.g4
in the same directory:
grammar MyParser;
options
{ tokenVocab = MyLexer; }
SHORT_YEAR: DIGIT DIGIT;
unfortunately, when I run gradle task of generateGrammarSource
, the following error occurs:
error(160): com\mypackage\MyParser.g4:4:18: cannot find tokens file MYPROJECT\build\generated-src\antlr\main\MyLexer.tokens
I.e. file is sought in incorrect place.
Actual file is created inside MYPROJECT\build\generated-src\antlr\main\com\mypackage\MyLexer.tokens
Upvotes: 16
Views: 4054
Reputation: 33
The issue you're experiencing was addressed in ANTLR version 4.7.1. Starting from this version, there's an additional parameter -Xexact-output-dir
that allows you to place the lexer and parser files in the exact directory you specify, such as src/main/antlr/com/mypackage
.
You can modify your build.gradle
file like this:
gradleCopygenerateGrammarSource {
outputDirectory = layout.buildDirectory.dir('generated-src/antlr/main/com/mypackage').get().asFile
arguments = [
'-visitor',
'-package', 'com.mypackage',
'-Xexact-output-dir'
]
}
By adding the -Xexact-output-dir
argument, ANTLR will generate the .tokens
file in the same directory as your grammar files, resolving the "cannot find tokens file" error.
Note: The
outputDirectory
setting explicitly defines where the generated files will be placed. This is particularly useful when you want to have more control over the location of your generated sources. In this case, it places the files in a subdirectory of your build directory, which is a common practice to keep generated sources separate from your main source code.
Upvotes: 1
Reputation: 1
As what suggested above, grammar file with package definition should be put under src/main/antlr folder. Once you compile it, it will generate files in the output folder. Then you can do the file move as what's desired based on the package path. Here is an relevant link how to move files based on your package
Generating ANTLR4 grammar files with package declaration in gradle
In the doLast method, it calls moveAntlrGeneratedFilesToTheirPackages to move the files to right folder to align with the package path.
Upvotes: 0
Reputation: 3015
As Steven Spungin said, you need to put your ANTLR source files in the directory src/main/antlr/
and not in a subdirectory of that directory.
You do not need to add the @header
to your ANTLR source files. Use the following instead.
In your build.gradle
you should have (modified for your version of ANTLR):
apply plugin: 'antlr'
dependencies {
antlr "org.antlr:antlr4:4.7.1"
}
generateGrammarSource {
arguments += ['-package', 'com.mypackage']
outputDirectory = new File(buildDir.toString() + "/generated-src/antlr/main/com/mypackage/")
}
Upvotes: 13
Reputation: 29071
When generating your parser in a package by using:
@header {package org.acme.my.package;}
and declaring tokenVocab in your parser
options {tokenVocab = MyLanguage;}
The MyLanguageLexer.g4 and MyLanguageParser.g4 files must NOT BE in a package directory. due to a bug of sorts.
So this means /src/main/antlr/MyLanguageParser.g4
and not /src/main/antlr/com/acme/my/package/MyLanguageParser.g4
.
The java files end up in the wrong directory in build/generated-src/antlr, but somehow make it to the correct directory in build/classes/java/main. And the .tokens file ends up where antlr expects it.
Keep in mind this will confuse your IDE; I had to add the compiled classes back to my compileClasspath to avoid visual class-not-found issues.
dependencies {
testCompile fileTree('build/classes/java/main')
}
Upvotes: 5