当前位置: 首页 > 知识库问答 >
问题:

如何使用Gradle 2.10将ANTLR lexer语法导入另一个语法?

武彭薄
2023-03-14

我一直在通过特伦斯·帕尔(Terence Parr)的《权威的ANTLR 4参考》(The Definitive ANTLR 4 Reference)学习ANTLR 4,到目前为止,我一直在使用Gradle 2.10及其内置的ANTLR插件来关注它。然而,我在获取一些代码时遇到了一些困难,我从第4章38-41页改编了这些代码,以便与我的Gradle构建脚本正常工作。(我之所以使用Gradle,而不是直接使用ANTLR,是因为我想最终将ANTLR集成到一个Java web应用程序中,这是我为我的论文所做的,我强烈希望使用一个构建工具来实现这一点,这样我就可以自动化ANTLR到Java代码的生成过程,并轻松地管理我的依赖关系。)

我创建了两个ANTLR 4语法(我在这个问题的末尾粘贴了它们):src/main/ANTLR/org/jbduncan/Expr。g4(标准语法)和src/main/antlr/org/jbduncan/CommonLexerRules。g4(词法语法),其中Expr。g4依赖于通用规则。g4通过导入CommonLexerRules语句。但是当我尝试在命令行中用我的构建运行gradlew generateGrammarSource时。gradle(也贴在这个问题的末尾以及我的gradle.properties),我得到了以下错误:

12:45:21: Executing external task 'generateGrammarSource'...
:generateGrammarSource
error(110): org\jbduncan\Expr.g4:3:7: can't find or load grammar CommonLexerRules
warning(125): org\jbduncan\Expr.g4:12:11: implicit definition of token NEWLINE in parser
warning(125): org\jbduncan\Expr.g4:13:6: implicit definition of token ID in parser
warning(125): org\jbduncan\Expr.g4:19:6: implicit definition of token INT in parser
:generateGrammarSource FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateGrammarSource'.
> There was 1 error during grammar generation

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 3.166 secs
There was 1 error during grammar generation
12:45:24: External task execution finished 'generateGrammarSource'.

看一下这个错误消息,在我看来,Gradle的ANTLR插件能够找到Expr. g4,但不知何故却找不到通用规则. g4。

我尝试使用几个外部Gradle插件来解决这个错误(https://github.com/melix/antlr4-gradle-plugin和https://github.com/Abnaxos/gradle-antlr4-plugin)而不是内置的,但当我尝试每一个,他们介绍了自己的问题,我无法解决。

使用直接从ANTLR网站下载的ANTLR 4.5.2 jar确实让我可以毫无问题地编译我的两个语法,但正如我之前讨论的那样,这对我来说是一个非常不可取的选择,因为我必须手动编译我的语法,而我相信Gradle可以为我自动完成。

我的问题是:我如何解决上面的错误,并让Gradle将我的lexer语法导入我的其他语法?

建筑格拉德尔

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'antlr'

sourceCompatibility = 1.8
targetCompatibility = 1.8

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

group = 'org.jbduncan'
version = '1.0-SNAPSHOT'
mainClassName = 'org.jbduncan.Application'

repositories {
    jcenter()
}

dependencies {
    antlr "org.antlr:antlr4:$antlrVersion"
    compile "com.google.guava:guava:$guavaVersion"
    testCompile "com.google.guava:guava-testlib:$guavaVersion"
    testCompile "com.google.truth:truth:$truthVersion"
    testCompile "junit:junit:$junitVersion"
}

// Send all generated source code to a directory other than build/, to workaround an issue in
// IntelliJ IDEA where it fails to recognise source files in build/.
def generatedJavaSourcesDir = 'src/generated/java'

generateGrammarSource {
    arguments += ['-visitor']
    outputDirectory = file(generatedJavaSourcesDir)
}

sourceSets {
    main {
        java {
            srcDir generatedJavaSourcesDir
        }
    }
}

clean {
    delete generatedJavaSourcesDir
}

task wrapper(type: Wrapper) {
    distributionUrl = "http://services.gradle.org/distributions/gradle-$gradleVersion-bin.zip"
}

gradle.properties

gradleVersion=2.10

# Dependency versions
antlrVersion=4.5
guavaVersion=19.0
junitVersion=4.12
truthVersion=0.28

src/main/antlr/org/jbduncan/Expr。g4

grammar Expr;

import CommonLexerRules; // includes all rules from CommonLexerRules.g4

@header {
    package org.jbduncan;
}

/** The start rule; begin parsing here. */
prog: stat+;

stat: expr NEWLINE # printExpr
    | ID '=' expr NEWLINE # assign
    | NEWLINE # blank
    ;

expr: expr op=('*'|'/') expr # MulDiv
    | expr op=('+'|'-') expr # AddSub
    | INT # int
    | ID # id
    | '(' expr ')' # parens
    ;

MUL: '*'; // assigns token name to '*' used above in grammar
DIV: '/';
ADD: '+';
SUB: '-';

src/main/antlr/org/jbduncan/CommonLexerRules。g4

lexer grammar CommonLexerRules; // note "lexer grammar"

ID: [a-zA-Z]+ ; // match identifiers
INT: [0-9]+ ; // match integers
NEWLINE: '\r'? '\n' ; // return newlines to parser (is end-statement signal)
WS: [ \t] -> skip ; // toss out whitespace

src/main/java/org/jbduncan/Application。JAVA

package org.jbduncan;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

import html" target="_blank">java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public final class Application {
  public static void main(String[] args) throws IOException {
    String inputFile = (args.length > 0) ? args[0] : null;

    InputStream inputStream = (inputFile == null) ? System.in : new FileInputStream(inputFile);
    ANTLRInputStream input = new ANTLRInputStream(inputStream);
    ExprLexer lexer = new ExprLexer(input);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    ExprParser parser = new ExprParser(tokens);
    ParseTree tree = parser.prog(); // parse; start at prog

    System.out.println(tree.toStringTree(parser)); // print tree as text
  }
}

