我在
MyLexer.g4
中创建了一个文件 myproject/src/main/antlr/com/mypackage
,例如:
lexer grammar MyLexer;
DIGIT : '0' .. '9' ;
...
WS : [ \t\r\n]+ -> skip ;
然后尝试在同一目录中的
MyParser.g4
中编写解析器:
grammar MyParser;
options
{ tokenVocab = MyLexer; }
SHORT_YEAR: DIGIT DIGIT;
不幸的是,当我运行
generateGrammarSource
的gradle任务时,出现以下错误:
error(160): com\mypackage\MyParser.g4:4:18: cannot find tokens file MYPROJECT\build\generated-src\antlr\main\MyLexer.tokens
即在错误的位置查找文件。
实际文件是在里面创建的
MYPROJECT\build\generated-src\antlr\main\com\mypackage\MyLexer.tokens
正如 Steven Spungin 所说,您需要将 ANTLR 源文件放在目录
src/main/antlr/
中,而不是该目录的子目录中。
您无需将
@header
添加到 ANTLR 源文件中。请改用以下内容。
在你的
build.gradle
中你应该有(根据你的 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/")
}
使用以下方式在包中生成解析器时:
@header {package org.acme.my.package;}
并在解析器中声明 tokenVocab
options {tokenVocab = MyLanguage;}
MyLanguageLexer.g4 和 MyLanguageParser.g4 文件不得位于包目录中。由于某种错误。
所以这意味着
/src/main/antlr/MyLanguageParser.g4
而不是 /src/main/antlr/com/acme/my/package/MyLanguageParser.g4
。
java 文件最终位于 build/ generated-src/antlr 中的错误目录中,但以某种方式使其到达 build/classes/java/main 中的正确目录。 .tokens 文件最终出现在 antlr 期望的位置。
请记住,这会让您的 IDE 感到困惑;我必须将已编译的类添加回我的compileClasspath 以避免视觉类未找到问题。
dependencies {
testCompile fileTree('build/classes/java/main')
}
正如上面所建议的,带有包定义的语法文件应该放在 src/main/antlr 文件夹下。编译后,它将在输出文件夹中生成文件。然后您可以根据包路径根据需要进行文件移动。这是如何根据您的包移动文件的相关链接
在 doLast 方法中,它调用 moveAntlrGenerateFilesToTheirPackages 将文件移动到正确的文件夹以与包路径对齐。
您遇到的问题已在 ANTLR 版本4.7.1中得到解决。从这个版本开始,有一个附加参数
-Xexact-output-dir
允许您将词法分析器和解析器文件放置在您指定的确切目录中,例如 src/main/antlr/com/mypackage
。
您可以像这样修改您的 build.gradle
文件:
gradleCopygenerateGrammarSource {
arguments = [
'-visitor',
'-package', 'com.mypackage',
'-Xexact-output-dir'
]
}
通过添加
-Xexact-output-dir
参数,ANTLR 将在与语法文件相同的目录中生成 .tokens
文件,解决“找不到标记文件”错误。