Antlr学习笔记:Maven配置Antlr4插件案例Demo

coverImg

源码

当前文档配套相关源码地址:

  • gitee:https://gitee.com/changluJava/demo-exer/tree/master/java-sqlparser/demo-Antlr/demo-Antlr4-demo
  • github:https://github.com/changluya/Java-Demos/tree/master/java-sqlparser/demo-Antlr/demo-Antlr4-demo

插件描述

在开源组件尤其是计算引擎中,经常使用使用Antlr4定义SQL语法。若不做好相应的代码配置,则会导致用户需要在本地安装Antlr Tools或者在IDEA中配置Antlr插件,这对用户来说是十分不友好的。

因此,Antlr4还有对应的maven插件(antlr4-maven-plugin),便可以实现代码的友好编译

pom引入插件

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <antlr.version>4.8</antlr.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-maven-plugin</artifactId>
            <version>${antlr.version}</version>
            <executions>
                <execution>
                    <id>antlr</id>
                    <goals>
                        <goal>antlr4</goal>
                    </goals>
                    <phase>generate-sources</phase>
                </execution>
            </executions>
            <configuration>
                <sourceDirectory>${basedir}/src/main/resources</sourceDirectory>
                <outputDirectory>${basedir}/src/main/java/com/changlu/hello</outputDirectory>
                <listener>true</listener>
                <visitor>true</visitor>
                <treatWarningsAsErrors>true</treatWarningsAsErrors>
            </configuration>
        </plugin>
    </plugins>
</build>

案例:实现hello 标识符 案例

1、引入Antlr4的pom运行依赖

下面步骤3里编译生成的Java代码,将自动引用org.antlr.v4.runtime包,需要pom.xml文件中添加org.antlr:antlr4-runtime,才能成功编译所有模块。

<dependencies>
    <dependency>
        <groupId>org.antlr</groupId>
        <artifactId>antlr4-runtime</artifactId>
        <version>${antlr.version}</version>
    </dependency>
</dependencies>

2、定义语义语法,配置.g4文件实现java代码

以一个最简单的例子:匹配关键字hello和标志符,来了解一下Antlr的应用。首先定义语法和词法,创建一个.g4文件,用于定义词法分析器(lexer)和语法解析器(Parser),g4文件内容如下:

// 通过@header指定package信息的antlr4语法示例
grammar Hello; // 1、定义文法的名字

//2、java package
@header {
    package com.changlu.hello;
}

s  : 'hello' ID ;            // 3、匹配关键字hello和标志符
ID : [a-z]+ ;                // 标志符由小写字母组成
WS : [ \t\r\n]+ -> skip ;    // 4、跳过空格、制表符、回车符和换行符

其中, 1、定义了 grammar 的名字,名字需要与文件名对应 2、定义生成的Java类的package 3、s定义的语法,会使用到下方定义的正则表达式词法 4、定义了空白字符,后面的 skip 是一个特殊的标记,标记空白字符会被忽略。

3、编写完之后,执行命令实现编译

mvn antlr4:antlr4

编译成功:

此时就会将编译的代码复制到.g4文件指定的包中:

4、编写单测测试使用

package com.changlu;

import com.changlu.hello.HelloLexer;
import com.changlu.hello.HelloParser;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

public class HelloTest {
    public static void main(String[] args) throws Exception {
        testStr("hello world");
        // 错误语法
//        testStr("helloworld");
//        testStr("hello 123");
    }

    public static void testStr(String str) {
        HelloLexer lexer = new HelloLexer(CharStreams.fromString(str));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        HelloParser parser = new HelloParser(tokens);
        ParseTree tree = parser.s();
        System.out.println(tree.toStringTree(parser));
    }

}

使用错误语法报错如下:


参考文章

[1]. mac上的Antlr4环境搭建:https://blog.csdn.net/u014454538/article/details/125879636

[2]. Antlr4系列(一):语法分析器学习:https://zhuanlan.zhihu.com/p/483679676

评论区请在客户端页面查看