1、实验目的算法
经过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程当中将其分解为各种单词的词法分析方法。编制一个读单词过程,从输入的源程序中,识别出各个具备独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类,并依次输出各个单词的内部编码及单词符号自身值。函数
2、实验内容和要求测试
实验内容:用C语言对源程序进行词法分析。经过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,而后跳过错误部分继续显示;同时进行标识符登记符号表的管理。编码
如下是实现词法分析设计的主要工做:(1)从源程序文件中读入字符(2)统计行数和列数用于错误单词的定位。(3)删除空格类字符,包括回车、制表符空格。(4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token的机内表示)(5)若是发现错误则报告出错(6)根据须要是否填写标识符表供之后各阶段使用。spa
实验要求:命令行
1.待分析的简单的词法设计
(1)保留字:if,else, for, while, do, int ,read, write,real,char 调试
(2)纯单分界符:+ — * (){};:, code
(3)双分界符:> < = ! ,&&,||blog
2.实现功能:
(1)在命令行中输入源程序文件名(包括文件名路径)
(2)输入目标文件名(包括文件名路径)
(3)调用所编词法分析代码将分析结果写入目标文件代码(编译完成)
3、 实验方法、步骤及结果测试
1. 源程序名:词法分析.zip 中源程序名:词法分析.c
可执行程序名:词法分析.exe
2. 原理分析及流程图
主要算法:算法的基本任务是从输入的字符串表示的源程序中识别出具备独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
存储结构:顺序存储结构
关键函数的实现:经过扫描函数对输入的字符串进行一一扫描
注:关键字做为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,不然为通常标识符。
3. 流程图:
4.主要程序段及其解释:
void scaner()
{ /*共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else */ for(n=0;n<7;n++) TOken[n]=0;//每次循环完就清零 ch=A[i]; while(ch==' '||ch=='\n')//若是字符是空格或者回车,跳过 { i++; ch=A[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'))//找到一个变量名或者关键字,直到遇到空格为止 { TOken[m]=ch;m++; i++;ch=A[i]; } TOken[m]='\0';//将识别出来的字符和已定义的标示符做比较, //由于定义的begin为1,if为2...... if(strcmp(TOken,r1)==0){syn=1;} else if(strcmp(TOken,r2)==0){syn=2; } else if(strcmp(TOken,r3)==0){syn=3;} else if(strcmp(TOken,r4)==0){syn=4;} else if(strcmp(TOken,r5)==0){syn=5;} else if(strcmp(TOken,r6)==0){syn=6;} else if(strcmp(TOken,r7)==0){syn=7;} else if(strcmp(r8,TOken)==0){syn=8;} else if(strcmp(r9,TOken)==0){syn=9;} else if(strcmp(r10,TOken)==0){syn=10;} else if(strcmp(r11,TOken)==0){syn=11;} else if(strcmp(r12,TOken)==0){syn=12;} else if(strcmp(r13,TOken)==0){syn=13;} else if(strcmp(r14,TOken)==0){syn=14;} else if(strcmp(r15,TOken)==0){syn=15;} else if(strcmp(r16,TOken)==0){syn=16;} else if(strcmp(r17,TOken)==0){syn=17;} else if(strcmp(r18,TOken)==0){syn=18;} else if(strcmp(r19,TOken)==0){syn=19;} else if(strcmp(r20,TOken)==0){syn=20;} else if(strcmp(r21,TOken)==0){syn=21;} else if(strcmp(r22,TOken)==0){syn=22;} else if(strcmp(r23,TOken)==0){syn=23;} else if(strcmp(r24,TOken)==0){syn=24;} else if(strcmp(r25,TOken)==0){syn=25;} else if(strcmp(r26,TOken)==0){syn=26;} else if(strcmp(r27,TOken)==0){syn=27;} else if(strcmp(r28,TOken)==0){syn=28;} else if(strcmp(r29,TOken)==0){syn=29;} else if(strcmp(r30,TOken)==0){syn=30;} else if(strcmp(r31,TOken)==0){syn=31;} else if(strcmp(r32,TOken)==0){syn=32;} else if(strcmp(r33,TOken)==0){syn=33;} else if(strcmp(r34,TOken)==0){syn=34;} else if(strcmp(r35,TOken)==0){syn=35;} else if(strcmp(r36,TOken)==0){syn=36;} else if(strcmp(r37,TOken)==0){syn=37;} else if(strcmp(r38,TOken)==0){syn=38;} else{syn=100;} //变量名 } else if((ch>='0'&&ch<='9')) //数字 { sum=0; while((ch>='0'&&ch<='9')) { sum=sum*10+ch-'0';//显示其数字sum i++; ch=A[i]; } syn=40; } else switch(ch) //其余字符 { case'<':m=0;TOken[m]=ch;m++; i++;ch=A[i]; if(ch=='=')//<>为22 { syn=41; TOken[m]=ch;m++;i++; } else { syn=46; } break; case'>':m=0;TOken[m]=ch;m++; i++;ch=A[i]; if(ch=='=') { syn=42; TOken[m]=ch;m++;i++; } else { syn=47; } break; case':':m=0;TOken[m]=ch;m++; i++;ch=A[i]; if(ch=='=') { syn=44; TOken[m]=ch;m++;i++; } else { syn=49; } break; case'@':syn=0; TOken[0]=ch; i++; break; case'=':syn=48; TOken[0]=ch; i++; break; case'#':syn=50; TOken[0]=ch; i++; break; case'+':syn=50; TOken[0]=ch; i++; break; case'-':syn=51; TOken[0]=ch; i++; break; case'*':syn=52; TOken[0]=ch; i++; break; case'/':syn=53; TOken[0]=ch; i++; break; case'(':syn=54; TOken[0]=ch; i++; break; case')':syn=55; TOken[0]=ch; i++; break; case'{':syn=56; TOken[0]=ch; i++; break; case'}':syn=57; TOken[0]=ch; i++; break; case';':syn=58; TOken[0]=ch; i++; break; case'.':syn=59; TOken[0]=ch; i++; break; case'\'':syn=60; TOken[0]=ch; i++; break; case'\n': syn=-2; break; default: syn=-1; break; } }
5. 运行结果及分析