1、编译原理实验指导书实验一 词法分析一、 实验目的编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。 二、 实验题目如源程序为C语言。输入如下一段:main()int a=-5,b=4,j;if(a=b) j=a-b; else j=b-a;要求输出如下:(2,”main”) (5,”(”) (5,”)”)(5,”) (1,”int”) (2,”a”)(4,”=”) (3,”-5”) (5,”,”)(2,”b”) (4,”=”) (3,”4”)(5,”,”) (2,”j”) (5,”
2、;”)(1,”if”) (5,”(”) (2,”a”)(4,”=”) (2,”b”) (5,”)”)(2,”j”) (4,”=”) (2,”a”)(4,”-”) (2,”b”) (5,”;”)(1,”else”) (2,”j”) (4,”=”)(2,”b”) (4,”-”) (2,”a”)(5,”;”) (5,”)三、 实验理论依据(一)识别各种单词符号1、 程序语言的单词符号一般分为五种:(1) 关键字(保留字/ 基本字)if 、while 、begin(2) 标识符:常量名、变量名(3) 常数:34 、56.78 、true 、a 、(4) 运算符:+ 、- 、* 、/ 、 、and 、o
3、r 、.(5) 界限符:, ; ( ) /*2、 识别单词:掌握单词的构成规则很重要 (1) 标识符的识别:字母| 下划线+( 字母/ 数字/ 下划线)(2) 关键字的识别:与标识符相同,最后查表 (3) 常数的识别 (4) 界符和算符的识别 3、 大多数程序设计语言的单词符号都可以用转换图来识别,如图1-1 图1-14、 词法分析器输出的单词符号常常表示为二元式:(单词种别,单词符号的属性值)(1) 单词种别通常用整数编码,如1 代表关键字,2 代表标识符等 (2) 关键字可视其全体为一种,也可以一字一种。采用一字一种得分法实际处理起来较为方便。 (3) 标识符一般统归为一种 (4) 常数按
4、类型(整、实、布尔等)分种 (5) 运算符可采用一符一种的方法。 (6) 界符一般一符一种的分法。 (二)超前搜索方法1、 词法分析时,常常会用到超前搜索方法。如当前待分析字符串为“a+” ,当前字符为“” ,此时,分析器倒底是将其分析为大于关系运算符还是大于等于关系运算符呢? 显然,只有知道下一个字符是什么才能下结论。于是分析器读入下一个字符+ ,这时可知应将 解释为大于运算符。但此时,超前读了一个字符+ ,所以要回退一个字符,词法分析器才能正常运行。又比如:+ 分析为正号还是加法符号 (三)预处理预处理工作包括对空白符、跳格符、回车符和换行符等编辑性字符的处理,及删除注解等。由一个预处理子
5、程序来完成。四、 词法分析器的设计1、 设计方法:(1) 写出该语言的词法规则。 (2) 把词法规则转换为相应的状态转换图。 (3) 把各转换图的初态连在一起,构成识别该语言的自动机 (4) 设计扫描器 2、 把扫描器作为语法分析的一个过程,当语法分析需要一个单词时,就调用扫描器。 扫描器从初态出发,当识别一个单词后便进入终态,送出二元式 图1-2 取单词程序框图五、 部分参考程序void main() if (fp=fopen(“example.c”,“r”)=NULL) /*只读方式打开一个文件*/ printf(error); else cbuffer = fgetc(fp); /*fg
6、etc( )函数:从磁盘文件读取一个字符*/ while (cbuffer!=EOF) if(cbuffer= |cbuffer=n) /*掠过空格和回车符*/ cbuffer=fgetc(fp); else if(isalpha(cbuffer) cbuffer=alphaprocess(cbuffer); else if (isdigit(cbuffer) cbuffer=digitprocess(cbuffer); else cbuffer=otherprocess(cbuffer); char alphaprocess(char buffer) int atype; /*保留字数组中的
7、位置*/ int i=-1; char alphatp20; while (isalpha(buffer)|(isdigit(buffer)|buffer=_) alphatp+i=buffer; /*读一个完整的单词放入alphatp数组中*/ alphatpi+1=0; atype=search(alphatp,1);/*对此单词调用search函数判断类型*/ if(atype!=0) printf(%s, (1,%d)n,alphatp,atype-1); id=1; else printf(%s ,2)n,alphatp); id=2; FILE *fp;char cbuffer;c
8、har *key8=if,else,for,while,do,return,break,continue;int atype,id=4;int search(char searchchar ,int wordtype) /*判断单词是保留字还是标识符*/ int i=0; int p; switch (wordtype) case 1:for (i=0;i=7;i+) if (strcmp(keyi,searchchar)=0) p=i+1; break; /*是保留字则p为非0且不重复的整数*/ else p=0; /*不是保留字则用于返回的p=0*/ return(p); char dig
9、itprocess(char buffer) int i=-1; char digittp20; while (isdigit(buffer) digittp+i=buffer; buffer=fgetc(fp); digittpi+1=0; printf(%s ,3)n,digittp); id=3; return(buffer); char otherprocess(char buffer) char ch20; ch0=buffer; ch1=0; if(ch0=,|ch0=;|ch0=|ch0=|ch0=(|ch0=) printf(%s ,5)n,ch); buffer=fgetc(
10、fp); id=4; return(buffer); if(ch0=*|ch0=/) printf(%s ,4)n,ch); buffer=fgetc(fp); id=4; return(buffer); if(ch0=|ch0=!|ch0=) buffer=fgetc(fp); if(buffer=) ch1=buffer; ch2=0; printf(%s ,4)n,ch); else printf(%s ,4)n,ch); id=4; return(buffer); buffer=fgetc(fp); id=4; return(buffer); if(ch0=+|ch0=-) if(id
11、=4) /*在当前符号以前是运算符,则此时为正负号*/ buffer=fgetc(fp); ch1=buffer; ch2=0; printf(%s ,3)n,ch); id=3; buffer=fgetc(fp); return(buffer); ch1=0; printf(%s ,4)n,ch); buffer=fgetc(fp); id=4; return(buffer); 实验二 LL(1)分析法一、实验目的:根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。二、实验题目实验规定对下列文法,用LL(1)分析
12、法对任意输入的符号串进行分析: (1)E:=TG(2)G:=+TG(3)G:=(4)T:=FS(5)S:=*FS(6)S:=(7)F:=(E)(8)F:=i若输入串为i+i*i# ,则输出为:LL(1)的分析表为: i + * ( ) # 说 明 E e eSelect(ETG)=(,i Ggg1g1Select (G+TG)=+Select (G)=#,) T t tSelect (TFS)=(,i Ss1 s s1 s1Select (S*FS)=*Select (S)=#,) + F f1 fSelect (F(E)=(Select (Fi)=i三、参考程序代码do/*读入分析串*/ s
13、canf(%c,&ch); if (ch!=i) &(ch!=+) &(ch!=*)&(ch!=()&(ch!=)&(ch!=#) printf(输入串中有非法字符n); exit(1); Bj=ch; j+; while(ch!=#); l=j;/*分析串长度*/ ch=B0;/*当前分析字符*/ Atop=#; A+top=E;/*#,E进栈*/ printf(步骤tt分析栈 tt剩余字符 tt所用产生式 n); do x=Atop-;/*x为当前栈顶字符*/ printf(%d,k+); printf(tt); for(j=0;j=5;j+)/*判断是否为终结符*/ if(x=v1j)
14、flag=1; break; if(flag=1)/*如果是终结符*/ if(x=#) finish=1;/*结束标记*/ printf(acc!n);/*接受 */ getchar(); getchar(); exit(1); if(x=ch) print(); print1(); printf(%c匹配n,ch); ch=B+b;/*下一个输入字符*/ flag=0;/*恢复标记*/ else/*出错处理*/ print(); print1(); printf(%c出错n,ch);/*输出出错终结符*/ exit(1); else/*非终结符处理*/ for(j=0;j=4;j+) if(
15、x=v2j) m=j;/*行号*/ break; for(j=0;j,cha.origin);/*输出产生式*/ for(j=0;j=0;j-)/*产生式逆序入栈*/ A+top=cha.arrayj; if(Atop=)/*为空则不进栈*/ top-; void print()/*输出分析栈 */ int a;/*指针*/ for(a=0;a=top+1;a+) printf(%c,Aa); printf(tt); void print1()/*输出剩余串*/ int j; for(j=0;jb;j+)/*输出对齐符*/ printf( ); for(j=b;j=l;j+) printf(%
16、c,Bj); printf(ttt);主程序中各变量定义:char A20;/*分析栈*/ char B20;/*剩余串*/ char v120=i,+,*,(,),#;/*终结符 */ char v220=E,G,T,S,F;/*非终结符 */ int j=0,b=0,top=0,l;/*L为输入串长度 */ typedef struct type/*产生式类型定义 */ char origin;/*大写字符 */ char array5;/*产生式右边字符 */ int length;/*字符个数 */ type;type e,t,g,g1,s,s1,f,f1;/*结构体变量 */type
17、 C1010;/*预测分析表 */*把文法产生式赋值结构体*/ e.origin=E; strcpy(e.array,TG); t.origin=T; strcpy(t.array,FS); g.origin=G; strcpy(g.array,+TG); g1.origin=G; g1.array0=; s.origin=S; strcpy(s.array,*FS); s1.origin=S; s1.array0=; f.origin=F; strcpy(f.array,(E); f1.origin=F; f1.array0=i;for(m=0;m=4;m+)/*初始化分析表*/ for(n
18、=0;n=0&ch=0&chS(1)S-BB(2)B-aB(3)B-b2、LR(1)分析表为:状态ACTIONGOTOab#SBS0S3S412S1accS2S6S75S3S3S48S4r3r3S5r1S6S6S79S7r3S8r2r2S9r2(1)若输入baba#,则输出为:步骤 状态栈 符号栈 输入串 ACTION GOTO 1 0 # baba# S4 2 04 #b aba# r3 23 02 #B aba# S64 026 #Ba ba# S75 0267 #Bab a# error(2)若输入bb#,则输出为:步骤 状态栈 符号栈 输入串 ACTION GOTO 1 0 # bb#
19、 S4 2 04 #b b# r3 23 02 #B b# S74 027 #Bb # r3 55 025 #BB # r1 16 01 #S # acc三、算法流程图四、参考程序代码/* ACTION表*/char *action103=S3#,S4#,NULL, NULL,NULL,acc, S6#,S7#,NULL, S3#,S4#,NULL, r3#,r3#,NULL, NULL,NULL,r1#, S6#,S7#,NULL, NULL,NULL,r3#, r2#,r2#,NULL, NULL,NULL,r2#;/* GOTO表*/int goto1102=1,2, 0,0, 0,5,
20、 0,8, 0,0, 0,0, 0,9, 0,0, 0,0, 0,0;char vt3=a,b,#; /*存放终结符*/char vn2=S,B; /*存放非终结符*/char *LR4=E-S#,S-BB#,B-aB#,B-b#; /*存放产生式*/*输出状态栈、输出符号栈、输出输入串*/do y=z;m=0;n=0; /*y,z指向状态栈栈顶*/ g=top;j=0;k=0; x=ctop; count+; printf(%dt,count); while(m=top1) /*输出状态栈*/ printf(%d,am); m=m+1; printf(tt); while(n=top2) /*输出符号栈*/ printf(%c,bn); n=n+1;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1