ANTLR学习(二):ANTLR入门项目
文章目录
- 前言
- 一、项目简介
- 二、ANTLR工具、运行库以及自动生成的代码
- 三、将生成的语法分析器与Java程序集成
- 四、构建一个语言类应用程序
前言
通过一个入门项目学习到:
- 一些ANTLR语法的语义元素定义
- ANTLR根据语法自动生成代码的机制
- 如何讲自动生成的语法分析器和Java程序集成
- 如何使用语法分析树监听器辨析一个代码翻译工具
一、项目简介
构造一个语法,它为C语言或其继承者Java语法的一个很小的子集,我们将识别包括花括号或者嵌套的花括号的一些整数,例如
{1,2,3}
和{1,{2,3},4}
二、ANTLR工具、运行库以及自动生成的代码
步骤:
- 对一个语法运行ANTLR
- 将生成的代码与运行库一起编译
- 将编译好的代码和运行库放在一起运行
//语法文件同从以grammar关键字开头
//这是一个名为ArrayInit的语法,必须以文件名ArrayInit.g4相匹配
grammar ArrayInit;//名为init的规则,它匹配一对花括号中的、逗号分隔的value
init : '{' value (',' value)* '}';//一个value可以是嵌套的花括号结构,也可以是一个简单的整数,即INT语法符号
value : init| INT;//语法分析器的规则必须以小写字母开头,语法分析器的规则必须用大写字母开头
INT : [0-9]+ ; //定义语法符号INT,它由一个或多个数字组成
WS : [ \t\r\n]+ -> skip ; //定义语法规则“空白符号”,skip
根据上一篇文章所说的步骤运行ANTLR,得到下面这些文件,先来讲讲勾选文件
- 1、ArrayInit.tokens:ANTLR会给每个我们定义的语法符号指定一个数字形式的类型,然后将它们的对应关系存储与该文件中
- 2、ArrayInitListener.java,ArrayInitBaseListener:默认情况下,ANTLR生成的语法分析器能将输入文本转换为一棵语法分析树,在遍历该树时,遍历器能够触发一些列回调,并通知监听器对象,第一个文件接口给出了这些回调方法的定义,第二个文件包含该接口的默认实现类
- 3、ArrayInitLexer.java:ANTLR能够自动识别出我们的语法中的文法规则和词法规则,这个文件包含的是词法分析器的定义
- 4、ArrayInitParser.java:该文件包含语法分析器类的定义
测试1:
每行输出代表一个词法符号,其中包含该词法符号的全部信息
以第二行[@1,1:2='99',<INT>,1:1]
为例:
- @1表示他是第一个词法符号
- 1:2表示由第1到第2个字符组成
- ='99’表示包含的文本是99
- < INT >表示类型是INT
- 最后的1:1表示位于输入文本的第一行第一个字符处
查看语法分析树
测试2:
两组测试均符合预期
三、将生成的语法分析器与Java程序集成
下面将演示在IDEA中的操作:
需先下载好antlr插件
按照个人习惯,我的项目最终的结构如图:
- 1、新建Maven项目
一直点next(可根据自身需求修改) - 2、在pom.xml中设置antlr依赖
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>test2</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.antlr</groupId><artifactId>antlr4-runtime</artifactId><version>4.10.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.antlr</groupId><artifactId>antlr4-maven-plugin</artifactId><version>4.10.1</version><executions><execution><id>antlr</id><goals><goal>antlr4</goal></goals><phase>none</phase></execution></executions><configuration><outputDirectory>src/test/java</outputDirectory><listener>true</listener><treatWarningsAsErrors>true</treatWarningsAsErrors></configuration></plugin></plugins></build></project>
注意version中的版本要与自身ANTLR的版本相同
若出现爆红,一般情况下点击重新加载项目即可
- 3、在src\main\java中创建文件夹,在文件夹下新建antlr文件,文件内容在第二部分开头已给出
- 4、设置参数并运行
- 5、在项目文件中新建demoMain.java文件
内容为:
package demo.test;import demo.ArrayInitLexer;
import demo.ArrayInitParser;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;public class demoMain {public static void run(String str) throws Exception {ANTLRInputStream input = new ANTLRInputStream(str);ArrayInitLexer lexer = new ArrayInitLexer(input);CommonTokenStream tokens = new CommonTokenStream(lexer);ArrayInitParser parser = new ArrayInitParser(tokens);ParseTree tree = parser.init();System.out.println(tree.toStringTree(parser));}public static void main(String[] args) throws Exception {String[] testString = {"{1,{2,3},4}","{1,2,3,4}",};for(String s:testString){System.out.println("Input: " + s);run(s);}}
}
运行结果
若我们设置个错误的格式,将testString改为
String[] testString = {"{1,2"
};
运行结果:
这里可以发现,antlr可以自动报告语法错误并从语法错误中恢复
测试结果符合预期
- 6、如果想要实现可视化,可以在
.g4
文件中右键,点击Test Rule init
输入测试用例,即可看到对应的结果
四、构建一个语言类应用程序
在第三部分我们知道了如何对语法运行ANTLR工具,以及如何将自动生成的语法分析器和一个Java程序集成,在这一部分我们继续完成能够处理数组初始化语句的示例程序,让程序不仅能够识别初始化语句,还能够翻译他们。
例如:在Java中将类似{99,3,415}的short数组翻译为"\u0063\u0003\u01c3"
,的这种十六进制表示的结果
翻译,其实就是一系列的映射过程
对程序的要求:程序能从语法分析树中提取数据
方案:使用antlr内置的语法分析树遍历器进行深度优先遍历,然后再它触发的一系列回调函数中进行适当的操作。
步骤:
- 1、新建shortToUnicodeString.java文件,文件内容为:
package demo.test;import demo.ArrayInitBaseListener;
import demo.ArrayInitParser;public class shortToUnicodeString extends ArrayInitBaseListener {//将“{”翻译为 “ @Overridepublic void enterInit(ArrayInitParser.InitContext ctx){System.out.print('"');}//将”}“翻译为 ”@Overridepublic void exitInit(ArrayInitParser.InitContext ctx){System.out.print('"');}//其他翻译@Overridepublic void enterValue(ArrayInitParser.ValueContext ctx){int value = Integer.valueOf(ctx.INT().getText());System.out.printf("\\u%04x",value);}
}
- 2、新建Translate.java文件,文件内容为:
package demo.test;import demo.ArrayInitLexer;
import demo.ArrayInitParser;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;public class Translate {public static void run(String str) throws Exception{ANTLRInputStream input = new ANTLRInputStream(str);ArrayInitLexer lexer = new ArrayInitLexer(input);CommonTokenStream tokens = new CommonTokenStream(lexer);ArrayInitParser parser = new ArrayInitParser(tokens);ParseTree tree = parser.init();ParseTreeWalker walker = new ParseTreeWalker();walker.walk(new shortToUnicodeString(),tree);System.out.println();}public static void main(String[] args) {String[] testStr={"{99,3,451}"};for(String s:testStr){System.out.println("Input: " + s);System.out.print("Translate: ");try {run(s);} catch (Exception e) {e.printStackTrace();}}}
}
运行结果:
结果符合预期
ANTLR学习(二):ANTLR入门项目相关推荐
- Gradle学习(二十)——多项目构建详解
跨项目配置 虽然子项目之间可以完全隔离单独配置,但是子项目直接有相同特征的情况也是很常见的,多个项目共享配置是更好的选择. 配置和执行 在gradle学习-十八-构建的生命周期这一篇中我们已经讲过Gr ...
- Spring boot 学习二:入门
1: 需要的环境: JDK:至少JDK7才支持Spring boot maven:至少3.2 spring-boot:1.2.5.RELEASE(在pom.xml中指定) 2: 创建一个maven工程 ...
- ballerina 学习二十六 项目docker 部署 运行(二)
ballerina 从发布,到现在官方文档的更新也是很给力的,同时也有好多改进,越来越好用了 可以参考官方文档 https://ballerina.io/learn/by-guide/restful- ...
- python基础学习[python编程从入门到实践读书笔记(连载二)]:外星人入侵项目
第一版游戏demo 添加计分系统:中间是最高得分,右边是本次得分. 显示余下的飞船数 主函数如下,完整程序将上传到笔者的github:https://github.com/shizhengLi/lea ...
- hadoop hive hbase 入门学习 (二)
hadoop 自学系列 hadoop hive hbase 入门学习 (一) hadoop安装.hdfs学习及mapreduce学习 hadoop 软件下载 (hadoo ...
- (转)MyBatis框架的学习(二)——MyBatis架构与入门
http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: ...
- 机器学习与计算机视觉入门项目——视频投篮检测(二)
机器学习与计算机视觉入门项目--视频投篮检测(二) 一.手工特征与CNN特征 在上一次的博客中,介绍了计算机视觉和机器学习的关系.篮球进球检测的基本问题和数据集的制作.这次的我们主要介绍如何从原始图像 ...
- SSM通用活动报名系统(会员、管理员)+SSM框架+mysql+tomcat+Maven项目(毕设学习)可以用于学习SSM、maven项目入门
SSM通用活动报名系统(会员.管理员)+SSM框架+mysql+tomcat+Maven项目(毕设学习)可以用于学习SSM.maven项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资源 ...
- JBox2d入门学习二 -----我的小鸟
入门学习一当中我学会了如何定义并且创建一个世界,在世界当中定义并且创建一个刚体,并尝试给刚体一个力.最近比较忙..现在抽空实现了一个类似于愤怒小鸟的例子,先看看图吧. 贴代码,注解写的比较详细了, ...
最新文章
- ExecutorService为创建的线程池ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE)
- 对DBF的操作建议用微软的驱动和新的链接字符串。
- 计算机一级挂科率,[转]计算机一级难吗?看了它想挂科,难难难难把此(精)
- leetcode双指针(python与c++)
- VMware Workstation 9.0安装体验
- C++ cout的使用,看这一篇就够了
- linux卸载windows boot,windows和Linux双系统卸载Linux系统
- 苹果最强芯片M1 Ultra亮相!两个M1 Max胶水拼接,性能爆表
- 网站安全公司对渗透测试行业的运营观点
- Python爬虫:爬取网页图片
- Virtual host / experienced an error on node rabbit@XX and may be inaccessible
- thinkpad重装系统不引导_联想电脑重装win7系统后引导不了的原因是什么?
- 英语不好怎么自学python_为什么我就是学不好英语啊?我明明很努力,但是为... 我英语一般,但我很想学Python这个编程语言,行不?...
- 胖人瘦下来后,会长高或变矮吗?
- 人工智能学习体系大纲
- 云计算与云存储,具体是什么关系?
- 晶振的构造及工作原理
- 重尾分布,长尾分布,肥尾分布 和 随机游走 (Heavy-tailed, Long-tailed, Fat-tailed distribution and Random walk)
- 前端Vue2项目开发常用依赖
- 通过html打开本地exe
热门文章
- 服务器性能测试工具及实战,软件测试与项目分析-性能测试实战.pptx
- 使用RTL-SDR收听FM广播
- 看完这个你会掌握:50W年薪的AI算法工程师必备的工具
- 最优化 | 无约束优化方法 | C++实现
- 干货分享:PCB防静电设计的必要性
- 树状结构 | 北邮OJ | 109. 中序遍历树
- python写驱动程序_Python 我的第一个程序
- 学好英语的20个经典要诀
- D3Dnet:基于可变形三维卷积的视频超分辨,编译好的D3DNet可行变卷积python文件已经放在我的CSDN下载资源---->D3D.so
- Ubuntu创建和编译文件