词法分析实验报告
实验一、 词法分析程序实验
专业 计算机科学与技术 姓名 王晓峰 学号 201506110163
一、 实验目的
编制一个词法分析程序。
二、 实验内容和要求
—输入:源程序字符串。
—输出:二元组(种别,单词本身)
—待分析语言的词法规则
主要是从左至右逐个字符地对源程序进行扫描,产生一个个单词序列,用于语法分析
三、 实验方法、步骤及结果测试
- 1. 源程序名:压缩包文件词法分析.rar中源程序名词法分析.c
- 2. 原理分析
这里的存储结构主要是用数组来存储字符串。
这里的算法主要是while语句的循环,首先先在主函数中检测是否有$这个终结条件,如果是的话就结束。不是的话就进入do-while的循环中,进入scaner()这一个函数中进行判定。而这个scaner这一个函数主要包括三大块,主要是标识符,数字和符号,然后不断地用if 和else if 等语句来塞选这些字符串,然后来对他们分别进行种别码的对应。运行完scaner这一个函数后就进入一个switch-case的句子,根据我所设置的sym种别码进行判断,当遇到种别码为29也就是$这个字符的时候,整个程序也就结束。
流程图 如下
3.主要程序段及解释
判定
void scaner() { /* 共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else */ for(n=0;n<7;n++) compare[n]=0;//每次循环完就清零 ch=All[i]; while(ch==' '||ch=='\n')//如果字符是空格或者回车,跳过 { i++; ch=All[i]; } if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是标示符或者变量名 { m=0; while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//找到一个变量名或者关键字,直到遇到空格为止 { compare[m]=ch;m++; i++;ch=All[i]; } compare[m]='\0'; //将识别出来的字符和已定义的标示符作比较, //因为定义的begin为1,if为2...... if(strcmp(compare,r1)==0){syn=1;} else if(strcmp(compare,r2)==0){syn=2; } else if(strcmp(compare,r3)==0){syn=3;} else if(strcmp(compare,r4)==0){syn=4;} else if(strcmp(compare,r5)==0){syn=5;} else if(strcmp(compare,r6)==0){syn=6;} else{syn=100;} //变量名 } else if((ch>='0'&&ch<='9')) //数字 { num=0; while((ch>='0'&&ch<='9')) { num=num*10+ch-'0';//显示其数字sum i++; ch=All[i]; } syn=7;//数字是7 } else switch(ch) //其他字符 { case'<':m=0;compare[m]=ch;m++; i++;ch=All[i]; if(ch=='=')//<=为21 { syn=21; compare[m]=ch;m++;i++; } else { syn=20;//<为20 } break; case'>':m=0;compare[m]=ch;m++; i++;ch=All[i]; if(ch=='=') { syn=24; compare[m]=ch;m++;i++; } else { syn=23; } break; case':':m=0;compare[m]=ch;m++; i++;ch=All[i]; if(ch=='=') { syn=18; compare[m]=ch;m++;i++; } else { syn=17; } break; case'"':syn=10;compare[0]=ch;i++;break; case',':syn=11;compare[0]=ch;i++;break; case'.':syn=12;compare[0]=ch;i++;break; case'+':syn=13;compare[0]=ch;i++;break; case'-':syn=14;compare[0]=ch;i++;break; case'*':syn=15;compare[0]=ch;i++;break; case'/':syn=16;compare[0]=ch;i++;break; case'=':syn=25;compare[0]=ch;i++;break; case';':syn=26;compare[0]=ch;i++;break; case'(':syn=27;compare[0]=ch;i++;break; case')':syn=28;compare[0]=ch;i++;break; case'#':syn=0;compare[0]=ch;i++;break; case'$':syn=29;compare[0]=ch;i++;break; case'{':syn=30;compare[0]=ch;i++;break; case'}':syn=31;compare[0]=ch;i++;break; case'\n':syn=-2;break; default: syn=-1;break; } }
输出
do { scaner();//进入函数进行判定 switch(syn) { case 7: printf("(%d,%d)\n",syn,num); break;//如果是7,那么就是数字 case 29: printf("(%d,%c)\n",syn,compare[0]);break;//如果是0,那么是$ 结束 case -2: row=row++;break; default: printf("(%d,%s)\n",syn,compare);break;//否则,就是变量名、关键词 } } while (syn!=29);
4.运行结果及截图
四、实验总结
对于,实现这个功能而言,我觉得初期的我是一脸蒙的,后来经过老师和同学的开导,才逐渐形成我的思想。这里最核心的东西也就是区分关键字,数字,特殊符号,然后给他们分配不同的种别码,然后一个一个输出来,虽然说起来简单,但是做起来很繁杂,比起其他同学做的,我觉得我的代码还有很多改善的地方,这也是我以后努力的地方,希望这里只是我的编译原理学习的第一步,下一步越走越扎实。