Antlr4,规则引擎的基础

原创
2021/09/30 12:03
阅读数 2.5K

概述

  • ANTLR v4是一款功能强大的语法分析器生成器,可以用来读取、处理、执行和转换结构化文本或二进制文件,被广泛应用于学术界和工业界构建各种语言、工具和框架
  • 它生成的语法分析器可以自动构建语法分析树——表示文法如何匹配输入的数据结构。ANTLR还可以自动生成树遍历器,你可以用它来访问那些树的节点,以执行特定的代码
  • 它的语法分析器使用一种新的称为 Adaptive LL() 或 ALL() 的语法分析技术,可以在生成的语法分析器执行前在运行时动态地,而不是静态地执行文法分析

概念

前端:定义语法规则,antlr通过g4文件来定义 lexer:词法解规则,就是将一个句子多个字符进行组装分成多个单词的规则 parser:语法解析,对分词后的整个句子进行解析,可以对每个分词单元做出自定义的处理,从而来实现自己的语法解析功能。

输出内容 词法分析器 (Lexer) 语法分析器 (Parser) 树分析器 (Tree Parser)

g4文件

是antlr生成词法解析规则和语法解析规则的基础 该文件是使用者自定义的,文件名后缀需要是.g4

g4文件的结构大致为:

  • grammar
  • comment(同java //)
  • options
  • import
  • tokens
  • @actionName
  • rule 需要关注的主要是grammar与rule

grammar

  • grammar 是规则文件的头,需要与文件名保持一致
  • 当 antlr 生成词法语法解析的规则代码时,类名就是根据 grammar 的名字来的

rule

  • rule 是 antlr 生成词法语法解析的基础
  • 包括了 lexer 与 parser ,每条规则都是 key:value 的形式,以分号结尾
  • lexer 首字母大写,lexer 小写

生成内容

DslLexer:词法解析类 DslParser:语法解析类

  • 在类中有各种Context,每个parser都赌对应了一个xxxContext的内部类
  • 在Context中记录了与其他Context的包含关系
  • 还提供了获取parser中的lexer的方法,以及进出这个rule的回调函数

DslListener:语法解析监听器

  • antlr有listener和visitor两种遍历方式,前面配置的时候选择的是listener,因此只生成了listener
  • 在Listener中提供了进入和退出每一种规则的回调方法
  • 可以通过实现Listtener类,按需覆写回调方法,来实现业务

项目集成

配置

在 pom.xml 中加入

<dependency>
     <groupId>org.antlr</groupId>
     <artifactId>antlr4-runtime</artifactId>
     <version>4.7.1</version>
</dependency>

sql解析实例

public static void main(String[] args) throws IOException {
	String sql= "Select 'abc' as a, `hahah` as c  From a aS table;";
	ANTLRInputStream input = new ANTLRInputStream(sql);  //将输入转成antlr的input流
	DslLexer lexer = new DslLexer(input);    //词法分析
	CommonTokenStream tokens = new CommonTokenStream(lexer);  //转成token流
	DslParser parser = new DslParser(tokens);  // 语法分析
	DslParser.StaContext tree = parser.sta();  //获取某一个规则树,这里获取的是最外层的规则,也可以通过sql()获取sql规则树......
    
	System.out.println(tree.toStringTree(parser));  //打印规则数
}

实现方式

遍历方式

ANTLR 提供两种访问语法生成树的方式

监听器方式

特点:

  • 自动产生回调,不需要显式访问

ANTLR提供ParseTreeWalker类

  • 可自行实现ParseTreeListener的接口,在其中填充自己的逻辑
  • ANTLR为每个语法文件生成一个ParseTreeListener的子类
    • 在该类中,语法的每条规则都有对应的enter方法和exit方法

事件顺序 6ec6b3e8764e0aa384a1476758e6a549.png

d678eed63d0d9044bb5242e4d91e5969.png

访问者方式

特点

  • 显式回调

ANTLR

  • 语法中的每条规则对应接口中的一个visit方法
  • 为访问者模式提供的支持代码会在根节点处调用visitStat方法
    • visitStat方法的实现将会调用visit方法,并将所用的子节点作为参数传递给它,从而继续遍历的过程

事件顺序 7a9be58bedab92c55fcd40f25caf5661.png

附录

资料

官方资料 官方文法实例

在线教程

基本示例 基本示例2 四则运算实例+代码解释 一些具体举例

对antlr讲的更细致一些

在Idea中的基本使用

从文法解析到计算

展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
打赏
1 评论
0 收藏
0
分享
返回顶部
顶部