首页 > 解决方案 > 导入词法分析器语法(ANTLR 4)

问题描述

我有一个简单的测试语法,它分为两部分。第一部分是词法分析器:

lexer grammar TestLexer;

@lexer::header {
package de.test;
}

BOOL : ([Tt][Rr][Uu][Ee] | [Ff][Aa][Ll][Ss][Ee]) ;

AND : '&' ;
OR : '|' ;
IMPLIES : '=>' ;
IFF : '<=>' ;

NOT : '!' ;

WS : [ \t\n\r]+ -> skip ; // ignore whitespace

ANY : . ;

第二部分是实际语法:

grammar TestGrammar;

@parser::header {
package de.test;
}

options {
tokenVocab=TestLexer;
}

formula  :
  BOOL
  | NOT formula
  | formula (AND | OR) formula
  | formula IMPLIES formula
  | formula IFF formula
;

可以看出,语法包括使用选项tokenVocab的词法分析器。我在具有以下 POM 的 maven 存储库中有此语法(在我可以使用的关系中没有高于 ANTLR 4.7.1 的版本。而且我认为我的问题与 ANTLR 4 的特定版本无关。):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.test</groupId>
  <artifactId>antlrTest</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>antlrTest</name>
  <url>http://maven.apache.org</url>
  <build>
    <plugins>
      <plugin>
        <groupId>org.antlr</groupId>
        <artifactId>antlr4-maven-plugin</artifactId>
        <version>4.7.1</version>
        <configuration>
          <sourceDirectory>${basedir}/grammar</sourceDirectory>
          <outputDirectory>${basedir}/src/main/java/de/test</outputDirectory>
          <visitor>true</visitor>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>antlr4</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.antlr</groupId>
      <artifactId>antlr4-runtime</artifactId>
      <version>4.7.1</version>
    </dependency>
  </dependencies>
  <properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
  </properties>
</project>

当我现在编译语法时(使用mvn clean install),将创建相应的词法分析器(TestGrammarLexer.java)而没有相应的信息。因此,它不能在我的项目中使用。不能选择手动更改包信息,因为我需要不时更新语法。这会强制重建已编译的类,因此包信息将被覆盖。我尝试使用 ANTLR 的import语句包含词法分析器。但是,这会导致其他问题,因为我有一个更复杂的语法,甚至根本不会生成相应的词法分析器类。

当我将词法分析器与语法合并到一个g4文件中时,编译结果如所愿:

grammar TestGrammar2;

@lexer::header {
package de.test;
}

@parser::header {
package de.test;
}

BOOL : ([Tt][Rr][Uu][Ee] | [Ff][Aa][Ll][Ss][Ee]) ;

AND : '&' ;
OR : '|' ;
IMPLIES : '=>' ;
IFF : '<=>' ;

NOT : '!' ;

WS : [ \t\n\r]+ -> skip ; // ignore whitespace

ANY : . ;

formula  :
  BOOL
  | NOT formula
  | formula (AND | OR) formula
  | formula IMPLIES formula
  | formula IFF formula
;

现在,我被迫将词法分析器与解析器合并到一个文件中。但是,我会很感激分离,因为我想在多种不同的语法中重用词法分析器语法。那么,我做错了什么?非常感谢您的帮助。

标签: javamavenantlr4

解决方案


Maven 中心提供 4.9.2 版本:https ://mvnrepository.com/artifact/org.antlr/antlr4-maven-plugin/4.9.2但是,正如你所说,我认为这不是版本问题.

我建议删除@lexer::headerand@parser::header定义,并将*.g4文件放在./src/main/antlr4/de/test. 然后生成的文件将获得包de.test

在我的 POM 文件中,我使用的是这样的 ANTLR 插件:

<plugin>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4-maven-plugin</artifactId>
    <version>4.9.2</version>
    <configuration>
        <arguments>
            <argument>-visitor</argument>
        </arguments>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>antlr4</goal>
            </goals>
        </execution>
    </executions>
</plugin>

推荐阅读