//File parser.cpp #include #include #include #include #include "parser.h" #include "TokFiler.h" #include "QuadList.h" #include "QuadFiler.h" #include "FileManager.h" #include "Token.h" #include "pmglobs.h" #include "intstack.h" #include "idDescTab.h" #include "funcTab.h" #include "Quad.h" void parser::distributeProgName(char* pName) { pf.storeFileName(pName); char *tokenPtr = new char[strlen(pName) + 1]; char *ptr1 = new char[strlen(pName) + 1]; char *quadPtr = new char[strlen(pName) + 1]; char *ptr2 = new char[strlen(pName) + 1]; strcpy(tokenPtr, pName); ptr1 = strtok(tokenPtr, "."); strcat(ptr1, ".tok"); tf.storeFileName(ptr1); strcpy(quadPtr, pName); ptr2 = strtok(quadPtr, "."); strcat(ptr2, ".quad"); qf.store(ptr2); cout << "in distributeProgramName, ptr2 == " << ptr2 << endl; } void parser::emitallQuads() { int i; Quadruple q; QuadList* p=qlist; int seg=0; while (p!=NULL) { for (i=0; iquadSeg[i].oper!=0) { q=p->quadSeg[i]; qf.emitQuad(q); } // end of if. } // end of for. p=p->next; seg++; } // end of while. } parser::parser() { s.push(bottommark); Quadnum=1; linenumber=0; level=0; vcntprime=0; varcnt=0; localtempsmax=0; varmax=BASE; startaddrforglobaltemps=BASE; startaddrforlocaltemps=0; qlist= new QuadList; null.setClass(RESERVED); //RESERVED==0 null.setValue(0); fattribs.pcnt=0; } void parser::error(unsigned int n,unsigned int line) { cout<<"\n\nERROR #"<enterQuad(Quadnum,q); Quadnum++; } void parser::createASSIGNQuad() { Token opnd1,opnd2; int type1,type2,level1,level2,val; attributes attribs2; bool func1,func2,declared; getopndinfo(opnd1,level1,type1,func1); if (opnd1.getClass()==IDENTIFIER && func1) //return from funccall error(84,linenumber); // is tempclass getopndinfo(opnd2,level2,type2,func2); if (level2==0 && func2) error(84,linenumber); if (type1!=type2) { cout << "In createASSIGNQuad, type1== " << type1 << " type2 == " << type2 << endl; error(82,linenumber); } if (level1==0 && opnd1.getClass()==IDENTIFIER) { val=opnd1.getValue()+LEVELOADDRSHIFT; opnd1.setValue(val); } if (level2==0 && opnd2.getClass()==IDENTIFIER) { val=opnd2.getValue()+LEVELOADDRSHIFT; opnd2.setValue(val); }; Quadruple q; q.setQuad(assignop,opnd1,null,opnd2.getValue()); qlist->enterQuad(Quadnum,q); Quadnum++; freetempaddrs(); } void parser::createARITHQuad(int oper) { Token opnd1,opnd2; int type1,type2,level1,level2,val; bool func1,func2; getopndinfo(opnd1,level1,type1,func1); if (opnd1.getClass()==IDENTIFIER && func1) error(84,linenumber); getopndinfo(opnd2,level2,type2,func2); if (opnd2.getClass()==IDENTIFIER && func2) error(84,linenumber); if (type1!=1 || type2!=1) //both opnds must be of type INTEGER error(83,linenumber); int tempaddr=alloctempaddr(); qs.push(tempaddr); //addr for temp already adjusted for level qs.push(1); //temp type is INTEGER qs.push(tempclass); if (level1==0 && opnd1.getClass()==IDENTIFIER) { val=opnd1.getValue()+LEVELOADDRSHIFT; opnd1.setValue(val); } if (level2==0 && opnd2.getClass()==IDENTIFIER) { val=opnd2.getValue()+LEVELOADDRSHIFT; opnd2.setValue(val); } Quadruple q; q.setQuad(oper,opnd1,opnd2,tempaddr); qlist->enterQuad(Quadnum,q); Quadnum++; freetempaddrs(); } void parser::createBOOLQuad() { Token opnd1,opnd2; int type1,type2,level1,level2,val; bool func1,func2; getopndinfo(opnd1,level1,type1,func1); if (opnd1.getClass()==IDENTIFIER && func1) error(84,linenumber); int Quadoper=qs.pop() ; getopndinfo(opnd2,level2,type2,func2); if (opnd2.getClass()==IDENTIFIER && func2) error(84,linenumber); if (type1!=1 || type2!=1) //both opnds must be of type INTEGER error(83,linenumber); int tempaddr=alloctempaddr(); qs.push(tempaddr); //addr for ternp already adjusted for level qs.push(2); //temp type is BOOLEAN qs.push(tempclass); if (level1==0 && opnd1.getClass()==IDENTIFIER) { val=opnd1.getValue()+LEVELOADDRSHIFT; opnd1.setValue(val); }; if (level2==0 && opnd2.getClass()==IDENTIFIER) { val=opnd2.getValue()+LEVELOADDRSHIFT; opnd2.setValue(val); }; Quadruple q; q.setQuad(Quadoper,opnd1,opnd2,tempaddr); qlist->enterQuad(Quadnum,q); Quadnum++; freetempaddrs(); } void parser::createANDQuad() { // added later, need more work. Token opnd; int type,level1,val; bool func; int ANDoper=qs.pop(); getopndinfo(opnd,level1,type,func); if (opnd.getClass()==IDENTIFIER && func) error(84,linenumber); if (type!=2) error(85,linenumber); int tempaddr=alloctempaddr(); qs.push(tempaddr); qs.push(2); qs.push(tempclass); if (level1==0 && opnd.getClass()==IDENTIFIER) { val=opnd.getValue()+LEVELOADDRSHIFT; opnd.setValue(val); }; Quadruple q; q.setQuad(ANDoper,opnd,null,tempaddr); qlist->enterQuad(Quadnum,q); Quadnum++; freetempaddrs(); } void parser::createNOTQuad() { Token opnd; int type,level1,val; bool func; int NOToper=qs.pop(); getopndinfo(opnd,level1,type,func); if (opnd.getClass()==IDENTIFIER && func) error(84,linenumber); if (type!=2) error(85,linenumber); int tempaddr=alloctempaddr(); qs.push(tempaddr); qs.push(2); qs.push(tempclass); if (level1==0 && opnd.getClass()==IDENTIFIER) { val=opnd.getValue()+LEVELOADDRSHIFT; opnd.setValue(val); }; Quadruple q; q.setQuad(NOToper,opnd,null,tempaddr); qlist->enterQuad(Quadnum,q); Quadnum++; freetempaddrs(); }; void parser::createODDQuad() { Token opnd; int type,level1,val; bool func; int ODDoper=qs.pop(); getopndinfo(opnd,level1,type,func); if (opnd.getClass()==IDENTIFIER && func) error(84,linenumber); if (type!=1) //argument of ODD must be of type INFEGER error(8l,linenumber); int tempaddr=alloctempaddr(); qs.push(tempaddr); qs.push(2); qs.push(tempclass); if (level1==0 && opnd.getClass()==IDENTIFIER) { val=opnd.getValue()+LEVELOADDRSHIFT; opnd.setValue(val); }; Quadruple q; q.setQuad(ODDoper,opnd,null,tempaddr); qlist->enterQuad(Quadnum,q); Quadnum++; freetempaddrs(); } void parser::createJUMPQuad(int oper) { Token opnd; int type,level1,val; bool func; Quadruple q; if (oper==BF) { getopndinfo(opnd,level1,type,func); if (opnd.getClass()==IDENTIFIER && func) error(84,linenumber); if (level1==0 && opnd.getClass()==IDENTIFIER) { val=opnd.getValue()+LEVELOADDRSHIFT; opnd.setValue(val); }; q.setQuad(BF,opnd,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; } else { q.setQuad(B,null,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; } } void parser::createfuncASPQuad() { //used only at beginning of func Token opnd; opnd.setClass(NUMBER); opnd.setValue(-localtempsmax); Quadruple q; q.setQuad(ASP,opnd,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; } void parser::createfuncFSPQuad() { Token opnd; opnd.setClass(NUMBER); opnd.setValue(-localtempsmax); Quadruple q; q.setQuad(FSP,opnd,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; } void parser::createRTNQuad() { Quadruple q; q.setQuad(RTN,null,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; } void parser::createHALTQuad() { Quadruple q; q.setQuad(haltop,null,null,EMPTY); qlist->enterQuad(Quadnum,q); } void parser::savePROGinfo() { //cout << "In parser::savePROGinfo(), qs stack is: "; qs.display(); int temp=qs.pop(); if (temp==identclass) { int idinx=qs.pop(); bool duplicate=iddt.createEntry(idinx,level); if (duplicate) error(70,linenumber); //cannot have duplicate at this juncture iddt.saveLevel(idinx,0); iddt.saveAddr(idinx,NILADDR); iddt.saveType(idinx,0); } else cout<<"\nPROBLEM in savePROGinfo()!!!\n"; } void parser::saveVARinfo() { int ternp,addr; int type=qs.pop(); for (int k=vcnt+vcntprime; k>vcntprime; k--) { temp=qs.pop(); if (temp==IDENTIFIER) { int idinx=qs.pop(); bool duplicate=iddt.createEntry(idinx,level); if (duplicate) error(70,linenumber); iddt.saveLevel(idinx,level); iddt.saveType(idinx,type); if (level==1) { addr=-k; localmax--; } else if (level==0) { addr=k+BASE; } iddt.saveAddr(idinx,addr); } else cout<<"\nPROBLEM in saveVARinfo!!!\n"; } // end of for loop. vcntprime+=vcnt; vcnt=0; if (level==0) { varcnt=vcntprime; varmax=varcnt+BASE; startaddrforglobaltemps=varmax; } else if (level==1) { startaddrforlocaltemps=localmax; } } void parser::saveFUNCinfo() { int idinx; bool declared; int type=qs.pop(); /*int temPP=*/ qs.pop(); //throw away the class (i.e., identifier) int idinxp=qs.pop(); ft.createEntry(idinxp); ft.savePcnt(idinxp,pcnt); if (pcnt>10) error(100,linenumber); for (int i=i; i<=pcnt; i++) { temp=qs.pop(); idinx=qs.pop(); iddt.saveAddr(idinx,6+i); declared=iddt.retriveAttributes(idinx,attribs); if (!declared) error(71,linenumber); ft.saveType(idinxp,pcnt-i+1,attribs.type); } int Quadnumber=qs.pop(); ft.saveQnum(idinxp,Quadnumber); level=0; bool duplicate=iddt.createEntry(idinxp,level); if (duplicate) error(70,linenumber); iddt.saveLevel(idinxp,level); iddt.saveAddr(idinxp,NILADDR); //no level 0 addr for func iddt.saveType(idinxp,type); iddt.saveKind(idinxp,true); level=1; duplicate=iddt.createEntry(idinxp,level); if (duplicate) error(70,linenumber); iddt.saveLevel(idinxp,level); iddt.saveAddr(idinxp,6); iddt.saveType(idinxp,type); iddt.saveKind(idinxp,true); } void parser::FORMALparam() { int type=qs.pop(); temp=qs.pop(); int idinx=qs.pop(); int tempp=qs.pop(); int idinxp=qs.pop(); if (temp==IDENTIFIER && tempp==IDENTIFIER) { pcnt++; bool duplicate=iddt.createEntry(idinx,level); if (duplicate) error(70,linenumber); iddt.saveLevel(idinx,level); iddt.saveType(idinx,type); qs.push(idinx); qs.push(temp); qs.push(idinxp); qs.push(tempp); } else cout<<"\nPROBLEM in FORMALparam!!!\n"; } void parser::ACTUALparam() { Token opnd; int type1,type2,level1; bool func; getopndinfo(opnd,level1,type2,func); if (opnd.getClass()==IDENTIFIER && func) //return from funccall error(84,linenumber); //is teinpclass pcnt=qs.pop(); pcnt++; temp=qs.pop(); int idinx=qs.pop(); ft.retrieveFAttributes(idinx,fattribs); type1=fattribs.type[pcnt]; if (type1!=type2) error(87,linenumber); if (level1 == 0 && opnd.getClass() == IDENTIFIER) { int val=opnd.getValue()+LEVELOADDRSHIFT; opnd.setValue(val); } Quadruple q; q.setQuad(PSH,opnd,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; qs.push(idinx); qs.push(temp) ; qs.push(pcnt); } void parser::Fcallret() { pcnt=qs.pop(); temp=qs.pop(); int idinx=qs.pop(); ft.retrieveFAttributes(idinx,fattribs); cout << "in Fcallret(), fattribs.pcnt == " << fattribs.pcnt << " pcnt == " << pcnt << endl; if (fattribs.pcnt!=pcnt) //checks for correct # of params error(86,linenumber); Token opnd2; opnd2.setClass(NUMBER); opnd2.setValue(1); Quadruple q; q.setQuad(ASP,opnd2,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; q.setQuad(JSR,null,null,fattribs.qnum); qlist->enterQuad(Quadnum,q); Quadnum++; int tempaddr=alloctempaddr(); qs.push(tempaddr); iddt.retriveAttributes(idinx,attribs); //throw away boolean "declared" if (!attribs.func) error(88,linenumber); if (attribs.type==1) qs.push(1); //temp type is INTEGER else if (attribs.type==2) qs.push(2); //temp type is BOOLEAN qs.push(TEMP); q.setQuad(POP,null,null,tempaddr); qlist->enterQuad(Quadnum,q); Quadnum++; if (pcnt>0) { opnd2.setClass(NUMBER); opnd2.setValue(pcnt); q.setQuad(FSP,opnd2,null,EMPTY); qlist->enterQuad(Quadnum,q); Quadnum++; } } void parser::Tokensequence() { tf.retrieveTokenFile(); Token tok; intconst intok; int stacksymbol; int qnumsaved,idinx,intliteral; bool endparse=false; cout<<"\n"; s.push(program); tok=tf.getNextToken(); while (!endparse) { while (tok.getClass()==NEWLINE) { linenumber++; tok=tf.getNextToken(); } intok=getintok(tok); stacksymbol=s.pop() ; switch (stacksymbol) { //nonterminals case program:if (intok==PROGRAMrw) { // 1 s.push(haltop); s.push(period); s.push(ident); s.push(body); s.push(setlevel0); s.push(repair0); s.push(funcs); s.push(decs); s.push(qnum); s.push(B); s.push(heading); cout << "case program, s stack ==\n"; s.display(); } else error(10,linenumber); break; case heading: if (intok==PROGRAMrw) {// 2 s.push(semicolon); s.push(saveproginfo); s.push(ident); cout << "case heading, s stack ==\n"; s.display(); tok=tf.getNextToken(); } else error(11,linenumber); break; case decs: switch (intok) { case DECLARErw: s.push(moredeclists); // 4 s.push(declist); s.push(initdecs); tok=tf.getNextToken(); break; case FUNCTIONrw: case BEGINrw: break;//do nothing 5 default: error(13,linenumber); } // end of local switch. break; case moredeclists:switch(intok) { case idTOK: s.push(moredeclists); //6 s.push(declist); break; case FUNCTIONrw: case BEGINrw: break;//do nothing 7 default: error(14,linenumber); } // end of local switch. break; case declist: if (intok==idTOK) { //8 s.push(savevarinfo); s.push(semicolon); s.push(type); s.push(colon); s.push(identlist); } else error(15,linenumber); break; case identlist: if (intok==idTOK) { // 9 s.push(moreidents); s.push(ident); s.push(incvcnt); } else error(16,linenumber); break; case moreidents:switch (intok) { case commaTOK: s.push(identlist); // 10 tok=tf.getNextToken(); break; case colonTOK: case rparenTOK: break;//do nothing // new 12 default: error(17,linenumber); } // end of local switch. break; case type: cout << "case type, intok==" << intok << endl; switch (intok) { case INTEGERrw: s.push(integer); // 12 tok=tf.getNextToken(); break; case BOOLEANrw: s.push(booleanSEM); // 13 tok=tf.getNextToken(); break; default: error(18,linenumber); } // end of local switch. break; case funcs: switch (intok) { case FUNCTIONrw: s.push(funcs); // 14 s.push(semicolon); s.push(function); break; case BEGINrw: break;//do nothing is default: error(19,linenumber); } // end of local switch. break; case function: if (intok==FUNCTIONrw) { // 16 s.push(clearlevel1); s.push(RTN); s.push(FSP); s.push(adjustasp); s.push(funcbody); s.push(ASP); s.push(qnum); s.push(decs); s.push(funcheading); } else error(20,linenumber); break; case funcbody: if (intok==BEGINrw) { s.push(semicolon); s.push(ident); s.push(end); s.push(ident); s.push(assignop); s.push(RESULTrw); s.push(semicolon); s.push(stmtlist); tok=tf.getNextToken(); } else error(24, linenumber); break; case funcheading:if (intok==FUNCTIONrw) { // 17 s.push(savefuncinfo); s.push(semicolon); s.push(type); s.push(colon); s.push(rparen); s.push(paramlist); s.push(initfunc); s.push(lparen); s.push(ident); tok=tf.getNextToken(); } else error(2l,linenumber); break; case paramlist: cout << "case paramlist, intok == " << intok << " rparenTok == " << rparenTOK <repairQuad(qnumsaved,Quadnum); break; case repair1: qnumsaved=qs.pop(); qlist->repairQuad(qnumsaved,Quadnum+1); break; case patch: qnumsaved=qs.pop() ; qlist->repairQuad(Quadnum-1,qnumsaved+1); break; case adjustasp: qnumsaved=qs.pop(); qlist->adjustQuad(qnumsaved+1,-localtempsmax); break; case integer: qs.push(1); break; case booleanSEM: qs.push(2); break; case idSEM: idinx=s.pop(); //tok value write on s by ident qs.push(idinx); qs.push(identclass); cout << "case idSEM, s stack == " << endl; s.display(); cout << "case idSEM, qs stack == " << endl; qs.display(); break; case intSEM: intliteral=s.pop(); //literal write on s by unsignedint qs.push(intliteral); qs.push(numclass); break; case falseSEM: case trueSEM: intliteral=s.pop(); qs.push(intliteral); qs.push(boolclass); break; case initdecs: vcntprime=0; vcnt=0; break; case savevarinfo: saveVARinfo(); break; case incvcnt: vcnt++; break; case initfunc: pcnt=0; level=1; localmax=0; localtempsmax=0; temp=qs.pop(); if (temp==identclass) { idinx=qs.pop(); qs.push(Quadnum); qs.push(idinx); qs.push(temp); } else cout<<"\nPROBLEM in initfunc!\n"; break; case savefuncinfo:saveFUNCinfo(); break; case formalparam: FORMALparam(); break; case initpcnt: pcnt=0; qs.push(pcnt); break; case fcallret: Fcallret(); break; case actualparam: ACTUALparam(); break; case saveproginfo:savePROGinfo(); break; case setlevel0: level=0; break; case clearlevel1: iddt.clearLevel1Entries(); break; } // end of switch. } tf.closeTokenFile(); qf.createQuadFile(); emitallQuads(); qf.closeQuadFile(); } // end of all parser class methods. // Page B-26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42