java类代码解析为语法树 XML

本文介绍了如何使用BeanShell的bsh-2.0b4.jar和XMLdom4j-1.6.1.jar库解析Java源代码,通过BshParseUtil类将Person类及其方法转换为XML格式,展示了关键代码片段和辅助处理器的处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

依赖库

beanShell 的 bsh-2.0b4.jar
下载地址 http://beanshell.org/download.html
XML dom4j-1.6.1.jar

开发环境

![在这里插入图片描述](https://img-blog.csdnimg.cn/dcb34c910fa746638b11f78a92172078.png在这里插入图片描述

包名必须为 bsh ,因为 beanShell 中的Parse 相关类不是公共的,

测试解析类


public class Person {
    public String name;
    public int age;
    public void funcForTest(String testParma1,int testParma2){
        for (int i = 0; i < 10; i++) {
            System.out.println("for test");
        }

    }
    public void ifElseTest(int name){
        if(name == 1){
            System.out.println("if test");
        }else if(name == 2){
            System.out.println("else if test");
        }else {
            System.out.println("else test");
        }
    }
    public void whileTest(){
        while (true){
            System.out.println("while test");
        }
    }
    public void tryCatchTest(){
        try {
            System.out.println("try test");
        }catch (Exception e){
            System.out.println("catch test");
        }finally {
            System.out.println("finally test");
        }
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

解析主类

package bsh;


import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;


public class BshParseUtil {

    //是否对代码进行格式化
    public static  boolean isFormatCode = true;
    //制表符的数量
    public static int tabCount = 0;

    public static void addTab(StringBuffer stringBuffer){
        for (int i = 0; i < tabCount; i++) {
            stringBuffer.append("\t");
        }

    }

    public static String getText(SimpleNode simpleNode) {

        StringBuffer var1 = new StringBuffer();
        for(Token var2 = simpleNode.firstToken; var2 != null; var2 = var2.next) {

            //如果是{; 的话加换行符,并添加制表符进行格式化
            if(isFormatCode){
                if(var2.image.equals("{")){
                    var1.append("\n");
                    addTab(var1);
                    tabCount++;
                }else if(var2.image.equals("}")){
                    tabCount--;
                    var1.append("\n");
                    addTab(var1);
                }
            }
            var1.append(var2.image);

            //当前不是. 并且下一个token 不是.也不是) 的情况下加空格 小括号的前面不加空格 中括号后面不加空格,]前面不加空格
            //(右边的不加空格
            if(!var2.image.equals(".") && !var2.image.equals("!") && !var2.image.equals("[") &&!var2.image.equals("(")){
                if(var2.next != null && !var2.next.image.equals(".")
                        &&!var2.next.image.equals(")")
                        &&!var2.next.image.equals("(")
                        &&!var2.next.image.equals("]")){
                    var1.append(" ");
                }
            }
            //如果是{; 的话加换行符,并添加制表符进行格式化
            if(isFormatCode){
                if(var2.image.equals("{")){
                    var1.append("\n");
                    addTab(var1);
                }else if(var2.image.equals(";")){
                    var1.append("\n");
                    addTab(var1);
                }

            }
            if(var2.image.equals("(")){
                isFormatCode = false;

            }else if(var2.image.equals(")")){
                isFormatCode = true;
            }


            if (var2 == simpleNode.lastToken ) {
                break;
            }
        }

        return var1.toString().trim();
    }

    public static String bshPraseNodeToXml(SimpleNode rootNode, Element element){
        for(int i = 0; i< rootNode.jjtGetNumChildren(); i++){
            SimpleNode childNode = rootNode.getChild(i);
            String nodeStatement = childNode.toString();
            if(childNode instanceof BSHClassDeclaration){
                StatementProcessor.handleClassDeclaration(childNode,element);
            }else if(childNode instanceof BSHMethodDeclaration){
                StatementProcessor.handleMethodDeclaration(childNode,element);
            }
            else {
                switch (nodeStatement){
                    case "TypedVariableDeclaration":
                        StatementProcessor.handleTypedVariableDeclaration(childNode,element);
                        break;
                    //package 解析不了
                    case "PackageDeclaration":
                        StatementProcessor.handlePackageDeclaration(childNode,element);
                        break;
                    case "IfStatement":
                        StatementProcessor.handleIfStatement(childNode,element);
                        break;
                    case "ForStatement":
                        StatementProcessor.handleForStatement(childNode,element);
                        break;
                    case "EnhancedForStatement":
                        StatementProcessor.handleForeachStatement(childNode,element);
                        break;
                    case "WhileStatement":
                        StatementProcessor.handleWhileStatement(childNode,element);
                        break;
                    case "PrimaryExpression":
                        StatementProcessor.handlePrimaryExpression(childNode,element);
                        break;
                    case "TryStatement":
                        StatementProcessor.handleTryCatchStatement(childNode,element);
                        break;
                    default:
                        StatementProcessor.handleDefaultStatement(childNode,element);
                        break;
                }
            }

        }
        return null;
    }

    public static void main(String[] args) throws ParseException, FileNotFoundException {

        FileReader localFileReader = new FileReader("e:\\Person.java");
        Parser localParser = new Parser(localFileReader);
        localParser.setRetainComments(true);
        SimpleNode rootNode = new SimpleNode(1);
        int i = 0;
        while (!localParser.Line()) {
            SimpleNode  node = localParser.popNode();
            System.out.println(node.toString());
            rootNode.jjtAddChild(node, i);
            i++;
        }

        Document document = DocumentHelper.createDocument();
        Element element = document.addElement("keydriven");

        BshParseUtil.bshPraseNodeToXml(rootNode,element);


        String[][] arr = new String[][]{{}};

        XMLWriter writer = null;
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();
            writer = new XMLWriter(new FileOutputStream("e:\\test.xml"),format);
            writer.write(document);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null)
                    writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

辅助处理器类

package bsh;

import org.dom4j.Element;

import java.util.Hashtable;

public class StatementProcessor {

    public static void ifStatementDfs(SimpleNode node,Element ifElseElement){

        if(node instanceof BSHBlock){
            Element elseEle = ifElseElement.addElement("else");
            BshParseUtil.bshPraseNodeToXml(node,elseEle);
        }else if(node instanceof BSHIfStatement){
            Element elseIfEle = ifElseElement.addElement("else-if");
            if(node.getChild(0) instanceof BSHUnaryExpression || node.getChild(0) instanceof BSHBinaryExpression){
                node.getChild(0).firstToken = node.firstToken.next.next;
            }
            Element conditionEle = elseIfEle.addElement("condition");
            conditionEle.addCDATA(BshParseUtil.getText(node.getChild(0)));
            BshParseUtil.bshPraseNodeToXml(node.getChild(1),elseIfEle);
            if(node.jjtGetNumChildren() == 3)
                ifStatementDfs(node.getChild(2),ifElseElement);
        }

    }

    public static void  handleIfStatement(SimpleNode childNode,Element element){
            Element ifElseElement = element.addElement("if-else-block");
            Element ifElement  = ifElseElement.addElement("if");
            //如果是!flag 形式 ,condition不对
            Element conditionEle = ifElement.addElement("condition");

            if(childNode.getChild(0) instanceof BSHBinaryExpression || childNode.getChild(0) instanceof BSHUnaryExpression){
                childNode.getChild(0).firstToken = childNode.firstToken.next.next;
            }
            conditionEle.addCDATA(BshParseUtil.getText(childNode.getChild(0)));
            BshParseUtil.bshPraseNodeToXml(childNode.getChild(1),ifElement);
            if(childNode.jjtGetNumChildren() == 3)
                ifStatementDfs(childNode.getChild(2),ifElseElement);
            Element notationEle = ifElseElement.addElement("notation");
            notationEle.addCDATA(childNode.firstToken.specialToken == null?"":childNode.firstToken.specialToken.image);
    }

    public static void handleForStatement(SimpleNode childNode,Element element){


            Element forEle = element.addElement("for");
            Element initEle = forEle.addElement("init");
            initEle.addCDATA(BshParseUtil.getText(childNode.getChild(0)));
            Element conditionEle = forEle.addElement("condition");
            BSHBinaryExpression bshBinaryExpression = (BSHBinaryExpression)childNode.getChild(1);
            //发现frist token 不对,不知道是为什么
            bshBinaryExpression.firstToken = bshBinaryExpression.getChild(0).firstToken;
            conditionEle.addCDATA(BshParseUtil.getText(bshBinaryExpression));
            Element incrementEle = forEle.addElement("increment");
            incrementEle.addCDATA(BshParseUtil.getText(childNode.getChild(2)));
            //type
            Element typeEle = forEle.addElement("type");
            typeEle.addCDATA("for");
            BshParseUtil.bshPraseNodeToXml(childNode.getChild(3),forEle);
            //注释
            Element notationEle = forEle.addElement("notation");
            notationEle.addCDATA(childNode.firstToken.specialToken == null?"":childNode.firstToken.specialToken.image);


    }

    public static void handleForeachStatement(SimpleNode childNode,Element element){
        {
            //foreach
            Element forEle = element.addElement("for");
            Element initEle = forEle.addElement("init");
            BSHEnhancedForStatement forStatement = (BSHEnhancedForStatement)childNode;
            initEle.addCDATA(BshParseUtil.getText(forStatement.getChild(0)) + " " + forStatement.varName);

            Element typeEle = forEle.addElement("type");
            typeEle.addCDATA("foreach");
            Element varialbleEle = forEle.addElement("varialble");
            varialbleEle.addCDATA(BshParseUtil.getText(childNode.getChild(1)));
            BshParseUtil.bshPraseNodeToXml(childNode.getChild(2),forEle);
            //注释
            Element notationEle = forEle.addElement("notation");
            notationEle.addCDATA(childNode.firstToken.specialToken == null?"":childNode.firstToken.specialToken.image);

        }
    }

    public static  void handleWhileStatement(SimpleNode childNode,Element element){
        {
            BSHWhileStatement whileStatement = (BSHWhileStatement) childNode;
            if(whileStatement.isDoStatement){
                Element whileEle = element.addElement("do-while");
                Element conditionEle = whileEle.addElement("condition");
                conditionEle.addCDATA(BshParseUtil.getText(childNode.getChild(1)));
                BshParseUtil.bshPraseNodeToXml(childNode.getChild(0),whileEle);
                //注释
                Element notationEle = whileEle.addElement("notation");
                notationEle.addCDATA(childNode.firstToken.specialToken == null?"":childNode.firstToken.specialToken.image);
            }else {
                Element whileEle = element.addElement("while");
                Element conditionEle = whileEle.addElement("condition");
                conditionEle.addCDATA(BshParseUtil.getText(childNode.getChild(0)));
                BshParseUtil.bshPraseNodeToXml(childNode.getChild(1),whileEle);
                //注释
                Element notationEle = whileEle.addElement("notation");
                notationEle.addCDATA(childNode.firstToken.specialToken == null?"":childNode.firstToken.specialToken.image);
            }

        }
    }

    public static void handlePrimaryExpression(SimpleNode childNode,Element element){
               handleDefaultStatement(childNode,element);
            
    }

    public static  void handleTryCatchStatement(SimpleNode childNode,Element element){
        Element tryCatchEle = element.addElement("try-catch-block");
        //Try
        Element tryEle = tryCatchEle.addElement("try");
        BshParseUtil.bshPraseNodeToXml(childNode.getChild(0),tryEle);

        for(int i = 1; i < childNode.jjtGetNumChildren(); i++){
            SimpleNode childChildNode = childNode.getChild(i);
            if(childChildNode instanceof BSHBlock){
                if(childNode.getChild(i-1) instanceof BSHFormalParameter){
                    Element catchEle = tryCatchEle.addElement("catch");
                    Element expressionEle = catchEle.addElement("expression");
                    expressionEle.addCDATA(BshParseUtil.getText(childNode.getChild(i-1)));
                    BshParseUtil.bshPraseNodeToXml(childNode.getChild(i),catchEle);
                }else {
                    Element finallyEle = tryCatchEle.addElement("finally");
                    BshParseUtil.bshPraseNodeToXml(childNode.getChild(i),finallyEle);
                }
            }
        }
    }


    public  static  void handleDefaultStatement(SimpleNode childNode,Element element){
        Element codeBlock = element.addElement("code-block");
        //x++; 会出现这种问题
        if(childNode instanceof BSHUnaryExpression || childNode instanceof BSHBinaryExpression)
            childNode.firstToken = childNode.getChild(0).firstToken;
        if(childNode.lastToken.next != null && childNode.lastToken.next.image.equals(";"))
            codeBlock.addCDATA(BshParseUtil.getText(childNode) + ";");
        else{
            codeBlock.addCDATA(BshParseUtil.getText(childNode));
        }

        //注释
        String notation = childNode.firstToken.specialToken == null?"":childNode.firstToken.specialToken.image;
        Element notationEle = codeBlock.addElement("notation");
        notationEle.addCDATA(notation);

    }

    public static void handlePackageDeclaration(SimpleNode childNode,Element element){

        Element packageEle = element.addElement("package");
        packageEle.addCDATA(BshParseUtil.getText(childNode));

    }


    public static void handleClassDeclaration(SimpleNode childNode,Element element){

        Element classEle = element.addElement("class-block");
        BSHClassDeclaration classDeclaration = (BSHClassDeclaration) childNode;
        Element classNameEle = element.addElement("class-name");
        classNameEle.addCDATA(classDeclaration.name);
        BSHBlock classBlock = (BSHBlock)childNode.getChild(0);
        BshParseUtil.bshPraseNodeToXml(classBlock,classEle);

    }

    public static void handleMethodDeclaration(SimpleNode childNode,Element element){

        BSHMethodDeclaration methodInvocation = (BSHMethodDeclaration) childNode;
        Element methodEle = element.addElement("method-block");
        Element nameEle = methodEle.addElement("name");
        nameEle.addCDATA(methodInvocation.name);
        Element returnTypeEle = methodEle.addElement("return-type");
        returnTypeEle.addCDATA(BshParseUtil.getText(methodInvocation.getReturnTypeNode()));
        Element argList = methodEle.addElement("arglist");
        BSHFormalParameters parameters = methodInvocation.paramsNode;
        for (int j = 0; j < parameters.jjtGetNumChildren(); j++) {
            Element arg = argList.addElement("arg");
            SimpleNode argNode = parameters.getChild(j);
            arg.addCDATA( BshParseUtil.getText(argNode));
        }
        BshParseUtil.bshPraseNodeToXml(childNode.getChild(2),methodEle);
    }

    public static void handleTypedVariableDeclaration(SimpleNode childNode,Element element ){
        BshParseUtil.isFormatCode = false;
        BSHTypedVariableDeclaration typedVariableDeclaration = (BSHTypedVariableDeclaration) childNode;
        Element typeEle = element.addElement("property");
        typeEle.addCDATA(BshParseUtil.getText(typedVariableDeclaration));
        BshParseUtil.isFormatCode = true;
    }

}

解析结果

<?xml version="1.0" encoding="UTF-8"?>

<keydriven>
  <class-block>
    <property><![CDATA[public String name]]></property>
    <property><![CDATA[public int age]]></property>
    <method-block>
      <name><![CDATA[funcForTest]]></name>
      <return-type><![CDATA[void]]></return-type>
      <arglist>
        <arg><![CDATA[String testParma1]]></arg>
        <arg><![CDATA[int testParma2]]></arg>
      </arglist>
      <for>
        <init><![CDATA[int i = 0]]></init>
        <condition><![CDATA[i < 10]]></condition>
        <increment><![CDATA[i ++]]></increment>
        <type><![CDATA[for]]></type>
        <code-block><![CDATA[System.out.println("for test");]]>
          <notation><![CDATA[]]></notation>
        </code-block>
        <notation><![CDATA[]]></notation>
      </for>
    </method-block>
    <method-block>
      <name><![CDATA[ifElseTest]]></name>
      <return-type><![CDATA[void]]></return-type>
      <arglist>
        <arg><![CDATA[int name]]></arg>
      </arglist>
      <if-else-block>
        <if>
          <condition><![CDATA[name == 1]]></condition>
          <code-block><![CDATA[System.out.println("if test");]]>
            <notation><![CDATA[]]></notation>
          </code-block>
        </if>
        <else-if>
          <condition><![CDATA[name == 2]]></condition>
          <code-block><![CDATA[System.out.println("else if test");]]>
            <notation><![CDATA[]]></notation>
          </code-block>
        </else-if>
        <else>
          <code-block><![CDATA[System.out.println("else test");]]>
            <notation><![CDATA[]]></notation>
          </code-block>
        </else>
        <notation><![CDATA[]]></notation>
      </if-else-block>
    </method-block>
    <method-block>
      <name><![CDATA[whileTest]]></name>
      <return-type><![CDATA[void]]></return-type>
      <arglist/>
      <while>
        <condition><![CDATA[true]]></condition>
        <code-block><![CDATA[System.out.println("while test");]]>
          <notation><![CDATA[]]></notation>
        </code-block>
        <notation><![CDATA[]]></notation>
      </while>
    </method-block>
    <method-block>
      <name><![CDATA[tryCatchTest]]></name>
      <return-type><![CDATA[void]]></return-type>
      <arglist/>
      <try-catch-block>
        <try>
          <code-block><![CDATA[System.out.println("try test");]]>
            <notation><![CDATA[]]></notation>
          </code-block>
        </try>
        <catch>
          <expression><![CDATA[Exception e]]></expression>
          <code-block><![CDATA[System.out.println("catch test");]]>
            <notation><![CDATA[]]></notation>
          </code-block>
        </catch>
        <finally>
          <code-block><![CDATA[System.out.println("finally test");]]>
            <notation><![CDATA[]]></notation>
          </code-block>
        </finally>
      </try-catch-block>
    </method-block>
    <method-block>
      <name><![CDATA[getName]]></name>
      <return-type><![CDATA[String]]></return-type>
      <arglist/>
      <code-block><![CDATA[return name ;]]>
        <notation><![CDATA[]]></notation>
      </code-block>
    </method-block>
    <method-block>
      <name><![CDATA[setName]]></name>
      <return-type><![CDATA[void]]></return-type>
      <arglist>
        <arg><![CDATA[String name]]></arg>
      </arglist>
      <code-block><![CDATA[this.name = name;]]>
        <notation><![CDATA[]]></notation>
      </code-block>
    </method-block>
    <method-block>
      <name><![CDATA[getAge]]></name>
      <return-type><![CDATA[int]]></return-type>
      <arglist/>
      <code-block><![CDATA[return age ;]]>
        <notation><![CDATA[]]></notation>
      </code-block>
    </method-block>
    <method-block>
      <name><![CDATA[setAge]]></name>
      <return-type><![CDATA[void]]></return-type>
      <arglist>
        <arg><![CDATA[int age]]></arg>
      </arglist>
      <code-block><![CDATA[this.age = age;]]>
        <notation><![CDATA[]]></notation>
      </code-block>
    </method-block>
  </class-block>
  <class-name><![CDATA[Person]]></class-name>
</keydriven>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值