📄 symboltable.java
字号:
package CatDecaf.SymTable;
import java.util.*;
import CatDecaf.IR.*;
public class SymbolTable{
private LinkedHashMap descriptorTable;
private SymbolTable parent;
private ArrayList childBlock; //list of symbol tables of child blocks
// only applicable to method's local var symbol table
private boolean paramST, fieldST, methodST; //whether this is a ST of fields or method's params
private int symbolTableSize;
public SymbolTable(){
descriptorTable = new LinkedHashMap();
parent = null;
childBlock = new ArrayList();
}
public void assertParamST(){
paramST = true;
}
public void assertFieldST(){
fieldST = true;
}
public boolean isFieldST(){
return fieldST;
}
public boolean isParamST(){
return paramST;
}
public void assertMethodST(){
methodST = true;
}
public boolean isMethodST(){
return methodST;
}
public int getSymbolTableSize(){
return this.symbolTableSize;
}
public void setSymbolTableSize(int s){
this.symbolTableSize = s;
}
public LinkedHashMap getDescriptorTable(){
return descriptorTable;
}
public static String getTypeName(int type){
if(type == parser.sym.INT) return "int";
if(type == parser.sym.BOOLEAN) return "boolean";
if(type == parser.sym.VOID) return "void";
return "Error: unknown Decaf type!!";
}
/*public int lookup_var(String id){
Object o = descriptorTable.get(id);
if(o != null){
int type = ((Descriptor)o).getType();
if( ((IDDescriptor)o).isArrayType()){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": index missing; '" + id + "' declared as an array of " + getTypeName(type));
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}
return type;
}
if(parent != null) return parent.lookup_var(id);
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' used before declaration");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}*/
public IDDescriptor lookup_var(String id){
Object o = descriptorTable.get(id);
if(o != null){
int type = ((Descriptor)o).getType();
if( ((IDDescriptor)o).isArrayType()){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": index missing; '" + id + "' declared as an array of " + getTypeName(type));
ClassProgram.numOfError++;
return new IDDescriptor(id, parser.sym.ERROR_TYPE);
}
return (IDDescriptor)o;
}
if(parent != null) return parent.lookup_var(id);
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' used before declaration");
ClassProgram.numOfError++;
return new IDDescriptor(id, parser.sym.ERROR_TYPE);//return parser.sym.ERROR_TYPE;
}
/*public int lookup_array(String id, int loc){
Object o = descriptorTable.get(id);
if(o != null){
if( ((IDDescriptor)o).isArrayType()){
int size = ((IDDescriptor)o).getArraySize();
if(loc >= 0 && loc < size) return ((Descriptor)o).getType();
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' array out of bound");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' has not been declared as an array");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}
if(parent != null) return parent.lookup_array(id, loc);
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' used before declaration");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}*/
public IDDescriptor lookup_array(String id, int loc){
Object o = descriptorTable.get(id);
if(o != null){
if( ((IDDescriptor)o).isArrayType()){
int size = ((IDDescriptor)o).getArraySize();
if(loc >= 0 && loc < size)
return (IDDescriptor)o;
//return ((Descriptor)o).getType();
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' array out of bound");
ClassProgram.numOfError++;
return new IDDescriptor(id, parser.sym.ERROR_TYPE);
}
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' has not been declared as an array");
ClassProgram.numOfError++;
return new IDDescriptor(id, parser.sym.ERROR_TYPE);
}
if(parent != null) return parent.lookup_array(id, loc);
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + id + "' used before declaration");
ClassProgram.numOfError++;
return new IDDescriptor(id, parser.sym.ERROR_TYPE);
}
public int lookup_method(String id, ExpList el){
Object o = descriptorTable.get(id); // o: method descriptor for method with name "id"
if(o == null){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": no method '" + id + "' defined");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}
SymbolTable paramVar = ((MethodDescriptor)o).getParam(); //paramVar: a symbol table of parameters
Iterator i = paramVar.getDescriptorTable().values().iterator();
while(i.hasNext() && el != null){
int type = ((IDDescriptor)i.next()).getType();
if ( type != el.exp_.getType()){
//System.out.println("Param: " + getTypeName(type) + " ,exp: " + getTypeName(el.exp_.getType()));
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": parameter mismatch, bad method call to '" + ((MethodDescriptor)o).getMethodSignature() + "' ");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}
el = el.expList_;
}
if(i.hasNext() || el != null){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": parameter mismatch, bad method call to '" + ((MethodDescriptor)o).getMethodSignature() + "' ");
ClassProgram.numOfError++;
return parser.sym.ERROR_TYPE;
}
return ((MethodDescriptor)o).getType();
}
public MethodDescriptor lookup_methodDescriptor(String id, ExpList el){
Object o = descriptorTable.get(id); // o: method descriptor for method with name "id"
if(o == null){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": no method '" + id + "' defined");
ClassProgram.numOfError++;
return new MethodDescriptor(id, parser.sym.ERROR_TYPE);
}
SymbolTable paramVar = ((MethodDescriptor)o).getParam(); //paramVar: a symbol table of parameters
Iterator i = paramVar.getDescriptorTable().values().iterator();
while(i.hasNext() && el != null){
int type = ((IDDescriptor)i.next()).getType();
if ( type != el.exp_.getType()){
//System.out.println("Param: " + getTypeName(type) + " ,exp: " + getTypeName(el.exp_.getType()));
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": parameter mismatch, bad method call to '" + ((MethodDescriptor)o).getMethodSignature() + "' ");
ClassProgram.numOfError++;
return new MethodDescriptor(id, parser.sym.ERROR_TYPE);
}
el = el.expList_;
}
if(i.hasNext() || el != null){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": parameter mismatch, bad method call to '" + ((MethodDescriptor)o).getMethodSignature() + "' ");
ClassProgram.numOfError++;
return new MethodDescriptor(id, parser.sym.ERROR_TYPE);
}
return (MethodDescriptor)o;
}
/*while(el != null)
{
el.exp_.type;
el = el.expList_;
}*/
public boolean checkIfMainExists(){ //only applicable to Symbol Table of MethodDescriptors
boolean foundMain = false;
/*Iterator i = descriptorTable.values().iterator();
while(i.hasNext()){
String name = ((MethodDescriptor)i.next()).getName();
if(name.equals("main")){
foundMain = true; continue;
}
if(foundMain){
}
}*/
foundMain = descriptorTable.containsKey("main");
if(!foundMain){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": 'main()' method declaration not found");
ClassProgram.numOfError++;
}
return foundMain;
}
public void addDescriptor(Descriptor d){
String name = d.getName();
if(descriptorTable.containsKey(name)){
if(this.isMethodST())
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": '" + ((MethodDescriptor)descriptorTable.get(name)).getMethodSignature() + "' already defined in class Program");
else System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": identifier '" + name + "' already declared");
ClassProgram.numOfError++;
}else if(parent != null && (parent.isParamST() || this.isMethodST()) && (parent.getDescriptorTable()).containsKey(name)){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": identifier '" + name + "' already declared");
ClassProgram.numOfError++;
}else{
if(this.isMethodST()){
if(descriptorTable.containsKey("main")){
System.err.println(parser.parser.infile+":" + parser.Scanner.lineno + ": WARNING method '" + ((MethodDescriptor)d).getMethodSignature() + "' defined after '" + ((MethodDescriptor)descriptorTable.get("main")).getMethodSignature() + "', can never be reached");
ClassProgram.numOfWarning++;
}
}
descriptorTable.put(name, d);
}
}
public void addChild(SymbolTable s){
childBlock.add(s);
}
public ArrayList getChildren(){
return childBlock;
}
public void pPrint(){
//System.out.println(descriptorTable);
Iterator i = descriptorTable.values().iterator();
//ClassProgram.scope++;
if(i.hasNext()) {
Descriptor d = (Descriptor)i.next();
if(this.isFieldST()) System.out.println("\nField Descriptors: ");
else if(this.isParamST()) System.out.println("\nParam Descriptors: ");
else {
if(d instanceof MethodDescriptor) System.out.print("\n\nMethod Descriptors: ");
else if(d instanceof IDDescriptor) System.out.println("Local Variable Descriptors: ");
else System.err.println("Error: Unknown Descriptor");
}
//System.out.print("Scope: " + ClassProgram.scope + " " + ClassProgram.indent);
System.out.print(ClassProgram.indent);
d.pPrint();
}
while(i.hasNext()){
((Descriptor)i.next()).pPrint();
}
//ClassProgram.scope--;
i = childBlock.iterator();
ClassProgram.scope++;
while(i.hasNext()){
System.out.print("\n---------------------\n");
ClassProgram.indent += " ";
((SymbolTable)i.next()).pPrint();
ClassProgram.indent = ClassProgram.indent.substring(5);
}
ClassProgram.scope--;
if(this.isFieldST()) System.out.println("\nGlobal size: " + this.symbolTableSize);
}
public void setParent(SymbolTable p){
parent = p;
}
public SymbolTable getParent(){
return parent;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -