您好,欢迎访问三七文档
当前位置:首页 > 机械/制造/汽车 > 编译原理--增加数据类型
//pl0.h///这个文件中的代码与课本的一致//对于使用C++的编译器,这句话可以注释掉,但对于C语言不行//typedefenum{FALSE,TRUE,}bool;#definenorw16//关键字的个数#definetxmax100//名字表的容量#definenmax14//数字的最大位数#defineal10//符号的最大长度#defineamax2047//地址上界#definelevmax3//最大允许的嵌套声明层数#definecxmax200//最多的虚拟机代码数enumsymbol{//枚举类型://nul=0,ident=1,number=2,plus=3,minus=4//times=5,依次类推,procsym=31nul,ident,number,//下面的表示的是系统的算数运算符以及逻辑运算符,知道意思就可以plus,minus,times,//相乘的意思slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,//左括号rparen,comma,semicolon,period,becomes,//赋值的意思//下面的表示是系统的保留字beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym,integersym,charactersym,doubsym,charnum,integercon,doubnum};#definesymnum38enumobject{constant,variable,procedur,integer,character,doub,};enumfct{lit,opr,lod,sto,cal,inte,jmp,jpc,};#definefctnum11structinstruction{enumfctf;//虚拟机代码指令intl;//引用层与声明层的层差doublea;//根据f的不同而不同,参考课本};FILE*fas;//输出名字表FILE*fa;//输出虚拟机代码FILE*fa1;//输出源文件及其各行对应的首地址FILE*fa2;//输出结果boollistswitch;booltableswitch;charch;//获取字符的缓冲区enumsymbolsym;charid[al+1];doublenum;intcc,ll;//cc表示当前字符的位置intcx;//虚拟机代码指针charline[81];//读取行缓冲区chara[al+1];//临时符号,多出的一个字节用于表示字符串的结尾structinstructioncode[cxmax];//存放虚拟机代码的数组charword[norw][al];//保留字enumsymbolwsym[norw];//保留字对应的符号值enumsymbolssym[256];//单符号的符号值charmnemonic[fctnum][5];//虚拟机代码指令的名称booldeclbegsys[symnum];//表示声明开始的符号集合boolstatbegsys[symnum];//表示语句开始的符号集合boolfacbegsys[symnum];//表示因子开始的符号集合//名字表结构structtablestruct{charname[al];//名字//enumdatatypetype;//数据类型:integer,character,doub,enumobjectkind;//类型:const,var,array,proceduredoubleval;//数值,仅const使用,使用双精度浮点型intlevel;//所处层intadr;//地址intsize;//需分配的数据空间};structtablestructtable[txmax];//名字表FILE*fin;FILE*fout;charfname[al];interr;//错误计数器,每出一次错误,其加一#definegetsymdoif(-1==getsym())return-1#definegetchdoif(-1==getch())return-1#definetestdo(a,b,c)if(-1==test(a,b,c))return-1#definegendo(a,b,c)if(-1==gen(a,b,c))return-1#defineexpressiondo(a,b,c)if(-1==expression_r(a,b,c))return-1#definefactordo(a,b,c)if(-1==factor(a,b,c))return-1#definetermdo(a,b,c)if(-1==term(a,b,c))return-1#defineconditiondo(a,b,c)if(-1==condition(a,b,c))return-1#definestatementdo(a,b,c)if(-1==statement(a,b,c))return-1#defineconstdeclarationdo(a,b,c)if(-1==constdeclaration(a,b,c))return-1#definevardeclarationdo(a,b,c)if(-1==vardeclaration(a,b,c))return-1#defineintegerdeclarationdo(a,b,c)if(-1==integerdeclaration(a,b,c))return-1#definecharacterdeclarationdo(a,b,c)if(-1==characterdeclaration(a,b,c))return-1#definedoubdeclarationdo(a,b,c)if(-1==doubdeclaration(a,b,c))return-1voiderror(intn);intgetsym();intgetch();voidinit();intgen(enumfctx,inty,doublez);inttest(bool*s1,bool*s2,intn);intinset(inte,bool*s);intaddset(bool*sr,bool*s1,bool*s2,intn);intsubset(bool*sr,bool*s1,bool*s2,intn);intmulset(bool*sr,bool*s1,bool*s2,intn);intblock(intlev,inttx,bool*fsys);voidinterpret();intfactor(bool*fsys,int*ptx,intlev);intterm(bool*fsys,int*ptx,intlev);intcondition(bool*fsys,int*ptx,intlev);intexpression_r(bool*fsys,int*ptx,intlev);intstatement(bool*fsys,int*ptx,intlev);voidlistcode(intcx0);intvardeclaration(int*ptx,intlev,int*pdx);intintegerdeclaration(int*ptx,intlev,int*pdx);intcharacterdeclaration(int*ptx,intlev,int*pdx);intdoubdeclaration(int*ptx,intlev,int*pdx);intconstdeclaration(int*ptx,intlev,int*pdx);intposition(char*idt,inttx);voidenter(enumobjectk,int*ptx,intlev,int*pdx);intbase(intl,int*s,intb);//pl0.cpp#includestdio.h#includepl0.h#includestring.h//这个宏定义的意思表示是运行时的数据栈大小,这个会在interpret函数中出现,可以先不用管它#definestacksize500/***********************************************************************************在看源程序之前,请始终记住****sym表示的是当前字符串的类型,****num表示的数字,****id中存放的是字符串,****记住这点在看源程序的时候非常重要。****另外,还要记住的是nxtlev数组中存放的是后继符号集************************************************************************************/intmain(){boolnxtlev[symnum];//这个数组表示的是当前语句的后继符号集合,一共有个printf(Inputpl/0file?);//输入文件的路径scanf(%s,fname);fin=fopen(fname,r);//以只读打开文件,fin文件指针if(fin){printf(Listobjectcode?(Y/N));scanf(%s,fname);listswitch=(fname[0]=='y'||fname[0]=='Y');//listswitch用于列举代码printf(Listsymboltable?(Y/N));scanf(%s,fname);tableswitch=(fname[0]=='y'||fname[0]=='Y');//tableswitch表示是否输出table表//该表类似于页的表fa1=fopen(fa1.tmp,w);//以只读格式打开文件,对于本程序其实是新建一个文件//fa1文件中存储的是源程序,运行一次,看看这个文件就明白啦fprintf(fa1,Inputpl/0file?);//将Inputpl/0file?输入文件中fprintf(fa1,%s\n,fname);//同上init();//初始化err=0;cc=cx=ll=0;ch='';if(-1!=getsym()){//如果程序开始是对的,则往下执行//fa存放的是模拟程序的代码//fas存放的是table表中的数据//运行一次代码看一下文件即明白fa=fopen(fa.tmp,w);//以只读形式打开fas=fopen(fas.tmp,w);//同上//函数原型:intaddset(bool*sr,bool*s1,bool*s2,intn);//boolnxtlev[32];/*declbegsys[constsym]=true;declbegsys[varsym]=true;declbegsys[procsym]=true;statbegsys[beginsym]=true;statbegsys[callsym]=true;statbegsys[ifsym]=true;statbegsys[whilesym]=true;执行该函数的结果为对应的下标在nxtlev中上述值均为true;*///在分程序开始的时候,其后继符号可以是//const,var,procedure,begin,call,if,while//所以在nxtlev中将上述这些置为true//当然在整个程序可以只有一个'.',即程序是空的也可以,所以会有nxtlev[period]=true;addset(nxtlev,declbegsys,statbegsys,symnum);//symnum=32;nxtlev[period]=true;//block是编译程序的主程序,是分程序的分析处理过程,其里面调用了大部分程序//耐心看//请记住在block程序开始的
本文标题:编译原理--增加数据类型
链接地址:https://www.777doc.com/doc-6131741 .html