ANTLR4(一) IDEA Win10 Java 安装+环境配置+官方示例

355 阅读3分钟

安装IDEA 插件

1、安装 antlr v4 插件

image.png

2、编写 Expr.g4 文件

image.png

3、测试

输入表达式进行测试

image.png

预期效果


static short[] data={1,2,3}
翻译成
static string data="\u001\u002\u003"
即 将一个short数组翻译成16进制字符串。

1、编写批处理文件

编写.g4格式的语法文件

  • ArrayInit必须和文件名ArrayInit.g4匹配。

  • 语法分析器的规则必须以小写字幕开头,词法分析器的规则必须大写开头。

//语法文件以grammar开头
//ArrayInit必须和文件名ArrayInit.g4匹配
grammar ArrayInit;

//init规则:匹配一对花括号中的、逗号分隔的value
init : '{' value (',' value)* '}';

//value可以是嵌套的花括号结构,也可以是一个简单整数,即INT词法符号
value : init
     | INT
     ;

//语法分析器的规则必须以小写字幕开头,词法分析器的规则必须大写开头
//词法符号INT,由一个或者多个数字组成
INT : [0-9]+;

//定义词法规则空白符号,丢弃
WS : [\t\r\n]+ -> skip;

测试预览

image.png

2、生成代码

右键-> 选择 Generate ANTLR ...

image.png

生成的代码如下:

image.png

简单介绍一下生成的文件:

  1. ArrayInitParser.java:包含一个语法分析器类的定义,用来识别语法ArrayInit。
  2. ArrayInitLexer.java:包含一个词法分析器类的定义,识别语法中的词法规则和文法规则。
  3. ArrayInit.tokens:ANTLR会对每个词法符号指定数字类型,这个关系保存在该文件中。有时候ANTLR会对一个大的语法切割,生成许多小语法,这个文件可以同步所有小语法的词法符号。
  4. ArrayInitListener.java ArrayInitBaseListener.java:我们输入的文本会被ANTLR语法分析器转换成一棵语法分析树。遍历这些语法分析树时,遍历器可以触发一系列回调事件。前者是回调事件的定义,后者是实现。后者的好处在于我们可以只重写我们感兴趣的回调。

3、拷贝生成的代码到一个安装包

image.png

4、编写处理代码

添加依赖包

<dependency>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4</artifactId>
    <version>4.13.1</version>
</dependency>

因此我们需要重写之前说过的ArrayInitBaseListener类,也就是回调函数实现类:

@Override public void enterInit(ArrayInitParser.InitContext ctx) {
   // 将{翻译成"
   System.out.print('"');
}

@Override public void exitInit(ArrayInitParser.InitContext ctx) {
   // 将 } 翻译成"
   System.out.print('"');
}

@Override public void enterValue(ArrayInitParser.ValueContext ctx) {
   //将value翻译成位16进制形式
   //假定不存在嵌套结构
   int value=Integer.valueOf(ctx.INT().getText());
   System.out.printf("\\u%04x",value);
}

5、编写主程序

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

import java.io.IOException;

public class ArrayInitMain {

    public static void main(String[] args) throws IOException {
        //新建CharStream,从标准输入读取数据
        ANTLRInputStream input = new ANTLRInputStream("{1,2,3}");

        //新建词法分析器,处理输入的CharStream
        ArrayInitLexer lexer = new ArrayInitLexer(input);

        //新建词法符号缓冲区,存储词法分析器生成的词法符号
        CommonTokenStream tokens = new CommonTokenStream(lexer);

        //新建语法分析器,处理词法符号缓冲区内容
        ArrayInitParser parse = new ArrayInitParser(tokens);

        //针对init规则,开始语法分析
        ParseTree tree = parse.init();

        //新建一个能够触发回调函数的语法分析树遍历器
        ParseTreeWalker walker=new ParseTreeWalker();

        //遍历语法分析过程中生成的语法分析树,触发回调
        walker.walk(new ArrayInitBaseListener(),tree);
        System.out.println();
    }
}

输出结果如下:

image.png