📄 astviewer.java
字号:
package edu.ustc.cs.minijool.interp;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
/**
* 把AST用swing的树控件显示出来。
*
*/
public class ASTViewer extends JFrame {
/**
* 把以AST节点n为根的AST用树控件显示。
* @param n AST的根节点
*/
public void viewAST(ASTNode n) {
this.setTitle("AST Viewer");
this.setSize(600, 400);
this.setLocation(300, 200);
Container content = getContentPane();
Object[] hierarchy = new HierachyBuilder().build(n);
DefaultMutableTreeNode root = processHierarchy(hierarchy);
JTree tree = new JTree(root);
content.add(new JScrollPane(tree), BorderLayout.CENTER);
setVisible(true);
}
/**
* Small routine that will make node out of the first entry in the array,
* then make nodes out of subsequent entries and make them child nodes of
* the first one. The process is repeated recursively for entries that are
* arrays.
*/
private DefaultMutableTreeNode processHierarchy(Object[] hierarchy) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(hierarchy[0]);
DefaultMutableTreeNode child;
for (int i = 1; i < hierarchy.length; i++) {
Object nodeSpecifier = hierarchy[i];
if (nodeSpecifier instanceof Object[]) // Ie node with children
child = processHierarchy((Object[]) nodeSpecifier);
else
child = new DefaultMutableTreeNode(nodeSpecifier); // Ie Leaf
node.add(child);
}
return (node);
}
}
/**
* 从AST构造树的层次结构
* 注意这个visitor与其他的不同之处在于返回true,这样JDT会自动访问每个节点的
* 子节点
*/
class HierachyBuilder extends GenericVisitor {
private final String PARENT = "parent";
private final String THIS = "this";
private java.util.List hierachy;
private java.util.List p, c;
/**
* 构造以AST节点n为根的AST的层次结构
* @param n AST的根节点
* @return 一个数组,其元素类型或者是String,或者是类似的一个数组。
*/
public Object[] build(ASTNode n) {
hierachy = new ArrayList();
hierachy.add("MiniJOOL Program");
p = hierachy;
n.accept(this);
return hierachy.toArray();
}
public boolean visit(NumberLiteral n) {
c = new ArrayList();
c.add(getNodeName(n) + " \"" + n.getToken() + "\"");
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
public boolean visit(SimpleName n) {
c = new ArrayList();
c.add(getNodeName(n) + " \"" + n.getIdentifier() + "\"");
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
public boolean visit(InfixExpression n) {
c = new ArrayList();
c.add(getNodeName(n) + " \"" + n.getOperator().toString() + "\"");
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
public boolean visit(Assignment n) {
c = new ArrayList();
c.add(getNodeName(n) + " \"" + n.getOperator().toString() + "\"");
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
public boolean visit(PostfixExpression n) {
c = new ArrayList();
c.add(getNodeName(n) + " \"" + n.getOperator().toString() + "\"");
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
public boolean visit(PrefixExpression n) {
c = new ArrayList();
c.add(getNodeName(n) + " \"" + n.getOperator().toString() + "\"");
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
protected boolean visitNode(ASTNode n) {
c = new ArrayList();
c.add(getNodeName(n));
n.setProperty(PARENT, p);
n.setProperty(THIS, c);
p = c;
return true;
}
protected void endVisitNode(ASTNode n) {
p = (java.util.List)n.getProperty(PARENT);
c = (java.util.List)n.getProperty(THIS);
if (c.size() == 1) {
p.add(c.get(0));
} else {
p.add(c.toArray());
}
}
private String getNodeName(ASTNode n) {
String fullName = n.getClass().getName();
int pos = fullName.lastIndexOf('.');
if (pos == -1) return fullName;
return fullName.substring(pos + 1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -