Beispiel #1
0
void EventEntry::print(ostream& out, int indent) const{
	if(name()!="any"){
		for(int i=0;i<indent;++i){
			out << "\t";
		}
		out << "event "<< name() << "(";
		const SymTab* st = this->symTab();
		if(st!=NULL){
			for(SymTab::const_iterator i = st->begin(); i != st->end();){
				if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){
					VariableEntry* ve = (VariableEntry*) (*i);
					if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR){
						out << ve->type()->fullName()<<" "<<ve->name();
						out << "(offset = " << ve->offSet() << ")";
					}
				}
				++i;
				if(i != st->end()){
					out << ", ";
				}
			}
		}
		out << ");"<<endl;
	}
}
Beispiel #2
0
void EventEntry::memAlloc(MemoryMgr &mm){
	memory_mgr_ = MemoryMgr();
	//cout << "Event memAlloc" << endl;
	SymTab* st = this->symTab();
	if(st!=NULL){
		for(SymTab::iterator i = st->begin(); i != st->end();++i){
			if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){
				VariableEntry* ve = (VariableEntry*) (*i);
				if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR){
					ve->offSet(memory_mgr_.getNextAddress());
				}
			}
		}
	}
}
Beispiel #3
0
Type* EventEntry::typeCheck(){
	vector<Type*>* arg_types = new vector<Type*>();

	SymTab* st = this->symTab();
	if(st!=NULL){
		for(SymTab::iterator i = st->begin(); i != st->end();++i){
			if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){
				VariableEntry* ve = (VariableEntry*) (*i);
				if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR){
					arg_types->push_back(ve->type());
				}
			}
		}
	}
	type()->argTypes(arg_types);
	return NULL;
}
/**
 * Function representing the <par_dec_list_prime> prods
 */
ParamList* RecursiveDescentParser::par_dec_list_prime(Type type) {
	ParamList* paramList = NULL;
	if(errorCondition) return paramList;
	if(token == TK_COMMA) 
	{
#if DEBUG_PARSER
		std::cout << "<par_dec_list_prime> --> ,<par_spec><par_dec_list_prime>\n";
#endif
		token = scanner->getToken();
		VariableEntry* ve = par_spec(type);
		ve->setParamFlag();
		
		if(!ve) {
			// error recovery: consume tokens until we find another comma or a semicolon
			while(token != TK_EOF) 
			{
				if(token == TK_LEFT_BRACE) {
					break;
				}
				if(token == TK_COMMA || token == TK_SEMICOLON) 
				{
					return par_dec_list_prime(type);
				} 
				token = scanner->getToken();
			}
			return new ParamList();
		}
		
		paramList = par_dec_list_prime(type);
		paramList->push_front(ve);
	} 
	else if(token == TK_SEMICOLON) 
	{
#if DEBUG_PARSER
		std::cout << "<par_dec_list_prime> --> e\n";
#endif
		paramList = new ParamList();
	}
	else 
	{	//errorHandler();
		errorHandler("missing semicolon at the end of parameter declaration", token);
	}
	
	return paramList;
}
void FunctionEntry::print(ostream& out, int indent) const
{

    out << type()->fullName() << " " << name();
    out << "(";


    int i = 0;
    const SymTab *st = symTab();
    if(st!=NULL)
    {

        SymTab::const_iterator it = st->begin();
        for (i=0; (it != st->end()); i++, ++it)
        {
            SymTabEntry *ste = (SymTabEntry *)(*it);
            if(ste->kind() == SymTabEntry::Kind::VARIABLE_KIND)
            {
                VariableEntry *ve = (VariableEntry *)ste;
                if(ve->varKind() != VariableEntry::VarKind::PARAM_VAR)
                {
                    break;
                }
            }
        }
    }
    if(i!=0)
    {
        printST(out, indent,'\0', '\0', false, 0, i);
    }
    out << ")";

    if((st != NULL && i < st->size()) || body())
    {
        out << " {";
        if(st != NULL && i < st->size())
            printST(out, indent,'\0', ';',true, i, st->size());
        if(body())
            body()->printWithoutBraces(out, indent);
        out << "}";
    }

}
Beispiel #6
0
void FunctionEntry::memAlloc(MemoryMgr &mm){
	memory_mgr_ = MemoryMgr();

	const SymTab* st = this->symTab();
	bool p_var = true;
	if(st!=NULL){
		for(SymTab::const_iterator i = st->begin(); i != st->end(); ++i){
			if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){
				VariableEntry* ve = (VariableEntry*) (*i);
				if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR && p_var){
					//Parameters
					ve->offSet(memory_mgr_.getNextAddress());
				} else {
					if(p_var){
						//Set control_link_ and return_address_
						returnLabel(memory_mgr_.getNextAddress());
						returnOffset(memory_mgr_.getNextAddress());
						controlLink(memory_mgr_.getNextAddress());
						p_var = false;
					}
					//Local variables declared in function
					ve->memAlloc(memory_mgr_);
				}
			}
		}
		if(p_var){
			returnLabel(memory_mgr_.getNextAddress());
			returnOffset(memory_mgr_.getNextAddress());
			controlLink(memory_mgr_.getNextAddress());
		}
	}
	if(body()!=NULL){
		body()->memAlloc(memory_mgr_);

		//Used for returning in case function reaches the end of its body without a return statement
		mem_reg_ = memory_mgr_.getNextRegister(true);
		memory_mgr_.addRegister(mem_reg_);
		label_reg_ = memory_mgr_.getNextRegister(true);
		memory_mgr_.addRegister(label_reg_);
		memory_mgr_.freeRegister(mem_reg_);
		memory_mgr_.freeRegister(label_reg_);
	}
}
/**
 * Function representing the <var> productions
 */
VariableEntry* RecursiveDescentParser::var() {
	VariableEntry* ve=NULL;
	
	if(errorCondition) return ve;
	
	if(token == TK_IDENTIFIER) 
	{
#if DEBUG_PARSER
		std::cout << "<var> --> i<var_prime>\n";
#endif
		TableEntry* te=NULL;
		if(!symTab.search(token, te)) 
		{			
			std::stringstream errorMsg;
			errorMsg << "Undeclared variable '" << token.getValue() << "'";
			errorHandler(errorMsg.str(), token);
		} 
		
		if(te && te->getEntryType()==TableEntry::VARIABLE) 
		{
			ve = (VariableEntry*)te;
 		}
		
		token = scanner->getToken();
		attr varP = var_prime(ve);
		
		if(ve && ve->getAttribute() == VA_ARRAY && varP.attrib == VA_SIMPLE) {
			VariableEntry* vEntry = new VariableEntry(ve->getType(), VA_SIMPLE);
			vEntry->setAddress( symTab.getNextAddress() );
			
			iCode.threeAddressCode(vEntry->getAttr(), TAC_ADDRESS_OF, ve->getAttr(), varP);
			ve = vEntry;
		}
	} 
	else 
	{
		errorHandler();
	}
	
	return ve;
}
Beispiel #8
0
void FunctionEntry::typePrint(ostream& out, int indent) const{
	for(int i=0;i<indent;++i){
		out << "\t";
	}
	out << type()->retType()->name() << " " << name() << "(";
	const SymTab* st = this->symTab();
	bool p_var = true;
	if(st!=NULL){
		for(SymTab::const_iterator i = st->begin(); i != st->end(); ++i){
			if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){
				VariableEntry* ve = (VariableEntry*) (*i);
				if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR && p_var){
					if(i != st->begin()){
						out << ", ";
					}
					out << ve->type()->fullName()<<" "<<ve->name();
				} else {
					if(p_var){
						out << ") {" << endl;
						p_var = false;
					}
					ve->print(out,indent+1);
				}
			}
		}
	}
	if(p_var){
		out << ")";
	}
	if(body()!=NULL){
		if(p_var){
			out<<" {" << endl;
		}
		body()->typePrintWithoutBraces(out,indent);
		for(int i=0;i<indent-1;++i){
			out << "\t";
		}
		out << "}";
	}
	out<< ";" << endl;
}
/**
 * Function representing the <par_spec> prods
 */
VariableEntry* RecursiveDescentParser::par_spec(Type type) {
	if(errorCondition) return NULL;
	
	if(token == TK_IDENTIFIER) 
	{	
#if DEBUG_PARSER
		std::cout << "<par_spec> --> i<par_spec_prime>\n";
#endif
		Token identifier = token;	
		token = scanner->getToken();
		
		VariableAttribute va = par_spec_prime();
		VariableEntry* paramList = new VariableEntry(type, va);
	
		if(symTab.search(identifier)) {
			// duplicate parameter name
			std::stringstream errorMsg;
			errorMsg << "Duplicate declaration for parameter '" << identifier.getValue() << "'";
			errorHandler(errorMsg.str(), identifier);
		} else {
			VariableEntry* entry = new VariableEntry(
					paramList->getType(),
					paramList->getAttribute(),
					paramList->getArraySize(),
					true
			);
			
			symTab.insert(identifier, entry);
		}
		
		return paramList;
	}
	else 
	{	//errorHandler();
		errorHandler("Missing variable name in parameter declaration", token);
	}
	
	return NULL;
}
/**
 * Function representing the <st_prime> productions
 */
void RecursiveDescentParser::st_prime(Type type) {
	if(errorCondition) return;
	if(token == TK_COMMA) 
	{
		token = scanner->getToken();
#if DEBUG_PARSER
		std::cout << "<st_prime> --> ,i<arr_spec><st_prime>\n";
#endif
		if(token!=TK_IDENTIFIER){
			// error
		}
		
		if(symTab.search(token)) {
			std::stringstream msg;
			msg << "Duplicate variable declaration '" << token.getValue() << "'";
			errorHandler(msg.str(), token);
		}
		
		VariableEntry* entry = new VariableEntry();
		entry->setType(type);
		symTab.insert(token, entry);
		
		token = scanner->getToken();
		VariableAttribute va = arr_spec();
		entry->setAttribute(va);
		st_prime(type);
	} 
	else if(token == TK_SEMICOLON) 
	{
#if DEBUG_PARSER
		std::cout << "<st_prime> --> e\n";
#endif
	}
	else
	{
		errorHandler();
	}
}
/**
 * Function representing the <oelem> productions
 */
attr RecursiveDescentParser::oelem(ParamList* &pList) {
	attr retVal;
	retVal.type = T_ERROR;
	VariableEntry* vEntry = NULL;
	
	if(errorCondition) return retVal;
	
	if(token == TK_IDENTIFIER)
	{
#if DEBUG_PARSER
		std::cout << "<oelem> --> <var>\n";
#endif
		vEntry = var();
	}
	else if(token == TK_NUM) 
	{
#if DEBUG_PARSER
		std::cout << "<oelem> --> n\n";
#endif
		//TODO fix memory leak here vEntry is never deleted
		vEntry = new VariableEntry(T_INT, VA_SIMPLE);
		vEntry->setAddress( symTab.getNextAddress() );
		
		std::string val = token.getValue();
		int litTabIndex = litTab.insert(atoi(val.c_str()));
		iCode.threeAddressCode(vEntry->getAttr(), TAC_NUM_CONST, litTabIndex);
		
		token = scanner->getToken();
	} 
	else if(token == TK_CHAR_CONST) 
	{
#if DEBUG_PARSER
		std::cout << "<oelem> --> 'c'\n";
#endif
		//TODO fix memory leak here vEntry is never deleted
		vEntry = new VariableEntry(T_CHAR, VA_SIMPLE);
		vEntry->setAddress( symTab.getNextAddress() );
		
		std::string val = token.getValue();
		int litTabIndex = litTab.insert(val[1]);
		iCode.threeAddressCode(vEntry->getAttr(), TAC_CHAR_CONST, litTabIndex);
		
		token = scanner->getToken();
	}
	else 
	{
		errorHandler();
	}
	
	if(vEntry) {
		pList->push_back(vEntry);
		retVal = vEntry->getAttr();
	}
	
	return retVal;
}
Beispiel #12
0
CodeBlock* FunctionEntry::codeGen() {
	if(body()!=NULL){

		CodeBlock* func_block = new CodeBlock();
		func_block->setStartLabel(func_start_);
		func_block->append(body()->codeGen());

		const SymTab* st = this->symTab();
		if(st!=NULL){
			for(SymTab::const_iterator i = st->begin(); i != st->end(); ++i){
				if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){
					VariableEntry* ve = (VariableEntry*) (*i);
					if(ve->varKind()!=VariableEntry::VarKind::PARAM_VAR){
						func_block->append(ve->codeGen());
					}
				}
			}
		}

		CodeBlock* func_end = new CodeBlock();

		//Loads label from memory
		ICode lab_addr(ICode::ICodeType::ADD,&MemoryMgr::basePointerRegister(),new Value(returnLabel(),Type::TypeTag::UINT),&mem_reg_);
		ICode load_lab(ICode::ICodeType::LDI,&mem_reg_,&label_reg_);
		ICode ret_jmp(ICode::ICodeType::JMPI,&label_reg_);

		func_end->append(lab_addr);
		func_end->append(load_lab);
		func_end->append(ret_jmp);

		func_block->append(func_end);

		return func_block;
	}
	return NULL;
}
/**
 * Function representing the <st_factor_ident> prods
 */
void RecursiveDescentParser::st_factor_ident(TableEntry* te) {
	if(errorCondition) return;
	if(token == TK_LEFT_PARENTHESES) 
	{
#if DEBUG_PARSER
		std::cout << "<st_factor_ident> --> (<o_list>);\n";
#endif
		Token leftParen = token;
		token = scanner->getToken();
		ParamList* pList = o_list();
		
		if(te) {
			if(te->getEntryType()!=TableEntry::FUNCTION) {
				std::stringstream errorMsg;
				errorMsg << "'" << te->getName() << "' is not a function";
				errorHandler(errorMsg.str(), leftParen);
			} else {
				// now makes sure the lists match
				FunctionEntry* fe = (FunctionEntry*)te;
				if(pList) matchParameters(fe, pList, leftParen);
				
				iCode.threeAddressCode(TAC_PARAM, pList);
				iCode.threeAddressCode( 
						symTab.getNextAddress(), // throw away temporary
						TAC_CALL, 
						fe->getLabel(), 
						fe->getParamCount()
					);
			}
		} else {
			std::stringstream errorMsg;
			errorMsg << "Undeclared function";
			errorHandler(errorMsg.str(), leftParen);
		}
		
		match(TK_RIGHT_PARENTHESES);
		match(TK_SEMICOLON);
	} 
	else if(token == TK_LEFT_BRACKET || 
			token == TK_ASSIGNMENT) 
	{
#if DEBUG_PARSER		
		std::cout << "<st_factor_ident> --> <var_prime>=<exp>;\n";
#endif
		VariableEntry* vEntry = (VariableEntry*)te;
		Token startToken = token;
		
		attr varAttr  = var_prime(vEntry);
		match(TK_ASSIGNMENT);
		attr expAttr = exp();
		
		if(expAttr.type != varAttr.type) {
			std::stringstream errorMsg;
			errorMsg << "Type mismatch variable '" << vEntry->getName() << "'";
			errorHandler(errorMsg.str(), startToken);
		}
		
		if(varAttr.attrib == VA_ARRAY) {
			std::stringstream errorMsg;
			errorMsg << "Assignment error, array '" << vEntry->getName() << "' must be indexed.";
			errorHandler( errorMsg.str(), startToken );
		}
		
		if(vEntry->getAttribute() == VA_ARRAY) {
			//                       array addr                           value to assign   index
			iCode.threeAddressCode(vEntry->getAttr(), TAC_ASSIGN_TO_ADDRESS_AT, expAttr, varAttr);
		} else {
			iCode.threeAddressCode(vEntry->getAttr(), TAC_ASSIGN, expAttr);
		}
		
		match(TK_SEMICOLON);
	} 
	else 
	{
		errorHandler();
	}
}
/**
 * Functions representing the <st> productions
 */
void RecursiveDescentParser::st() {
	if(token == TK_SEMICOLON) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> ;\n";
#endif
		token = scanner->getToken();
	} 
	else if(token == TK_LEFT_BRACE) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> <comp_st>\n";
#endif
		comp_st();
	}
	else if(token == TK_IF) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> if<log_exp><st>else<st>\n";
#endif
		token = scanner->getToken();
		
		attr logExp = log_exp();
		
		std::string lbl1 = iCode.getNextLabel();
		iCode.threeAddressCode(TAC_IF_FALSE, logExp, lbl1);

		st();
		
		std::string lbl2 = iCode.getNextLabel();
		iCode.threeAddressCode(TAC_GOTO, lbl2);
		
		match(TK_ELSE);
		
		iCode.threeAddressCode(lbl1);
		
		st();
		
		iCode.threeAddressCode(lbl2);
	} 
	else if(token == TK_WHILE) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> while<log_exp><st>\n";
#endif
		token = scanner->getToken();
		
		std::string lbl1 = iCode.getNextLabel();
		iCode.threeAddressCode(lbl1);
		std::string lbl2 = iCode.getNextLabel();
		
		attr cond = log_exp();
		
		iCode.threeAddressCode(TAC_IF_FALSE, cond, lbl2);
		
		st();
		
		iCode.threeAddressCode(TAC_GOTO, lbl1);
		iCode.threeAddressCode(lbl2);
	}
	else if(token == TK_RETURN) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> return(<exp>);\n";
#endif
		Token sToken = token;
		token = scanner->getToken();
		
		match(TK_LEFT_PARENTHESES);
		attr expAttr = exp(); 

		const FunctionEntry* fe = symTab.getCurrentFunction();
		if(expAttr.type != fe->getReturnType() && fe->getReturnType() != T_VOID) {
			std::stringstream ss;
			ss << "Type Mismatch, function '" << fe->getName() << "' must return ";
			if(fe->getReturnType() == T_INT) ss << "an integer";
			if(fe->getReturnType() == T_CHAR) ss << "a character";
			errorHandler(ss.str(), sToken);
		}
		
		match(TK_RIGHT_PARENTHESES);
		match(TK_SEMICOLON);
		iCode.threeAddressCode(TAC_SAVE_RET_VAL, expAttr);
		iCode.threeAddressCode(TAC_GOTO, currentReturnLabel);
	}
	else if(token == TK_SCANF) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> scanf<i_list>;\n";
#endif

		token = scanner->getToken();
		ParamList* pList = i_list();
		match(TK_SEMICOLON);
		
		iCode.threeAddressCode(TAC_READ, pList);
	}
	else if(token == TK_PRINTF) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> printf<o_list>;\n";
#endif

		token = scanner->getToken();
		ParamList* pList = o_list();
		match(TK_SEMICOLON);
		
		iCode.threeAddressCode(TAC_WRITE, pList);
	}
	else if(token == TK_IDENTIFIER) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> i<st_factor_ident>\n";
#endif
		TableEntry* te=NULL;
		if(!symTab.search(token, te)) {
			errorHandler("Undefined identifier", token);
		}
		token = scanner->getToken();
		st_factor_ident(te);
	}
	else if(token == TK_INT)  
	{
#if DEBUG_PARSER
		std::cout << "<st> --> int i <st_factor_type>\n";
#endif
		token = scanner->getToken();
		if(token!=TK_IDENTIFIER) {
			errorHandler();
		}		
		if(symTab.search(token) ) {
			std::stringstream msg;
			msg << "Duplicate variable declaration '" << token.getValue() << "'";
			errorHandler(msg.str(), token);
		} 
		
		VariableEntry* vEntry = new VariableEntry();
		vEntry->setType(T_INT);
		vEntry->setName( token.getValue() );
		//std::string varName = token.getValue();
		
		
		token = scanner->getToken();
		st_factor_type(vEntry);
		
		//symTab.insert(varName, vEntry);
	}
	else if(token == TK_CHAR) 
	{
#if DEBUG_PARSER
		std::cout << "<st> --> char i <st_factor_type>\n";
#endif
		token = scanner->getToken();
		if(token!=TK_IDENTIFIER) {
			errorHandler();
		}

		if(symTab.search(token)) {
			// aready declared in this scope
			std::stringstream msg;
			msg << "Duplicate variable declaration '" << token.getValue() << "'";
			errorHandler(msg.str(), token);
		}

		VariableEntry* vEntry = new VariableEntry();
		vEntry->setType(T_CHAR);
		vEntry->setName( token.getValue() );
		//std::string varName = token.getValue();
		
		token = scanner->getToken();
		st_factor_type(vEntry);
		
		//symTab.insert(varName, vEntry);
	}
	else 
	{
		errorHandler();
	}
	
	if(errorCondition) {
		while(token!=TK_EOF) {
			token = scanner->getToken();
			if(token==TK_RIGHT_BRACE) {
				errorCondition=false;
				break;
			}
			if(token==TK_SEMICOLON) {
				errorCondition=false;
				token = scanner->getToken();
				break;
			}
		}
	}
}