依赖库
beanShell 的 bsh-2.0b4.jar
下载地址 http://beanshell.org/download.html
XML dom4j-1.6.1.jar
开发环境
{
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>