java-在ANTLR中,如何使用生成的Listener代码

2024-09-07 16:28

本文主要是介绍java-在ANTLR中,如何使用生成的Listener代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

测试基本环境

  1. windows 10
  2. java 19
  3. antlr 4.13.1

使用场景

主要是通过实现ParseTreeListener 的接口实现自己的业务逻辑,从而构建自己的程序。

Listener概要

  1. 生成java代码后,会有两个listener的类,HelloListener是接口,HelloBaseListener是实现。

D:\源码\kafka-2.1\antlr\gen\HelloBaseListener.java
D:\源码\kafka-2.1\antlr\gen\HelloListener.java

  1. HelloBaseListener和HelloListener是根据定义的语法生成的,其中HelloListener继承ParseTreeListener。
public class HelloBaseListener implements HelloListener {public interface HelloListener extends ParseTreeListener {
  1. 要触发Listener的事件,需要使用ParseTreeWalker对树进行遍历。

十进制转十六进制样例

这个样例主要是将字符串中的数字转换为16进制,然后按格式原样输出。如何生成ANTLR的java代码过程忽略了,可以参考之前的文章

https://blog.csdn.net/m0_60688978/article/details/141937659

Hello.g4文件

这是对字符串5{42,43,{32,3,5},44}ddd中的花括号里面的进行转换,

grammar Hello;
line:'{' value(','value)* '}';
value:INT| line;
INT:[0-9]+;

其实写成这样也没有问题?

grammar Hello;
line:'{' value(','value)* '}';
value:INT| line;
INT:[0-9]+;

main文件
这里需要继承HelloBaseListener,继承后你可以只需要重写enterLine、exitLine、enterValue就可以了,其他的方法根据情况来。代码如下:

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.antlr.v4.runtime.tree.TerminalNode;public class main {public static void main(String[] args) {//需要分析的语句String inputStr="5{42,43,{32,3,5},44}ddd";//将字符串转换为ANTLR的CharStreamCharStream input = CharStreams.fromString(inputStr);//使用词法分析器分析转换后的输入Lexer lexer = new HelloLexer(input);//新建一个词法符号的缓冲区,存储生成的词法符号CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);//使用语法分析器处理缓冲区的内容HelloParser helloParser = new HelloParser(commonTokenStream);//对第一个line规则进行语法分析ParseTree parseTree = helloParser.line();//获取树的子数目int childCount = parseTree.getChildCount();//打印LISP风格的树System.out.println(parseTree.toStringTree());//循环打印出子节点for (int i = 0; i < childCount; i++) {System.out.println("child "+i+":"+parseTree.getChild(i).toStringTree());}catToDog cc=new catToDog();ParseTreeWalker walker=new ParseTreeWalker();walker.walk(cc,parseTree);}public static class catToDog extends HelloBaseListener {StringBuilder s=new StringBuilder();@Overridepublic void enterLine(HelloParser.LineContext ctx) {s.append("{");}@Overridepublic void exitLine(HelloParser.LineContext ctx) {s.append("},");System.out.println(s.toString().replaceAll(",}","}").substring(0,s.toString().replaceAll(",}","}").length()-1));}@Overridepublic void enterValue(HelloParser.ValueContext ctx) {if(null!=ctx.INT()){System.out.println("enterValue:"+ctx.INT().getText());s.append(Integer.toHexString(Integer.parseInt(ctx.INT().getText()))+",");}}}
}

打印结果

line 1:0 extraneous input '5' expecting '{'
line 1:20 token recognition error at: 'd'
line 1:21 token recognition error at: 'd'
line 1:22 token recognition error at: 'd'
([] 5 { ([5] 42) , ([7] 43) , ([7] ([16 7] { ([5 16 7] 32) , ([7 16 7] 3) , ([7 16 7] 5) })) , ([7] 44) })
child 0:5
child 1:{
child 2:([5] 42)
child 3:,
child 4:([7] 43)
child 5:,
child 6:([7] ([16 7] { ([5 16 7] 32) , ([7 16 7] 3) , ([7 16 7] 5) }))
child 7:,
child 8:([7] 44)
child 9:}
enterValue:42
enterValue:43
enterValue:32
enterValue:3
enterValue:5
{2a,2b,{20,3,5}
enterValue:44
{2a,2b,{20,3,5},2c}

可以看到,没有在花括号里面的d字母有提示没有识别到,最后成功的将字符串5{42,43,{32,3,5},44}ddd中花括号的十进制原格式转换为了十六进制{2a,2b,{20,3,5},2c}。

这篇关于java-在ANTLR中,如何使用生成的Listener代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145564

相关文章

Qt 中 isHidden 和 isVisible 的区别与使用小结

《Qt中isHidden和isVisible的区别与使用小结》Qt中的isHidden()和isVisible()方法都用于查询组件显示或隐藏状态,然而,它们有很大的区别,了解它们对于正确操... 目录1. 基础概念2. 区别清见3. 实际案例4. 注意事项5. 总结1. 基础概念Qt 中的 isHidd

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

Java实现数据库图片上传与存储功能

《Java实现数据库图片上传与存储功能》在现代的Web开发中,上传图片并将其存储在数据库中是常见的需求之一,本文将介绍如何通过Java实现图片上传,存储到数据库的完整过程,希望对大家有所帮助... 目录1. 项目结构2. 数据库表设计3. 实现图片上传功能3.1 文件上传控制器3.2 图片上传服务4. 实现

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

CSS @media print 使用详解

《CSS@mediaprint使用详解》:本文主要介绍了CSS中的打印媒体查询@mediaprint包括基本语法、常见使用场景和代码示例,如隐藏非必要元素、调整字体和颜色、处理链接的URL显示、分页控制、调整边距和背景等,还提供了测试方法和关键注意事项,并分享了进阶技巧,详细内容请阅读本文,希望能对你有所帮助...

使用Folium在Python中进行地图可视化的操作指南

《使用Folium在Python中进行地图可视化的操作指南》在数据分析和可视化领域,地图可视化是一项非常重要的技能,它能够帮助我们更直观地理解和展示地理空间数据,Folium是一个基于Python的地... 目录引言一、Folium简介与安装1. Folium简介2. 安装Folium二、基础使用1. 创建

Java实现MD5加密的四种方式

《Java实现MD5加密的四种方式》MD5是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示,MD5的底层实现涉及多个复杂的步骤和算法,本文给大家介绍了Ja... 目录MD5介绍Java 中实现 MD5 加密方式方法一:使用 MessageDigest方法二:使用

Java中的runnable 和 callable 区别解析

《Java中的runnable和callable区别解析》Runnable接口用于定义不需要返回结果的任务,而Callable接口可以返回结果并抛出异常,通常与Future结合使用,Runnab... 目录1. Runnable接口1.1 Runnable的定义1.2 Runnable的特点1.3 使用Ru

Java中Runnable和Callable的区别和联系及使用场景

《Java中Runnable和Callable的区别和联系及使用场景》Java多线程有两个重要的接口,Runnable和Callable,分别提供一个run方法和call方法,二者是有较大差异的,本文... 目录一、Runnable使用场景二、Callable的使用场景三、关于Future和FutureTa

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory