📄 tablemaker.java
字号:
/**
* process the given <code>SymTabAST</code> as a file definition
*
* @param tree the <code>SymTabAST</code> to process
* @return <code>void</code>
* @see #setCurrentFile(String)
*/
public void processFile(SymTabAST tree) {
setCurrentFile(tree.getText());
}
/**
* adds the given <code>SymTabAST</code> to <code>imports</code> member
*
* @param tree the <code>SymTabAST</code> to process
* @return <code>void</code>
*/
public void processImport(SymTabAST tree) {
imports.add( tree );
}
/**
* clears the <code>imports</code> member
* @return <code>void</code>
*/
private void clearImports() {
imports.clear();
}
/**
* process the given SymTabAST as a label definition
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see com.trwx.symtab.antlr.SymTabAST
* @see net.sourceforge.transmogrify.symtab.LabelDef
* @see #walkTree(SymTabAST, boolean)
*/
public void processLabel(SymTabAST tree) {
String name = tree.findFirstToken(TokenTypes.IDENT).getText();
LabelDef label = new LabelDef( name, symbolTable.getCurrentScope(),
tree );
symbolTable.defineLabel( label );
walkTree((SymTabAST)tree.getFirstChild().getNextSibling(), false);
}
/**
* process the given <code>SymTabAST</code> as a class definition
*
* @param tree the <code>SymTabAST</code> to process
* @return <code>void</code>
* @see #makeClass(String, SymTabAST)
* @see #walkSiblings(SymTabAST, boolean)
* @see net.sourceforge.transmogrify.symtab.antlr.SymTabAST
*/
public void processClass(SymTabAST tree) {
String name = tree.findFirstToken(TokenTypes.IDENT).getText();
makeClass(name, tree);
final SymTabAST objblock =
tree.findFirstToken(TokenTypes.OBJBLOCK);
SymTabAST start = (SymTabAST)objblock.getFirstChild();
if (start != null) {
//skip LPAREN
if (start.getType() == TokenTypes.LPAREN) {
start = (SymTabAST)start.getNextSibling();
}
walkSiblings(start, false);
}
symbolTable.popScope();
}
/**
* creates <code>ClassDef</code> for the current class node and add it to the
* symbol table
* @param name name of the class
* @param tree current node to be processed
* @return <code>void</code>
* @see net.sourceforge.transmogrify.symtab.ClassDef
* @see net.sourceforge.transmogrify.symtab.SymbolTable
*/
public void makeClass(String name, SymTabAST tree) {
ClassDef def = new ClassDef(name, symbolTable.getCurrentScope(), tree);
def.addUnprocessedImports(imports);
symbolTable.defineClass(def);
symbolTable.pushScope(def);
}
/**
* processes anonymous inner class encountered in the tree
* @param objblock the anonymous block
* @param classExtended
* @return <code>void</code>
* @see net.sourceforge.transmogrify.symtab.AnonymousInnerClass
* @see net.sourceforge.transmogrify.symtab.SymbolTable
*/
public void processAnonymousInnerClass(SymTabAST objblock,
SymTabAST classExtended) {
ClassDef def = new AnonymousInnerClass(objblock,
classExtended,
symbolTable.getCurrentScope());
symbolTable.defineClass(def);
symbolTable.pushScope(def);
walkSiblings((SymTabAST)objblock.getFirstChild(), false);
symbolTable.popScope();
}
/**
* process the given SymTabAST as a variable definition
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see net.sourceforge.transmogrify.symtab.VariableDef
* @see net.sourceforge.transmogrify.symtab.SymbolTable
* @see net.sourceforge.transmogrify.symtab.antlr.SymTabAST
* @see #makeVariableDef(SymTabAST, Scope)
* @see #walkTree(SymTabAST, boolean)
*/
private void processVariableDef(SymTabAST tree) {
VariableDef def = makeVariableDef( tree, symbolTable.getCurrentScope() );
symbolTable.defineVariable(def);
SymTabAST assignmentNode
= tree.findFirstToken(TokenTypes.ASSIGN);
if (assignmentNode != null) {
walkTree((SymTabAST)assignmentNode.getFirstChild(), false);
}
}
/**
* creates <code>VariableDef</code> based on the current tree node and scope
* @param tree the current tree node
* @param scope the current scope
* @return <code>VariableDef</code>
* @see net.sourceforge.transmogrify.symtab.VariableDef
*/
public VariableDef makeVariableDef(SymTabAST tree, Scope scope) {
String name = tree.findFirstToken(TokenTypes.IDENT).getText();
VariableDef result = new VariableDef(name, scope, tree);
return result;
}
/**
* process the given SymTabAST as a try block
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see #makeBlock(SymTabAST)
* @see net.sourceforge.transmogrify.symtab.antlr.SymTabAST
* @see #walkTree(SymTabAST, boolean)
* @see #walkSiblings(SymTabAST, boolean)
*/
public void processTry(SymTabAST tree){
BlockDef block = makeBlock(tree);
SymTabAST slist = tree.findFirstToken(TokenTypes.SLIST);
SymTabAST everythingElse = (SymTabAST)slist.getNextSibling();
symbolTable.pushScope( block );
walkTree( slist, false );
symbolTable.popScope();
walkSiblings( everythingElse, false );
}
/**
* process the given SymTabAST as a finally block
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see #makeBlock(SymTabAST)
* @see #walkTree(SymTabAST, boolean)
*/
public void processFinally(SymTabAST tree){
BlockDef block = makeBlock(tree);
SymTabAST slist = tree.findFirstToken(TokenTypes.SLIST);
SymTabAST tryBlock = tree.findFirstToken(TokenTypes.LITERAL_TRY);
symbolTable.pushScope( block );
walkTree( slist, false );
symbolTable.popScope();
walkTree( tryBlock, false );
}
/**
* process the given SymTabAST as a method definition
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see net.sourceforge.transmogrify.symtab.MethodDef
* @see net.sourceforge.transmogrify.symtab.SymbolTable
* @see #walkTree(SymTabAST, boolean)
*/
public void processMethodDef(SymTabAST tree) {
String name = tree.findFirstToken(TokenTypes.IDENT).getText();
MethodDef method = new MethodDef(name, symbolTable.getCurrentScope(),
tree);
symbolTable.defineMethod( method );
symbolTable.pushScope( method );
walkTree(tree.findFirstToken(TokenTypes.SLIST), false);
symbolTable.popScope();
}
/**
* process the given SymTabAST as a constructor definition
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see net.sourceforge.transmogrify.symtab.MethodDef
* @see net.sourceforge.transmogrify.symtab.SymbolTable
* @see #walkTree(SymTabAST, boolean)
*/
public void processConstructorDef(SymTabAST tree) {
processMethodDef(tree);
}
/**
* process the given SymTabAST as a for block
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see #makeBlock(SymTabAST)
* @see #walkTree(SymTabAST, boolean)
*/
public void processFor(SymTabAST tree) {
BlockDef block = makeBlock(tree);
symbolTable.pushScope( block );
SymTabAST body;
SymTabAST forEach = tree.findFirstToken(TokenTypes.FOR_EACH_CLAUSE);
if (forEach != null) {
walkTree(forEach, false);
body = (SymTabAST)forEach.getNextSibling();
}
else {
walkTree(tree.findFirstToken(TokenTypes.FOR_INIT), false);
walkTree(tree.findFirstToken(TokenTypes.FOR_CONDITION), false);
SymTabAST forIter = tree.findFirstToken(TokenTypes.FOR_ITERATOR);
walkTree(forIter, false);
body = (SymTabAST)forIter.getNextSibling();
}
//handle Checkstyle grammar
if (body.getType() == TokenTypes.RPAREN) {
body = (SymTabAST) body.getNextSibling();
}
walkTree(body, false);
symbolTable.popScope();
}
/**
* process the given SymTabAST as an if block
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see #makeBlock(SymTabAST)
* @see #walkTree(SymTabAST, boolean)
* @see #processElse(SymTabAST)
*/
public void processIf(SymTabAST tree) {
BlockDef block = makeBlock(tree);
SymTabAST expr = tree.findFirstToken(TokenTypes.EXPR);
SymTabAST ifBranch = (SymTabAST)expr.getNextSibling();
// handle Checkstyle grammar
if (ifBranch.getType() == TokenTypes.RPAREN) {
ifBranch = (SymTabAST) ifBranch.getNextSibling();
}
SymTabAST elseBranch = (SymTabAST)ifBranch.getNextSibling();
// handle Checkstyle grammar
if ((elseBranch != null) && (elseBranch.getType() == TokenTypes.SEMI)) {
elseBranch = (SymTabAST) elseBranch.getNextSibling();
}
if ((elseBranch != null) && (elseBranch.getType() == TokenTypes.LITERAL_ELSE)) {
elseBranch = (SymTabAST) elseBranch.getFirstChild();
}
symbolTable.pushScope( block );
walkTree(expr, false);
walkTree(ifBranch, false);
symbolTable.popScope();
processElse(elseBranch);
}
/**
* process the given SymTabAST as an else block
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see #processIf(SymTabAST)
* @see #makeElseBlock(SymTabAST)
*/
public void processElse(SymTabAST tree) {
if (tree != null) {
if (tree.getType() == TokenTypes.LITERAL_IF) {
processIf(tree);
}
else {
makeElseBlock(tree);
}
}
}
/**
* defines an anonymous block to enclose the scope of an else block
*
* @param tree the SymTabAST to process
* @return <code>void</code>
* @see #makeBlock(SymTabAST)
* @see #walkTree(SymTabAST, boolean)
*/
public void makeElseBlock(SymTabAST tree) {
if (tree.getType() == TokenTypes.SLIST) {
BlockDef block = makeBlock(tree);
symbolTable.pushScope( block );
walkTree(tree, false);
symbolTable.popScope();
}
else {
walkTree(tree, false);
}
}
/**
* processes the current tree node as BlockDef
* @param tree current tree node
* @param makeAnonymousScopes
* @return <code>void</code>
*/
public void processBlock(SymTabAST tree, boolean makeAnonymousScopes) {
BlockDef block = makeBlock(tree);
symbolTable.pushScope(block);
//handle Checkstyle grammar
SymTabAST child = (SymTabAST)tree.getFirstChild();
if ((child != null) && (child.getType() == TokenTypes.LPAREN)) {
child = (SymTabAST) child.getNextSibling();
}
walkSiblings(child, makeAnonymousScopes);
symbolTable.popScope();
}
/**
* set the current file to the named file
*
* @param fileName the name of the file
* @return <code>void</code>
*/
public void setCurrentFile(String fileName) {
currentFile = new File(fileName);
symbolTable.setCurrentFile(currentFile);
}
/**
* creates a new <code> BlockDef </code> in the SymbolTable
*
* @param tree is a <code> SymTabAST </code> whose root begins the new block
* @return <code> BlockDef </code>
* @see net.sourceforge.transmogrify.symtab.BlockDef
* @see net.sourceforge.transmogrify.symtab.SymbolTable
*/
private BlockDef makeBlock( SymTabAST tree ) {
BlockDef block = new BlockDef( symbolTable.getCurrentScope(), tree );
symbolTable.defineBlock( block );
return block;
}
/**
* returns the <code>SymTabAST</code> that contains the parameter classDef's
* extends nodes
*
* @param classDef is a <code> ClassDef </code> whose extends nodes we want
* @return <code> SymTabAST </code>
*/
public static SymTabAST getExtendsNode(ClassDef classDef) {
SymTabAST result = null;
SymTabAST extendsClause = null;
SymTabAST classDefTreeNode = classDef.getTreeNode();
extendsClause =
classDefTreeNode.findFirstToken(TokenTypes.EXTENDS_CLAUSE);
if (extendsClause != null) {
result = (SymTabAST)(extendsClause.getFirstChild());
}
return result;
}
/**
* Superclass for different kind of XXXFinisher subclass
* @see CatchFinisher
* @see ClassFinisher
* @see DefinitionFinisher
* @see MethodFinisher
* @see VariableFinisher
*/
class DefinitionFinisher {
protected SymTabAST _node = null;
/**
* Constructor. It finishes the definition passed to it
*
*/
public DefinitionFinisher( Definition def ) {
_node = def.getTreeNode();
}
public void finish() throws SymbolTableException {}
/**
* gets the classDef that represents the type of the given definition
*
*
* @param def the definition whose type to find
* @param typeNode the TokenTypes.TYPE node associated with the def
*
* @return the resulting class definition
*/
protected IClass getType( Definition def, SymTabAST typeNode ) {
IClass result = null;
SymTabAST typeClassNode = null;
boolean isArray = false;
if ( typeNode.getFirstChild().getType()
== TokenTypes.ARRAY_DECLARATOR ) {
isArray = true;
typeClassNode = (SymTabAST)typeNode.getFirstChild().getFirstChild();
}
else {
typeClassNode = (SymTabAST)typeNode.getFirstChild();
}
Scope lookupScope = null;
if (def instanceof Scope) {
lookupScope = (Scope)def;
}
else {
lookupScope = def.getParentScope();
}
Resolver resolver = new Resolver(symbolTable);
IClass typeClass = resolver.resolveClass(typeClassNode, lookupScope, null, false);
if ( isArray ) {
result = new ArrayDef( typeClass );
}
else {
result = typeClass;
}
return result;
}
}
class ClassFinisher extends DefinitionFinisher {
private ClassDef _def = null;
/**
* Constructor. Creates a ClassFinisher from a <code> Definition </code>
*
* @param def is a <code> Definition </code>
*/
public ClassFinisher( Definition def ) {
super( def );
_def = (ClassDef)def;
}
/**
* Completes all tasks required for finishing a ClassDef
* Including adding imports, setting super classes and adding
* interfaces.
* @return <code>void</code>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -