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; } }
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()); } } } } }
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 << "}"; } }
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; }
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; }
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; } } } }