java - 导入词法分析器语法(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
;
现在,我被迫将词法分析器与解析器合并到一个文件中。但是,我会很感激分离,因为我想在多种不同的语法中重用词法分析器语法。那么,我做错了什么?非常感谢您的帮助。
解决方案
Maven 中心提供 4.9.2 版本:https ://mvnrepository.com/artifact/org.antlr/antlr4-maven-plugin/4.9.2但是,正如你所说,我认为这不是版本问题.
我建议删除@lexer::header
and@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>
推荐阅读
- javascript - 开始使用 React,无法渲染页面传递道具
- laravel-6 - Laravel 6.12 种子工厂看不到状态
- mysql - Google Cloud sql 5.6+ 是否已弃用存储过程中的“CREATE TEMPORARY TABLE”?
- spring - 我可以擦除 GSON 时间标记吗?例如)上午/下午
- puppeteer - 如何在 DIV 中获取图像 URL
- javascript - 在使用 Javascript 搜索对象时需要帮助
- reactjs - 为什么我的 setState 不能正常工作?我想添加一个 div 元素 onClick
- mysql - Laravel 连接两个表,包括 null
- algorithm - 具有障碍物和角度限制的环面网格表面上的线性路径
- hyperledger-fabric - 超级账本结构通道配置中的数值意味着什么