当前位置: 首页 > news >正文

java-在ANTLR中,如何从java文件中提取类名和方法名0.1.8

java-在ANTLR中,如何从java文件中提取类名和方法名0.1.0

    • 目标
    • java源文件
    • java的g4文件
    • 生成antlr代码
    • 最终代码
    • 调测结果
    • 阶段性总结

2024年9月12日11:16:01----0.1.8

目标

从一个java文件中提取出类名和方法名

java源文件

文件名是main.java,具体内容如下

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;import java.util.List;public class main {public static void main(String[] args) {//需要分析的语句String inputStr = "{42,43,{32,7+6,3+9,5,6+55},3,7+1,44}";System.out.println("input size is "+inputStr.length());//将字符串转换为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());}System.out.println(" ");
//        catToDog cc=new catToDog();
//        ParseTreeWalker walker=new ParseTreeWalker();
//        walker.walk(cc,parseTree);myVisitor mv = new myVisitor();mv.visit(parseTree);}public static class myVisitor extends HelloBaseVisitor<String> {/*** {@inheritDoc}** <p>The default implementation returns the result of calling* {@link #visitChildren} on {@code ctx}.</p>*/@Overridepublic String visitLine(HelloParser.LineContext ctx) {
//            System.out.println("visitLine"+ctx.value().toString()+" text:"+ctx.getText());System.out.printf("{");return visitChildren(ctx);}/*** {@inheritDoc}** <p>The default implementation returns the result of calling* {@link #visitChildren} on {@code ctx}.</p>*/@Overridepublic String visitIntShow(HelloParser.IntShowContext ctx) {int stopInt=ctx.getParent().getStop().getCharPositionInLine()-1;
//            System.out.println("dd1:"+getLastPosition(ctx.getStop().toString()) +" "+stopInt);if(getLastPosition(ctx.getStop().toString())==stopInt){System.out.printf(Integer.toHexString(Integer.parseInt(ctx.getText()))+"},");if(getLastPosition(ctx.getStop().toString())==34){System.out.printf(Integer.toHexString(Integer.parseInt(ctx.getText()))+"}");}else{System.out.printf(Integer.toHexString(Integer.parseInt(ctx.getText()))+"},");}}else{System.out.printf(Integer.toHexString(Integer.parseInt(ctx.getText()))+",");}return visitChildren(ctx);}/*** {@inheritDoc}** <p>The default implementation returns the result of calling* {@link #visitChildren} on {@code ctx}.</p>*/@Overridepublic String visitLineShow(HelloParser.LineShowContext ctx) {return visitChildren(ctx);}/*** {@inheritDoc}** <p>The default implementation returns the result of calling* {@link #visitChildren} on {@code ctx}.</p>*/@Override public String visitGetSUM(HelloParser.GetSUMContext ctx) {int stopInt=ctx.getParent().getStop().getCharPositionInLine()-1;
//            System.out.println("dd:"+getLastPosition(ctx.INT(1).getSymbol().toString()) +" "+stopInt);if(getLastPosition(ctx.INT(1).getSymbol().toString())==stopInt){if(getLastPosition(ctx.INT(1).getSymbol().toString())==34){System.out.printf((Integer.parseInt(ctx.INT(0).toString())+Integer.parseInt(ctx.INT(1).toString()))+"}");}else{System.out.printf((Integer.parseInt(ctx.INT(0).toString())+Integer.parseInt(ctx.INT(1).toString()))+"},");}}else{System.out.printf((Integer.parseInt(ctx.INT(0).toString())+Integer.parseInt(ctx.INT(1).toString()))+",");}return "4444";}public int getLastPosition(String ruleString){// String cc="[@25,28:29='44',<3>,1:28]";String lastPositionStr=ruleString.split("=")[0].split(":")[1];return Integer.parseInt(lastPositionStr);}}
}

java的g4文件

这里使用的java.g4文件,下载地址如下

https://download.csdn.net/download/m0_60688978/89742093
https://github.com/antlr/codebuff/tree/master/grammars/org/antlr/codebuff

生成antlr代码

参考这篇文章就可以了

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

最终会生成如下java文件

D:\源码\kafka-2.1\antlr\gen\Java.interp
D:\源码\kafka-2.1\antlr\gen\Java.tokens
D:\源码\kafka-2.1\antlr\gen\JavaBaseListener.java
D:\源码\kafka-2.1\antlr\gen\JavaBaseVisitor.java
D:\源码\kafka-2.1\antlr\gen\JavaLexer.java
D:\源码\kafka-2.1\antlr\gen\JavaLexer.interp
D:\源码\kafka-2.1\antlr\gen\JavaLexer.tokens
D:\源码\kafka-2.1\antlr\gen\JavaListener.java
D:\源码\kafka-2.1\antlr\gen\JavaParser.java
D:\源码\kafka-2.1\antlr\gen\JavaVisitor.java

最终代码

里面由一个main方法,和一个继承了JavaBaseListener类的自定义类,实现了几个需要的方法。使用walk类去触发遍历。

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;/*** https://github.com/antlr/codebuff/blob/master/grammars/org/antlr/codebuff/Java8.g4*/
public class javamain {public static JavaParser javaParser;public static void main(String[] args) throws IOException {
//        String inputStr = "{42,43,{32,7+6,3+9,5,6+55},3,7+1,44}";
//        System.out.println("input size is "+inputStr.length());//将字符串转换为ANTLR的CharStream
//        CharStream input = CharStreams.fromString(inputStr);CharStream input =CharStreams.fromStream(new FileInputStream("D:\\源码\\kafka-2.1\\antlr\\src\\main.java"));//使用词法分析器分析转换后的输入Lexer lexer = new JavaLexer(input);//新建一个词法符号的缓冲区,存储生成的词法符号CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);//使用语法分析器处理缓冲区的内容javaParser = new JavaParser(commonTokenStream);//对第一个line规则进行语法分析ParseTree parseTree = javaParser.compilationUnit();//获取树的子数目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());}System.out.println(" ");recognizeJava cc=new recognizeJava();ParseTreeWalker walker=new ParseTreeWalker();walker.walk(cc,parseTree);//        main.myVisitor mv = new main.myVisitor();
//        mv.visit(parseTree);}public static class recognizeJava extends JavaBaseListener{/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void enterClassDeclaration(JavaParser.ClassDeclarationContext ctx) {System.out.printf(ctx.CLASS()+" "+ctx.Identifier().getText()+"{\n");}/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void exitClassDeclaration(JavaParser.ClassDeclarationContext ctx) {System.out.printf("}\n");}/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void enterMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {TokenStream tokens = javaParser.getTokenStream();
//            System.out.printf(ctx.getStart().getText()+" ");String type="void";if(ctx.typeSpec()!=null){type=tokens.getText(ctx.typeSpec());}System.out.printf(type+" "+ctx.Identifier()+ctx.formalParameters().getText()+"{");}/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void exitMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {System.out.printf("}\n");}/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void enterClassOrInterfaceModifier(JavaParser.ClassOrInterfaceModifierContext ctx) {
//            System.out.println(":"+ctx.getParent().getParent().getStart().getText());if("public".equals(ctx.getParent().getParent().getStart().getText())){//这里写死的办法需要优化一下if("static".equals(ctx.getText())){System.out.printf(ctx.getText()+" ");}else{System.out.printf("    "+ctx.getText()+" ");}}else if("@".equals(ctx.getParent().getParent().getStart().getText())){System.out.printf("\n        "+ctx.getText()+" ");}else{System.out.printf(ctx.getText()+" ");}//            System.out.printf(ctx.getParent().getParent().getStart().getText()+":"+ctx.getText()+" ");}/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void exitClassOrInterfaceModifier(JavaParser.ClassOrInterfaceModifierContext ctx) { }/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void enterFormalParameters(JavaParser.FormalParametersContext ctx) { }/*** {@inheritDoc}** <p>The default implementation does nothing.</p>*/@Override public void exitFormalParameters(JavaParser.FormalParametersContext ctx) { }}
}

调测结果

虽然不完美,但是基本的能提取了,提取到的类和方法如下

public class main{public static void main(String[]args){}public static class myVisitor{@Override public String visitLine(HelloParser.LineContextctx){}@Override public String visitIntShow(HelloParser.IntShowContextctx){}@Override public String visitLineShow(HelloParser.LineShowContextctx){}@Override public String visitGetSUM(HelloParser.GetSUMContextctx){}public int getLastPosition(StringruleString){}
}
}

阶段性总结

  1. 再一次体会到了Listener遍历是从树顶到树脚,遍历到哪个词法规则,就会去自定义Listener中执行对应的方法。比如enterClassOrInterfaceModifier表示public或static,在遍历它语句public static时就会执行enterClassOrInterfaceModifier这个方法两次。
  2. 这篇中只使用了重写了五个方法:enterClassOrInterfaceModifier、exitMethodDeclaration、enterMethodDeclaration、exitClassDeclaration、enterClassDeclaration。
  3. TokenStream tokens = javaParser.getTokenStream(),token内容打印出来就是源文件的内容。其他常用的方法如下

tokens.getTokenSource().getLine():获取内容的行数,包括了EOF,所以你看到文件只有125行,这查询出来是126,是因为包括了EOF标记

相关文章:

java-在ANTLR中,如何从java文件中提取类名和方法名0.1.8

java-在ANTLR中&#xff0c;如何从java文件中提取类名和方法名0.1.0 目标java源文件java的g4文件生成antlr代码最终代码调测结果阶段性总结 2024年9月12日11:16:01----0.1.8 目标 从一个java文件中提取出类名和方法名 java源文件 文件名是main.java&#xff0c;具体内容如下…...

十大护眼灯钢琴灯品牌是智商税吗?十大钢琴灯品牌排行榜

十大护眼灯钢琴灯品牌是智商税吗&#xff1f;不良的光线不仅会使得孩子在读写用眼时眼睛不舒服&#xff0c;还会引起视觉疲劳伤眼视力健康&#xff0c;这个时候要能有一台可靠的护眼灯钢琴灯&#xff0c;那真是再好不过了。但是市面上护眼灯钢琴灯的种类太多&#xff0c;盲目挑…...

搜维尔科技:CyberGlove将实时捕捉运动信号和触觉反馈,将其重新定位到人形机器人进行驱动

CyberGlove将实时捕捉运动信号和触觉反馈&#xff0c;然后将其重新定位到人形机器人上。 这款18个传感器&#xff08;有18节点和22节点两个型号&#xff0c;22节点早期用于美国军事方面&#xff0c;支持无线通信、蓝牙、WiFi、射频&#xff09;数据手套的每个手指上有两个弯曲…...

数据结构:堆的算法

目录 一堆的向上调整算法二堆的向下调整算法三堆的应用:堆排序四TOPK问题 一堆的向上调整算法 我们在堆中插入一个数据一般实在堆的最后插入然后可以一步一步与上层结点&#xff08;父结点进行比较&#xff09;&#xff0c;继而进行交换&#xff0c;完成二叉树的结构&#xff0…...

python画图|3D直方图基础教程

前述已经完成了直方图和3D图的基本学习&#xff0c;链接如下&#xff1a; 直方图&#xff1a;python画图|水平直方图绘制-CSDN博客 3D图&#xff1a;python画图|水平直方图绘制-CSDN博客 现在我们尝试把二者结合&#xff0c;画3D直方图。 【1】官网教程 首先&#xff0c;依…...

C语言中的函数,实参,形参,递归

1&#xff1a;什么是函数 2&#xff1a;定义带形式参数的函数和带实际参数的函数 3&#xff1a;递归 --------------------------------------------------------------------------------------------------------------------------------- 1&#xff1a;在 C 语言中&…...

ICM20948 DMP代码详解(15)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;14&#xff09; 上一回开始对icm20948_sensor_setup函数中第3段代码即inv_icm20948_initialize函数进行解析。为了便于理解和回顾&#xff0c;再次贴出其源码&#xff0c;在EMD-Core\sources\Invn\Devices\Drivers\IC…...

NC 和为K的连续子数组

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个无序…...

JS设计模式之装饰者模式:优雅的给对象增添“魔法”

引言 在前端开发中&#xff0c;我们经常会遇到需要在不修改已有代码的基础上给对象添加新的行为或功能的情况。而传统的继承方式并不适合这种需求&#xff0c;因为继承会导致类的数量急剧增加&#xff0c;且每一个子类都会固定地实现一种特定的功能扩展。 装饰者模式则提供了…...

准备好了吗?JAVA从业AI开发的学习路线详解

作为一个拥有扎实 Java 基础的人&#xff0c;想要涉足人工智能&#xff08;AI&#xff09;应用开发&#xff0c;你已经在编程能力方面打下了很好的基础。Java 是一种通用的、强类型的语言&#xff0c;非常适合于开发高性能的应用程序&#xff0c;尤其是在后端服务和大规模分布式…...

神经网络通俗理解学习笔记(1)

神经网络通俗理解学习笔记&#xff08;1&#xff09; 神经网络原理激活函数前向传播和反向传播多层感知机代码实现加载数据网络结构损失函数优化器训练测试保存 回归问题一元线性回归多元线性回归多项式回归 线性回归代码实现数据生成设置超参数初始化参数可视化Pytorch模型实现…...

有n个人,他们需要分配m元钱(m>n),每个人至少分到1元钱,且每个人分到的钱数必须是整数。请问有多少种分配方案?

分配方案 描述 有n个人&#xff0c;他们需要分配m元钱(m>n)&#xff0c;每个人至少分到1元钱&#xff0c;且每个人分到的钱数必须是整数。请问有多少种分配方案? 输入 一行&#xff0c;两个整数&#xff0c;分别是人数n与钱数m&#xff0c;用一个空格隔开。 输出 一行&am…...

光耦——创新引擎 助推中国经济高质量发展

近年来&#xff0c;中国经济正处于转型升级的关键时期&#xff0c;高质量发展成为经济发展的重要目标。在这一伟大征程中&#xff0c;光耦作为一种关键性的电子元器件&#xff0c;正在发挥着重要的作用&#xff0c;助力中国经济迈向更加光明的未来。 光耦概念及工作原理 ▲光耦…...

Go 中 RPC 的使用教程

前言 RPC&#xff08;Remote Procedure Call&#xff09;是一种允许程序调用远程服务器上函数的方法&#xff0c;调用过程对于开发者来说像是调用本地函数一样方便。Go 语言自带了强大的 net/rpc 库&#xff0c;能够让开发者轻松实现基于 Go 的 RPC 服务。本文将介绍 Go 中 RP…...

挖耳勺可以伸进耳朵多深?安全可视挖耳勺推荐!

一般来说&#xff0c;挖耳勺不应该伸进耳朵太深&#xff0c;外耳道的长度大约在2.5厘米到3.5厘米之间&#xff0c;但不建议将挖耳勺伸进超过外耳道外1/3的深度&#xff0c;也就是大概1厘米左右较为安全。因为如果伸得太深&#xff0c;很容易损伤外耳道皮肤&#xff0c;引起疼痛…...

SuperMap GIS基础产品FAQ集锦(20240911)

一、SuperMap iObjects Java 问题1&#xff1a;【iObject Python】Objects Python产品有哪些能力特性和优势&#xff1f; 11.2.0 【解决办法】iObjects Python产品包含传统GIS功能&#xff08;基于iObjects Java扩展的功能接口&#xff09;和AI GIS功能模块。 其中传统GIS功能…...

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compo…...

ChatGPT提示词优化大师使用指南

我希望你成为我的ChatGPT提示词优化大师。 您的目标是帮助我根据自己的需要制定尽可能最好的提示。 你提供的提示应该是站在我向ChatGPT发起请求的角度来写的。我的初始提示词如下&#xff1a;此处填入你的初始提示词 ChatGPT提示词生成器 我希望你充当提示词生成器。 比如&…...

计算机毕业设计 智能推荐旅游平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

【拥抱AI】基于多种数据分段工具的优缺点分析

最近在深入了解RAG方面的知识&#xff0c;其中数据清洗和数据分段是创建知识库的重要步骤。数据清洗目前暂时选用了MinerU&#xff0c;然后就需要针对数据分段进行选型。 以下是我了解到的几种数据分段工具&#xff0c;简单总结了一下它们的优缺点&#xff0c;权当笔记分享&am…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...