⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symboltable.java

📁 用Java实现的编译器。把源代码编译成SPARC汇编程序
💻 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 + -