文章目录

  • 前言
  • 一、项目简介
  • 二、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入门项目相关推荐

  1. Gradle学习(二十)——多项目构建详解

    跨项目配置 虽然子项目之间可以完全隔离单独配置,但是子项目直接有相同特征的情况也是很常见的,多个项目共享配置是更好的选择. 配置和执行 在gradle学习-十八-构建的生命周期这一篇中我们已经讲过Gr ...

  2. Spring boot 学习二:入门

    1: 需要的环境: JDK:至少JDK7才支持Spring boot maven:至少3.2 spring-boot:1.2.5.RELEASE(在pom.xml中指定) 2: 创建一个maven工程 ...

  3. ballerina 学习二十六 项目docker 部署 运行(二)

    ballerina 从发布,到现在官方文档的更新也是很给力的,同时也有好多改进,越来越好用了 可以参考官方文档 https://ballerina.io/learn/by-guide/restful- ...

  4. python基础学习[python编程从入门到实践读书笔记(连载二)]:外星人入侵项目

    第一版游戏demo 添加计分系统:中间是最高得分,右边是本次得分. 显示余下的飞船数 主函数如下,完整程序将上传到笔者的github:https://github.com/shizhengLi/lea ...

  5. hadoop hive hbase 入门学习 (二)

    hadoop 自学系列                hadoop hive hbase 入门学习 (一) hadoop安装.hdfs学习及mapreduce学习 hadoop 软件下载 (hadoo ...

  6. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图:  下面作简要概述: ...

  7. 机器学习与计算机视觉入门项目——视频投篮检测(二)

    机器学习与计算机视觉入门项目--视频投篮检测(二) 一.手工特征与CNN特征 在上一次的博客中,介绍了计算机视觉和机器学习的关系.篮球进球检测的基本问题和数据集的制作.这次的我们主要介绍如何从原始图像 ...

  8. SSM通用活动报名系统(会员、管理员)+SSM框架+mysql+tomcat+Maven项目(毕设学习)可以用于学习SSM、maven项目入门

    SSM通用活动报名系统(会员.管理员)+SSM框架+mysql+tomcat+Maven项目(毕设学习)可以用于学习SSM.maven项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资源 ...

  9. JBox2d入门学习二 -----我的小鸟

    入门学习一当中我学会了如何定义并且创建一个世界,在世界当中定义并且创建一个刚体,并尝试给刚体一个力.最近比较忙..现在抽空实现了一个类似于愤怒小鸟的例子,先看看图吧.   贴代码,注解写的比较详细了, ...

最新文章

  1. ExecutorService为创建的线程池ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE)
  2. 对DBF的操作建议用微软的驱动和新的链接字符串。
  3. 计算机一级挂科率,[转]计算机一级难吗?看了它想挂科,难难难难把此(精)
  4. leetcode双指针(python与c++)
  5. VMware Workstation 9.0安装体验
  6. C++ cout的使用,看这一篇就够了
  7. linux卸载windows boot,windows和Linux双系统卸载Linux系统
  8. 苹果最强芯片M1 Ultra亮相!两个M1 Max胶水拼接,性能爆表
  9. 网站安全公司对渗透测试行业的运营观点
  10. Python爬虫:爬取网页图片
  11. Virtual host / experienced an error on node rabbit@XX and may be inaccessible
  12. thinkpad重装系统不引导_联想电脑重装win7系统后引导不了的原因是什么?
  13. 英语不好怎么自学python_为什么我就是学不好英语啊?我明明很努力,但是为... 我英语一般,但我很想学Python这个编程语言,行不?...
  14. 胖人瘦下来后,会长高或变矮吗?
  15. 人工智能学习体系大纲
  16. 云计算与云存储,具体是什么关系?
  17. 晶振的构造及工作原理
  18. 重尾分布,长尾分布,肥尾分布 和 随机游走 (Heavy-tailed, Long-tailed, Fat-tailed distribution and Random walk)
  19. 前端Vue2项目开发常用依赖
  20. 通过html打开本地exe

热门文章

  1. 服务器性能测试工具及实战,软件测试与项目分析-性能测试实战.pptx
  2. 使用RTL-SDR收听FM广播
  3. 看完这个你会掌握:50W年薪的AI算法工程师必备的工具
  4. 最优化 | 无约束优化方法 | C++实现
  5. 干货分享:PCB防静电设计的必要性
  6. 树状结构 | 北邮OJ | 109. 中序遍历树
  7. python写驱动程序_Python 我的第一个程序
  8. 学好英语的20个经典要诀
  9. D3Dnet:基于可变形三维卷积的视频超分辨,编译好的D3DNet可行变卷积python文件已经放在我的CSDN下载资源---->D3D.so
  10. Ubuntu创建和编译文件