实验报告一、实验名称:分析PL0词法分析程序二、试验目的学习PL0程序的词法分析程序GenSym的实现过程结合具体的程序了解词法分析过程三、实验设备PC兼容机DOS操作系统或Windows操作系统TurboPascal软件等四、实验要求独立完程序的分析过程自己跟踪程序的执行过程记录程序的执行过程记录程序的运行结果五、实验内容1,通读程序。2,分析获取字符的算法3,通过对程序中算法的理解分析程序的功能,并且注释4,对程序中的各个涉及到的变量进行分析并注释5,对算法进行注释六、实验过程记录七、源程序{编译器程序阅读,程序功能为此法分析,读取字符串,单字符,标识符,识别数字}怎么读取空格,回车。{程序注释时间:2014年3月14日}{程序修改人:计科B113班程鑫}{修改方式:对方法和函数进行分析,了解程序的功能}programpl0(input,output);{定义一个程序,program为程序的开始标志}{pl/0compilerwithcodegeneration}{编译生成代码}label99;{定义一个标签}constnorw=11;{no.ofreservedwords}{保留字}txmax=100;{lengthofidentifiertable}{标识符长度表}nmax=14;{max.no.ofdigitsinnumbers}{最大位数}al=10;{lengthofidentifiers}{标识符的长度}amax=2047;{maximumaddress}{最大的地址}levmax=3;{maximumdepthofblocknesting}{最大深度嵌套块}cxmax=200;{sizeofcodearray}{代码数组的大小}typesymbol=(nul,ident,number,plus,minus,times,slash,oddsym,{标识符,在pascal语言中定义好的,直接拿过来可以用的}eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,dosym,callsym,constsym,varsym,procsym);alfa=packedarray[1..al]ofchar;{打包字符}object1=(constant,varible,proc);{常量}symset=setofsymbol;{字符集}fct=(lit,opr,lod,sto,cal,int,jmp,jpc);{functions}{功能测试}instruction=packedrecordf:fct;{functioncode}l:0..levmax;{level}a:0..amax{displacementaddress}end;{lit0,a:loadconstanta{加载}opr0,a:executeoperationa{执行}lodl,a:loadvariblel,a{加载变量}stol,a:storevariblel,a{存储变量}call,a:callprocedureaatlevell{调用程序}int0,a:incrementt-registerbyajmp0,a:jumptoajpc0,a:jumpconditionaltoa}varch:char;{lastcharacterread}{最后一个字符的阅读}sym:symbol;{lastsymbolread}{最后一个符号}id:alfa;{lastidentifierread}{标识符}num:integer;{lastnumberread}cc:integer;{charactercount}{字符统计}ll:integer;{linelength}{行长度,interger为整数}kk,err:integer;cx:integer;{codeallocationindex}{代码分配下标}line:array[1..81]ofchar;{在pascal编译器里,界面上每一行最长可以输入80个字符,这是由于文本编辑器就只能输入80个而定义的,}a:alfa;code:array[0..cxmax]ofinstruction;word:array[1..norw]ofalfa;wsym:array[1..norw]ofsymbol;ssym:array[char]ofsymbol;{运算符}mnemonic:array[fct]of{助记符}packedarray[1..5]ofchar;declbegsys,statbegsys,facbegsys:symset;table:array[0..txmax]ofrecordname:alfa;casekind:object1ofconstant:(val:integer);varible,proc:(level,adr:integer)end;fin:text;sfile:string;procedureerror(n:integer);{程序错误}beginwriteln('****','':cc-1,'^',n:2);err:=err+1end{error};proceduregetsym;{读单词子程序}{定义三个整型变量,变量i是一个临时变量,用来做查找的下标;变量k是一个临时变量,用来做获取保留字的下标}vari,j,k:integer;{程序说明:这个程序是getsym的一个子程序}{程序功能:读取下一个字符;}{程序实现过程:第一步为读字符,第二步为读单词,第三步为标示符和保留字处理,第四步位数字处理}{入口参数:无}{出口参数:无}{返回结果:读取到的字符放到全程变量ch中}proceduregetch;{读字符子程序}beginifcc=llthen{cc为字符下标ll行长度}beginifeof(fin)then{eof文件结束符}beginwrite('programincomplete');{goto99}{程序不完整,程序不完整说明程序读完一个序列后,读下一个Token序列时,程序突然结束了,造成了无法继续往下读。}close(fin);exit;end;ll:=0;cc:=0;write(cx:5,'');{变量的初始化,ll为行长度,行长度每次读完一行之后都是继续读下一行,所以行号每次都是加一的,cx代码分配}whilenoteoln(fin)do{eoln文本行结束状态}beginll:=ll+1;read(fin,ch);write(ch);line[ll]:=ch{ch为字符,如果读入一行的时没有遇到文本行结束状态,则将这一行字符全部读完,读完之后行号加一,将读到的字符ch返回}end;writeln;readln(fin);ll:=ll+1;line[ll]:='';end;cc:=cc+1;ch:=line[cc]{将读出的字符放到line数组中}end{getch};{读字符子程序结束}begin{getsym}{读单词子程序开始}whilech=''dogetch;{如果当前的字符数组是空的,则做下一步,读取字符}ifchin['a'..'z']then{如果是由字母组成的,则继续}begin{identifierorreservedword}k:=0;{识别标识符和保留字}repeatifkalthen{al是标示符长度}begink:=k+1;a[k]:=ch{将标示符放到ch中}end;getch;untilnot(chin['a'..'z','0'..'9']);{如果不是字母和数字,则停止}ifk=kkthenkk:=kelserepeata[kk]:='';kk:=kk-1untilkk=k;id:=a;i:=1;j:=norw;repeatk:=(i+j)div2;ifid=word[k]thenj:=k-1;ifid=word[k]theni:=k+1untilij;ifi-1jthensym:=wsym[k]elsesym:=ident{标示符和保留字处理结束}endelseifchin['0'..'9']thenbegin{number}k:=0;num:=0;sym:=number;{数处理开始}repeatnum:=10*num+(ord(ch)-ord('0'));k:=k+1;getchuntilnot(chin['0'..'9']);ifknmaxthenerror(30)end{数处理结束}elseifch=':'thenbegingetch;ifch='='thenbeginsym:=becomes;getchendelsesym:=nul;endelsebeginsym:=ssym[ch];getchend{读单词子程序结束}end{getsym};{查找字符结束}proceduregen(x:fct;y,z:integer);{代码生成子程序}beginifcxcxmaxthenbeginwrite('programtoolong');{goto99}end;withcode[cx]dobeginf:=x;l:=y;a:=zend;cx:=cx+1end{gen};proceduretest(s1,s2:symset;n:integer);beginifnot(symins1)thenbeginerror(n);s1:=s1+s2;whilenot(symins1)dogetsymendend{test};procedureblock(lev,tx:integer;fsys:symset);vardx:integer;{dataallocationindex}tx0:integer;{initialtableindex}cx0:integer;{initialcodeindex}procedureenter(k:object1);begin{enterobjectintotable}tx:=tx+1;withtable[tx]dobeginname:=id;kind:=k;casekofconstant:beginifnumamaxthenbeginerror(30);num:=0end;val:=numend;varible:beginlevel:=lev;adr:=dx;dx:=dx+1;end;proc:level:=levendendend{enter};functionposition(id:alfa):integer;vari:integer;begin{findindentifieridintable}table[0].name:=id;i:=tx;whiletable[i].nameiddoi:=i-1;position:=iend{position};procedureconstdeclaration;beginifsym=identthenbegingetsym;ifsymin[eql,becomes]thenbeginifsym=becomesthenerror(1);getsym;ifsym=numberthenbeginenter(constant);getsymendelseerror(2)endelseerror(3)endelseerror(4)end{constdeclaration};procedurevardeclaration;beginifsym=identthenbeginenter(varible);getsymendelseerror(4)end{vardeclaration};procedurelistcode;vari:integer;begin{listcodegeneratedforthisblock}fori:=cx0tocx-1dowithco