摘要:本文将首先介绍Antlr4,以及如何通过Antlr4 grammer生成对应的hello的AST

1. Antlr4简单介绍

Antlr4(Another Tool for Language Recognition)是一款基于Java开发的开源的语法分析器生成工具,能够根据语法规则文件生成对应的语法分析器,广泛应用于DSL构建,语言词法语法解析等领域。现在在非常多的流行的框架中都用使用,例如,在构建特定语言的AST方面,CheckStyle工具,就是基于Antlr来解析Java的语法结构的(当前Java Parser是基于JavaCC来解析Java文件的,据说有规划在下个版本改用Antlr来解析),还有就是广泛应用在DSL构建上,著名的Eclipse Xtext就有使用Antlr。

Antlr可以生成不同target的AST(https://www.antlr.org/download.html),包括Java、C++、JS、Python、C#等,可以满足不同语言的开发需求。当前Antlr最新稳定版本为4.9,Antlr4官方github仓库中,已经有数十种语言的grammer(https://github.com/antlr/grammars-v4,不过虽然这么多语言的规则文法定义都在一个仓库中,但是每种语言的grammer的license是不一样的,如果要使用,需要参考每种语言自己的语法结构的license)。

2,ANTLR v4 安装和hello world运行环境避坑

在ANTLR上有个downloads界面,但是点击老是报错,

实际上,downloads的界面不再此处,
antlr资源下载

点击下载 antlr-4.9.3-complete.jar

现在来测试下ANTLR工具是否工作正常:

java -jar antlr-4.5.1-complete.jar  # 启动org.antlr.v4.Tool

如果正常的话会看到以下帮助信息:

ANTLR Parser Generator  Version 4.5.1-o ___              specify output directory where all output is generated-lib ___            specify location of grammars, tokens files...

每次运行ANTLR工具都要输入这么长的命令是否有些痛苦?写个脚本来解放我们的手指吧!

#!/bin/sh
java -cp .:./antlr-4.5.1-complete.jar:$CLASSPATH org.antlr.v4.Tool $*

把它保存为antlr.sh,以后就可以使用下列命令来运行ANTLR工具了:

antlr

3,idea插件安装

file -> settings -> plugins 搜索 ANTLR 点击安装即可


修改下文件生成路径

创建springboot或者maven项目添加jar

       <dependency><groupId>org.antlr</groupId><artifactId>antlr4</artifactId><version>4.9.3</version></dependency>
创建Hello.g4

grammar 的名字要和文件名保持一致

grammar Hello;compilation_unit:prog+ EOF //EOF结束符号匹配;prog:level_num '9' HELLO ID '!';level_num:NUM | '9';//  '9' 是隐式词法,一般情况下,在词法解析树后,第一个排列(也就是当前位置) 匹配时首个匹配
// '9' 直接做本字符匹配//词法解析 由这些组成
HELLO : H E L L O;// 表示 由纯数字组成 最少有1个,可以有多个 至少出现一次
NUM : [0-9]+ ;//表示 由数字和字母组成 最少有1个,可以有多个 至少出现一次
ID : [a-zA-Z0-9]+ ;//如果是以这些符号开头的,这一行不匹配 放入 HIDDEN 隐藏通道
// 匹配双斜线后的任意字符,可以有可以没有
// .*? 非判断模式 可有可无
// '\r'? 可有可无  (适配linux)(liunx下的换行符为\n,win是\r\n)
LINE_COMMIT : '//' .*? '\r'? '\n' -> channel(HIDDEN);//无效字符 跳过不匹配 放入隐藏通道
WS : [ \t\r\n]+ -> skip;fragment H : [Hh];
fragment E : [Ee];
fragment L : [Ll];
fragment O : [Oo];

点击生成

最终项目结构


继承监听器,并实现替换输出

package com.yz.antlr.hello.impstand;import com.yz.antlr.hello.g4.HelloBaseListener;
import com.yz.antlr.hello.g4.HelloParser;
import org.antlr.v4.runtime.TokenStreamRewriter;
import org.antlr.v4.runtime.tree.TerminalNode;public class JCLAna extends HelloBaseListener {private TokenStreamRewriter tokenStreamRewriter;public JCLAna(TokenStreamRewriter tokenStreamRewriter) {super();this.tokenStreamRewriter = tokenStreamRewriter;}@Overridepublic void enterProg(HelloParser.ProgContext ctx) {//        super.enterProg(ctx);System.out.println(">>>" + ctx.getText());HelloParser.Level_numContext level_numContext = ctx.level_num();TerminalNode num = level_numContext.NUM();}@Overridepublic void exitLevel_num(HelloParser.Level_numContext ctx) {//        super.exitLevel_num(ctx);String text = ctx.getText();Integer level_num = Integer.valueOf(text);level_num += 1;// 修改替换 level_num,tokenStreamRewriter.replace(ctx.getStart(), ctx.getStop(), String.valueOf(level_num));}
}

`

获取树结构并替换值

package com.yz.antlr.hello.main;import com.yz.antlr.hello.g4.HelloLexer;
import com.yz.antlr.hello.g4.HelloParser;
import com.yz.antlr.hello.impstand.JCLAna;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStreamRewriter;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;/*** @author yz* @version 1.0* TODO* @date 2022/3/24 19:18*/
public class HelloAntlrMain {private static final Logger log = LoggerFactory.getLogger(HelloAntlrMain.class);public void execMath(String str) {CharStream input = CharStreams.fromString(str);// 将内容传递到词法解析器HelloLexer lexer = new HelloLexer(input);//getAllTokens() 行为会取出字符,导致后续无法解析
//        lexer.getAllTokens().forEach(token -> System.out.println(token.toString()));// 传递到流CommonTokenStream tokenStream = new CommonTokenStream(lexer);//获取到g4捕获到所有内容TokenStreamRewriter tokenStreamRewriter = new TokenStreamRewriter(tokenStream);//将流传递到语法解析器HelloParser parser = new HelloParser(tokenStream);//两个方法都能生成树,但是prog会报结尾错误,具体原因不详
//        ParseTree tree = parser.prog();ParseTree tree = parser.compilation_unit();System.out.println(tree.toStringTree());//创建树遍历器ParseTreeWalker parseTreeWalker = new ParseTreeWalker();//添加自定义解析器JCLAna jclAna = new JCLAna(tokenStreamRewriter);// 添加树和自定义解析器到parseTreeWalker.walk(jclAna, tree);// 输出打印最终的内容System.out.println(tokenStreamRewriter.getText());}public static void main(String[] args) throws IOException {HelloAntlrMain antlrMain = new HelloAntlrMain();String str = "01 9 Hello world!";antlrMain.execMath(str);}
}

最终实现数据读取和替换输出

([] ([6] ([13 6] 01) 9 Hello world !) <EOF>)
>>>019Helloworld!
29Helloworld!

·
·
·

参考资料

Antlr4 —入门介绍

Antlr4 入门

从定义到AST及其遍历方式

·
·

我是离离原上草,要是有用就请一键三连吧。

Antlr4介绍和Helloworld相关推荐

  1. play(一) play介绍,helloworld项目

    1.下载安装包并安装: (1)登录http://www.playframework.org/ 直接点击Download链接,下载.zip文件.选择版本play-1.4.2.zip (2) 直接解压该文 ...

  2. libgdx游戏引擎开发笔记(一)引擎介绍和Helloworld

       做Android快一年了,项目也做了四五个,感觉没什么动力向前,思绪整理了一段时间,决定转入Android游戏开发,同时发现了一款强大的游戏引擎libgdx,在此边学边整理,好记性不如烂笔头嘛! ...

  3. CORBA的简单介绍及HelloWorld

    CORBA概述 CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)是由OMG组织制订的一种标准的面向对象应用程 序体系规范.或者 ...

  4. Springboot简单介绍

    Springboot入门介绍 一.Spring框架概述 1.1 什么是Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnso ...

  5. Java编程一个简单运算程序+MyEclipse使用方法+HelloWorld,你get了吗?

    相信每一位编程者第一段代码都是HelloWorld,由于太简单,所以会一笔带过,下面重点讲的是对于萌新们的第二个代码.(打过HelloWorld的萌新们可以跳过这第一段,直接看第二段) 第一段:首先介 ...

  6. Visual Studio 2008 可扩展性开发(九):总结篇

    可以说木匠让小时的我第一次感受到了专业,虽然那时还不知道专业这个词,尤其是那些有年纪的老木匠,专注地在那锯木头.钉钉子.刨出带着香味的木花.他们有其他人所没有的工具,更重要的是他们掌握了那些工具.VS ...

  7. prism项目搭建 wpf_WPF Step By Step 系列-Prism框架在项目中使用

    Prism是一个强大的Mvvm框架,下面我们将重点讲解如何在项目使用Prism提供的基础功能,完成基于MVVM的WPF项目的框架设计和开发,包括应用程序的架构. 项目的解决方案结构,项目采用Prism ...

  8. Spring松耦合的实现

    HelloShiyanlou 与松耦合的实现 一.实验介绍 1.1 实验内容 本节实验将带你入门简单的 Maven 项目创建和如何实现松耦合. 1.2 实验知识点 Maven 介绍 Spring 松耦 ...

  9. 在Angular专家Dan Wahlin的免费33部分课程中学习Angular

    According to the Stack Overflow developer survey 2018, Angular is one of the most popular frameworks ...

最新文章

  1. openssl 加密解密 指令_OpenSSL未来架构设计,3.0初步实现
  2. 人脸情绪识别系统第一次迭代总结
  3. Android网络开发之Volley--Volley自定义Request
  4. 通过sql-labs进行sql注入学习(11-22)
  5. 微计算机和微处理器的区别,CPU和微处理器的区别
  6. Linux学习笔记-Makefile优化之头文件依赖
  7. 大型互联网分布式企业微服务云架构
  8. 权威解读 GitHub、Apache 疑云:主流开源软件究竟是否会被闭源?| CSDN 独家
  9. IE9下透明度设置无效
  10. win11快捷键怎么使用 Windows11快捷键的使用方法
  11. bdm导入mysql_MySQL数据库导入教程
  12. 【图像提取】基于matlab PCA-CSIFT feature图像特征提取【含Matlab源码 1174期】
  13. 创新金融科技:从零到一构建新房交易供应链金融服务 PPT分享
  14. 12.接口测试报告包含哪些内容
  15. 夜深人静了,我们来学学分布式锁
  16. 关于MySQL中出现相对应引用词报错“ambiguous”的问题
  17. 目前几种实时视频流协议对比
  18. 国内android第三方rom,安卓手机第三方rom大盘点,曾经火到不行,如今几乎全军覆没...
  19. 狄利克雷分布公式_关于狄利克雷分布的理解
  20. 局域网和广域网的传输流程

热门文章

  1. 用 create-vue 从 0 到 1 搭建一个后台管理系统
  2. 【Unity】通过Plane播放视频存在的颜色偏暗的问题
  3. Python基础语法 序列
  4. Django学习 Day9
  5. 金山实习日记·第二天(2008-07-15)
  6. FATE实战——从零实现横向联邦之逻辑回归
  7. python算法:回文数
  8. 多智能体系统协同一致性问题(三)
  9. 使用python Turtle工具画一个发射爱心的小人
  10. java 实现文件排序