资源描述
word 格式文档词法分析一、实验目的设计 、编制并调试一个词法分析程序,加深对词法分析原理的理解。二、实验要求2.1 待分析的简单的词法( 1)关键字 :beginifthenwhiledoend所有的关键字都是小写。( 2)运算符和界符:=+-*/=;()#( 3)其他单词是标识符( ID )和整型常数 ( SUM ), 通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*( 4)空格有空白 、制表符和换行符组成。空格一般用来分隔ID 、 SUM 、运算符 、界符和关键字 ,词法分析阶段通常被忽略。2.2 各种单词符号对应的种别码:表 2.1 各种单词符号对应的种别码单词符号种别码单词符号种别码bgin1:17If2: =18Then320wile421专业整理word 格式文档do523lettet10=24( letter|digit ) *dight dight*11=25+13;2614(27*15)28/16#02.3 词法分析程序的功能 :输入 :所给文法的源程序字符串 。输出 :二元组 (syn,token或 sum )构成的序列 。其中 :syn 为单词种别码 ;token 为存放的单词自身字符串;sum 为整型常数 。例如 :对源程序 begin x:=9: if x9 then x:=2*x+1/3; end #的源文件 ,经过词法分析后输出如下序列 :(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。3.1 主程序示意图:专业整理word 格式文档主程序示意图如图3-1 所示 。 其中初始包括以下两个方面: 关键字表的初值。关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表), 当扫描程序识别出标识符时,查关键字表 。 如能查到匹配的单词,则该单词为关键字,否则为一般标识符 。关键字表为一个字符串数组,其描述如下 :Char *rwtab6 = “begin ”,“if”,“then ”,“while ”,“do ”,“end ”,;置初值调用扫描子程序输出单词二元组否输入串结束是专业整理word 格式文档结束图 3-1(2 )程序中需要用到的主要变量为syn,token和 sum3.2 扫描子程序的算法思想:首先设置 3 个变量 : token 用来存放构成单词符号的字符串; sum 用来整型单词 ;syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2 所示 。变量初始化忽略空格是否文件结束?是是返回专业整理word 格式文档否字母拼字符串数字其他运算符 、符号界符等符号拼数是否关键字?否对不同符号给报错出相应的 syn 值是syn=10syn 为对应关键字的单词种别码syn=11返回图 3-2四 、词法分析程序的 C 语言程序源代码 :专业整理word 格式文档#include #include#include#include char prog80,token8,ch;int syn,p,m,n,sum;char *rwtab6=begin,if,then,while,do,end;scaner();main()p=0;printf(n please input a string(end with #):n);doscanf(%c,&ch);progp+=ch;while(ch!=#);p=0;doscaner();switch(syn)case 11:printf( %-10d%5d )n,sum,syn);break;case -1:printf(you have input a wrong stringn);专业整理word 格式文档getch();exit(0);default: printf( %-10s%5d )n,token,syn);break;while(syn!=0);getch();scaner() sum=0;for(m=0;m8;m+)tokenm+=NULL;ch=progp+;m=0;while(ch= )|(ch=n)ch=progp+;if(ch=a)|(ch=A) while(ch=a)|(ch=A)|(ch=0)&(ch=9) tokenm+=ch;ch=progp+;p-;syn=10;专业整理word 格式文档for(n=0;n=0)&(ch=0)&(ch=9) sum=sum*10+ch-0;ch=progp+;p-;syn=11;else switch(ch) case :tokenm+=ch;ch=progp+;if(ch=) syn=24;tokenm+=ch;else syn=23; p-;break;case +: tokenm+=ch;ch=progp+;if(ch=+) syn=17; tokenm+=ch;else专业整理word 格式文档 syn=13;p-;break;case -:tokenm+=ch;ch=progp+;if(ch=-) syn=29; tokenm+=ch;else syn=14;p-;break;case !:ch=progp+;if(ch=) syn=21; tokenm+=ch;专业整理word 格式文档else syn=31; p-;break;case =:tokenm+=ch;ch=progp+;if(ch=) syn=25; tokenm+=ch;else syn=18; p-;break;case *: syn=15;tokenm+=ch;break;case /: syn=16;tokenm+=ch;专业整理word 格式文档break;case (: syn=27;tokenm+=ch;break;case ): syn=28;tokenm+=ch;break;case : syn=5;tokenm+=ch;break;case : syn=6;tokenm+=ch;break;case ;: syn=26;tokenm+=ch;break;case : syn=30;tokenm+=ch;break;case #: syn=0;tokenm+=ch;break;专业整理word 格式文档case :syn=17;tokenm+=ch;break;default: syn=-1;break;tokenm+=0;五、结果分析 :输入 begin x:=9: if x9 then x:=2*x+1/3; end #后经词法分析输出如下序列: (begin1)(x10)( : 17)(=18)(911)( ; 26)(if2)如图 5-1 所示:图 5-1六、总结:词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基专业整理word 格式文档本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的完成 ,更加加深了对词法分析原理的理解。语法分析一、实验目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析 。二、实验要求利用 C 语言编制递归下降分析程序,并对简单语言进行语法分析。专业整理word 格式文档2.1 待分析的简单语言的语法用扩充的BNF 表示如下 : : =beginend : = ; : = : =ID := : =+ | -:=*|/ :=ID|NUM|()2.2 实验要求说明输入单词串 ,以 “# ”结束 ,如果是文法正确的句子,则输出成功信息,打印 “success ”,否则输出 “error ”。例如 :输入begin a:=9; x:=2*3; b:=a+x end #输出success !输入x:=a+b*c end #输出error2.3 语法分析程序的酸法思想(1 )主程序示意图如图2-1 所示 。专业整理word 格式文档置初值调用 scaner 读下一个单词符号调用 lrparser结束图 2-1语法分析主程序示意图(2 )递归下降分析程序示意图如图2-2 所示 。(3 )语句串分析过程示意图如图2-3所示 。是否begin?否调用 statement 函数是专业整理调用 scaner调用语句串分析程序是否 end?是调用 scanersyn=0&kk=0?是打印分析成功word 格式文档是否;?否是调用 scaner否调用 statement 函数出错处理否图 2-3语句串分析示意图出错处理图 2-2递归下降分析程序示意图(4 ) statement语句分析程序流程如图2-4 、 2-5 、2-6 、 2-7 所示 。专业整理word 格式文档是否标识符 ?否调用 term 函数调用 scaner是否: =?调用 scaner是否+,-?否否调用 expression 函数出错处理图 2-4 statement 语句分析函数示意图意图调用 factor 函数是否*,/?调用 scaner专业整理是调用 scaner调用 term 函数出错处理图 2-5 expression 表达式分析函数示是否标识符 ?是调用 factor 函数出错处理word 格式文档否是否图 2-6 term 分析函数示意图否出错处理否是是否整常数 ?否是否( ?是调用 scaner调用 expression 函数是否) ?是调用 scaner调用 scaner图 2-7 factor分析过程示意图三、 语法分析程序的C 语言程序源代码 :#include stdio.h专业整理word 格式文档#include string.hchar prog100,token8,ch;char *rwtab6=begin,if,then,while,do,end;int syn,p,m,n,sum;int kk;factor();expression();yucu();term();statement();lrparser();scaner();main()p=kk=0;printf(nplease input a string (end with #): n);do scanf(%c,&ch);progp+=ch;while(ch!=#);p=0;scaner();专业整理word 格式文档lrparser();getch();lrparser()if(syn=1)scaner();/* 读下一个单词符号*/yucu();/* 调用 yucu() 函数 ; */if (syn=6) scaner();if (syn=0)&(kk=0)printf(success!n);else if(kk!=1) printf(the string havent got a end!n);kk=1;else printf(havent got a begin!n);kk=1;return;专业整理word 格式文档yucu()statement();/* 调用函数 statement();*/while(syn=26)scaner();/* 读下一个单词符号*/if(syn!=6)statement();/* 调用函数 statement();*/return;statement() if(syn=10)scaner();/* 读下一个单词符号*/if(syn=18) scaner();/* 读下一个单词符号*/expression();/* 调用函数statement();*/else printf(the sing := is wrong!n);kk=1;专业整理word 格式文档else printf(wrong sentence!n);kk=1;return;expression() term(); while(syn=13)|(syn=14) scaner();/* 读下一个单词符号*/term();/* 调用函数 term();*/return;term() factor(); while(syn=15)|(syn=16) scaner();/* 读下一个单词符号*/factor();/* 调用函数factor(); */return;专业整理word 格式文档factor() if(syn=10)|(syn=11) scaner();else if(syn=27) scaner();/* 读下一个单词符号*/expression();/* 调用函数statement();*/if(syn=28)scaner();/* 读下一个单词符号*/else printf(the error on (n);kk=1;else printf(the expression error!n);kk=1;return;scaner() sum=0; for(m=0;m8;m+)tokenm+=NULL; m=0;ch=progp+;专业整理word 格式文档while(ch= )ch=progp+;if(ch=a)|(ch=A) while(ch=a)|(ch=A)|(ch=0)&(ch=9)tokenm+=ch;ch=progp+;p-;syn=10;tokenm+=0;for(n=0;n=0)&(ch=0)&(ch=9) sum=sum*10+ch-0;ch=progp+;p-;syn=11;专业整理word 格式文档else switch(ch) case ) syn=21;else if(ch=) syn=22;else syn=20; p-;break;case :m=0;ch=progp+;if(ch=) syn=24;else syn=23;专业整理word 格式文档p-;break;case :m=0;ch=progp+;if(ch=) syn=18;else syn=17; p-;break;case +: syn=13; break;case -: syn=14; break;case *: syn=15;break;case /: syn=16;break;case (: syn=27;break;case ): syn=28;break;case =: syn=25;break;case ;: syn=26;break;case #: syn=0;break;专业整理word 格式文档default: syn=-1;break;四、结果分析 :输入begin a:=9; x:=2*3; b:=a+x end #后输出 success ! 如图 4-1 所示:图 4-1输入x:=a+b*c end#后输出error如图 4-2 所示 :图 4-2五、总结:通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值 ” 调用专业整理word 格式文档scaner 函数读下一个单词符号调用 IrParse结束 。 递归下降分析的大致流程为:“先判断是否为 begin ” 不是则 “出错处理 ”,若是则 “调用 scaner 函数 ” 调用语句串分析函数“判断是否为 end ” 不是则 “出错处理 ”,若是则调用scaner 函数“判断 syn=0&kk=0是否成立”成立则说明分析成功打印出来。不成立则 “出错处理 ”。专业整理word 格式文档语义分析程序#include stdio.h#include string.hchar prog100,token8,ch;char *rwtab6=begin,if,then,while,do,end;int syn,p,m,n,sum,q;int kk;struct char result18;char ag118;char op18;char ag218; quad20; char *factor(); char *expression(); int yucu();char *term(); int statement();专业整理word 格式文档int lrparser();char *newtemp();scaner();emit(char *result,char *ag1,char *op,char *ag2);main() int j; q=p=kk=0;printf(nplease input a string (end with #): ); do scanf(%c,&ch);progp+=ch;while(ch!=#);p=0;scaner();lrparser();if(q19)printf( to long sentense!n);else for (j=0;jq;j+)printf(%s = %s %s %snn,quadj.result1,quadj.ag11,quadj.op1,quadj.ag21);getch();int lrparser()专业整理word 格式文档 int schain=0;kk=0;if (syn=1) scaner(); schain=yucu(); if(syn=6) scaner();if(syn=0)&(kk=0)printf(Success!n);else if(kk!=1)printf(short of end !n);kk=1;getch();exit(0);else printf(short of begin !n);kk=1;getch();exit(0);return (schain);专业整理word 格式文档int yucu() int schain=0; schain=statement(); while(syn=26) scaner();schain=statement();return (schain);int statement() char tt8,eplace8; int schain=0;if (syn=10) strcpy(tt,token); scaner(); if(syn=18) scaner(); strcpy(eplace,expression(); emit(tt,eplace,); schain=0;专业整理word 格式文档else printf(short of sign := !n);kk=1;getch();exit(0);return (schain);char *expression() char *tp,*ep2,*eplace,*tt; tp=(char *)malloc(12); ep2=(char *)malloc(12); eplace=(char *)malloc(12); tt=(char *)malloc(12); strcpy(eplace,term(); while(syn=13)|(syn=14) if (syn=13)strcpy(tt,+);else strcpy(tt,-); scaner(); strcpy(ep2,term();专业整理word 格式文档strcpy(tp,newtemp();emit(tp,eplace,tt,ep2);strcpy(eplace,tp);return (eplace);char *term() char *tp,*ep2,*eplace,*tt; tp=(char *)malloc(12); ep2=(char *)malloc(12); eplace=(char *)malloc(12); tt=(char *)malloc(12); strcpy(eplace,factor(); while(syn=15)|(syn=16) if (syn=15)strcpy(tt,*);else strcpy(tt,/); scaner(); strcpy(ep2,factor(); strcpy(tp,newtemp(); emit(tp,eplace,tt,ep2); strcpy(eplace,tp);专业整理word 格式文档return (eplace);char *factor() char *fplace;fplace=(char *)malloc(12);strcpy(fplace,);if(syn=10) strcpy(fplace,token); scaner();else if(syn=11) itoa(sum,fplace,10);scaner();else if(syn=27) scaner(); fplace=expression(); if(syn=28) scaner();else printf(error on ) !n); kk=1;专业整理word 格式文档getch();exit(0);else printf(error on ( !n);kk=1;getch();exit(0);return (fplace);char *newtemp() char *p; char m8; p=(char *)malloc(8); kk+; itoa(kk,m,10); strcpy(p+1,m); p0=t; return(p);专业整理word 格式文档scaner() sum=0; for(m=0;m8;m+)tokenm+=NULL; m=0;ch=progp+;while(ch= )ch=progp+; if(ch=a)|(ch=A) while(ch=a)|(ch=A)|(ch=0)&(ch=9) tokenm+=ch;ch=progp+;p-; syn=10;tokenm+=0;for(n=0;n=0)&(ch=0)&(ch=9) sum=sum*10+ch-0;ch=progp+;p-;syn=11;else switch(ch) case ) syn=21;else if(ch=) syn=22;elsesyn=20;p-;break;专业整理word 格式文档case :m=0;ch=progp+;if(ch=) syn=24;else syn=23; p-;break;case :m=0;ch=progp+;if(ch=) syn=18;else syn=17; p-;break;case +: syn=13; break;专业整理word 格式文档case -: syn=14; break;case *: syn=15;break;case /: syn=16;break;case (: syn=27;break;case ): syn=28;break;case =: syn=25;break;case ;: syn=26;break;case #: syn=0;break;default: syn=-1;break;emit(char *result,char *ag1,char *op,char *ag2)strcpy(quadq.result1,result);strcpy(quadq.ag11,ag1);strcpy(quadq.op1,op);strcpy(quadq.ag21,ag2);q+;专业整理word 格式文档专业整理
展开阅读全文