网站跳出,safari网页视频怎么下载,国际旅游网站设计报告,全球互联网排名前十名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;具体内容如下… 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,76,39,5,655},3,71,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 ccnew catToDog();
// ParseTreeWalker walkernew ParseTreeWalker();
// walker.walk(cc,parseTree);myVisitor mv new myVisitor();mv.visit(parseTree);}public static class myVisitor extends HelloBaseVisitorString {/*** {inheritDoc}** pThe default implementation returns the result of calling* {link #visitChildren} on {code ctx}./p*/Overridepublic String visitLine(HelloParser.LineContext ctx) {
// System.out.println(visitLinectx.value().toString() text:ctx.getText());System.out.printf({);return visitChildren(ctx);}/*** {inheritDoc}** pThe default implementation returns the result of calling* {link #visitChildren} on {code ctx}./p*/Overridepublic String visitIntShow(HelloParser.IntShowContext ctx) {int stopIntctx.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}** pThe default implementation returns the result of calling* {link #visitChildren} on {code ctx}./p*/Overridepublic String visitLineShow(HelloParser.LineShowContext ctx) {return visitChildren(ctx);}/*** {inheritDoc}** pThe default implementation returns the result of calling* {link #visitChildren} on {code ctx}./p*/Override public String visitGetSUM(HelloParser.GetSUMContext ctx) {int stopIntctx.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:2944,3,1:28];String lastPositionStrruleString.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,76,39,5,655},3,71,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 ccnew recognizeJava();ParseTreeWalker walkernew ParseTreeWalker();walker.walk(cc,parseTree);// main.myVisitor mv new main.myVisitor();
// mv.visit(parseTree);}public static class recognizeJava extends JavaBaseListener{/*** {inheritDoc}** pThe default implementation does nothing./p*/Override public void enterClassDeclaration(JavaParser.ClassDeclarationContext ctx) {System.out.printf(ctx.CLASS() ctx.Identifier().getText(){\n);}/*** {inheritDoc}** pThe default implementation does nothing./p*/Override public void exitClassDeclaration(JavaParser.ClassDeclarationContext ctx) {System.out.printf(}\n);}/*** {inheritDoc}** pThe default implementation does nothing./p*/Override public void enterMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {TokenStream tokens javaParser.getTokenStream();
// System.out.printf(ctx.getStart().getText() );String typevoid;if(ctx.typeSpec()!null){typetokens.getText(ctx.typeSpec());}System.out.printf(type ctx.Identifier()ctx.formalParameters().getText(){);}/*** {inheritDoc}** pThe default implementation does nothing./p*/Override public void exitMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {System.out.printf(}\n);}/*** {inheritDoc}** pThe 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}** pThe default implementation does nothing./p*/Override public void exitClassOrInterfaceModifier(JavaParser.ClassOrInterfaceModifierContext ctx) { }/*** {inheritDoc}** pThe default implementation does nothing./p*/Override public void enterFormalParameters(JavaParser.FormalParametersContext ctx) { }/*** {inheritDoc}** pThe 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){}
}
}阶段性总结
再一次体会到了Listener遍历是从树顶到树脚遍历到哪个词法规则就会去自定义Listener中执行对应的方法。比如enterClassOrInterfaceModifier表示public或static在遍历它语句public static时就会执行enterClassOrInterfaceModifier这个方法两次。这篇中只使用了重写了五个方法enterClassOrInterfaceModifier、exitMethodDeclaration、enterMethodDeclaration、exitClassDeclaration、enterClassDeclaration。TokenStream tokens javaParser.getTokenStream()token内容打印出来就是源文件的内容。其他常用的方法如下 tokens.getTokenSource().getLine()获取内容的行数包括了EOF所以你看到文件只有125行这查询出来是126是因为包括了EOF标记