共有1个答案

高和通
2023-03-14

在Gradle论坛上发布了我的问题后,我终于找到了答案:

generateGrammarSource {
  arguments << "-lib" << "src/main/antlr/org/jbduncan" 
}

其中,“src/main/antlr/org/jbduncan”是一个包含antlr的路径。g4库。

 类似资料:
  • 问题内容: 我已经将一个现有的Java应用程序导入到我的工作区中。我看到,在应用程序中的不同包中存在具有相同名称的类。 例如,存在一个名为“ Status.java”的类,其中包含 当我尝试在一个类中同时使用它们时,例如如下所示 它开始在Eclipse中指出一个错误 该 进口com.bayer.frontlayer.dao.Status 碰撞与其他import语句 有没有解决这个问题而无需更改类的

  • 我创建了一个版本.,就像这样: 现在我想像这样导入和使用该文件: 我该怎么做? 注意:我已经看到这篇文章,但它不完全是我搜索…

  • 我正在尝试用Maven构建一个ANTLR项目,项目结构如下所示 其中G1导入G2,类似于: 然而,当我使用Maven构建时,我得到以下错误: 如果我将和直接放在目录下,则不会有问题。在我看来,当把语法文件放在一个包中时,它需要在import语句中使用特殊的语法。 我注意到了一个问题,Antlr4 maven插件无法在不同的目录中找到语法文件,但在这里,语法在一个目录中。

  • 注意:我是gatling新手,对Scala几乎一无所知。 我正在开始将我的负载测试从Jeter转换为gatling的过程。我被困在如何组织代码库上。我能找到的所有示例都是单文件示例。 如何将代码从一个模拟类导入另一个模拟类? 我现在有了这个课程和测试场景: 当我尝试将类导入另一个模拟时,如下所示: 尝试导入时,我得到以下错误。 08:33:57.952[ERROR]i. g. c. ZincCom

  • 问题内容: 我有一个复杂的gradle脚本,该脚本封装了围绕将多个netbeans项目构建和部署到许多环境的功能。 该脚本可以很好地运行,但是从本质上来说,它是通过六个包含项目和环境信息的地图进行配置的。 我想将任务抽象到另一个文件中,以便可以在一个简单的构建文件中简单地定义地图,然后从另一个文件中导入任务。这样,我可以对多个项目使用相同的核心任务,并使用一组简单的地图来配置这些项目。 谁能告诉我

  • 我遇到了一个javascript库,它使用以下语法来导入库: 上面的方法和下面的方法有什么区别?