您好,欢迎访问三七文档
1.实验目的及要求1、目的通过设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。2、要求根据具体情况,由同学们自己选取C语言的一个适当大小的子集(可取一类典型单词,也可以尽可能使各种类型的单词都兼顾到);在实习前一定要制出相应的表。实验时间:4-8学时检查内容及时间:A)完整的实验报告。B)在机器上调试成功的源程序。3、软件、硬件环境Visualstudio2010,Windows7操作系统计算机一台2.实验步骤分析对于单词符号我们将其分成四类:保留字K、标识符I、常数C和界符P,每类单词符号均可使用一张表格表示.在词法分析过程中,保留字K和界符P这两个表格的内容是固定不变的(由语言确定),源程序字符串只能从其中选取,而标识符I、常数C这两表是在分析过程中不断形成的.对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是K、I、C或P中之一,那么就以单词的二元式形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串.各类单词的二元式表述均具有相同的结构与长度,形式如下:(单词种别t,单词自身的值i)t是单词种别,而单词种别共分为K、I、C、P四类且每类对应一张表格.因此,t实际上就是一个指向这四类中某一类对应表格的指针.i则为指向该类表格中一个特定项目的指针.所以整个的词法分析过程就是从源程序中获得一个个的单词符号,将这些符号分别填入四张类表中,并且有一个二元式序列构成一个索引,这个索引为以后的语法分析提供处理上的方便.为了减少实习量,可以适量地选取K,P中的一个子集来进行.如下表:表1保留字K表内部地址12345678910保留字forwhileDOELSEIFSTATICINTSIZEOFBREAKCONTINUE表2界符P表内部地址123456789101112131415161718南华大学计算机科学与技术学院实验报告界符+-*/==!====(),:;{}表3单词符号的编码单词符号类别编码标识符1常数2保留字3+4-5*6/78=910=11!=12==13=14(15)16,17:18;19{20}21保留字表包括10个有代表性的保留字,界符表包括关系运算符,算术运算符,分隔符三种,一对圆括号,加上赋值号,花括号,分号,引号.这两表的内容表明C语言的条件语句,赋值语句,WHILE型循环语句,复合语句,过程及变量说明均可作为源程序例子输入给词法分析程序,标识符表I中的每一项包含一个标识符,常数表C中的每一项包含一个整常数,后两表的内容都是在词法分析过程中产生的.如何从源程序中识别出一个个的单词符号呢?图1中的流图清晰地反映出这一过程.图1中,双圆圈的状态表示终态,即能到达终态就代表识别出一个单词符号,而带有*号的终态是指处理时应回退一字符.算法词法分析器在扫描过程中,依次从源程序中取出源字符,根据图1的扫描过程状态转换图,当碰到终态时,即双圆圈的状态时就得到一个单词符号,此时可以根据第一个字符判断单词属于K,I,C,P中哪一个类,从而确定单词的“单词种别”和“单词自身的值”。南华大学计算机科学与技术学院实验报告说明:这个图只是大概表达一个词法分析的思路,由于不知道加入,所以并不完全准确。2字母非字母与数字1字母与数字0空白4数字非数字3数字+6;58:非=7=9(10,11)12其它1714非=131516=图1扫描程序的状态转换图南华大学计算机科学与技术学院实验报告2.实验内容流程图、程序源程序#includestdio.h#includestring.h#includectype.h#includestdlib.h#includeassert.h#defineLENGTH110//定义保留字的大小其它界符数字字母出错处理有C表有此单词否?形成一项无形成(C,i)十进制数转化成二进制数K表有此单词否?形成(I,i)形成(K,i)有无查界符表形成(P,i)源程序完否?输出二元式开始开始对源程序扫描扫描到的单词符号首字母是什么?完未完图2词法分析算法流图南华大学计算机科学与技术学院实验报告FILE*fp=NULL;//输出流指针FILE*fw=NULL;//输入流指针charcharacter;//字符chartoken[16];//字符数组,用来存放已读入的字符序列//编码表char*CODE[]={identifier/*标识符*/,constant/*常数*/,keyword/*保留字*/,+,-,*,/,,=,,=,!=,==,=,(,),,,:,;,{,}};//保留字表char*k[]={for,while,do,else,if,static,int,sizeof,break,continue};//标识符结构体typedefstruct{char*I[256];//标识符数组intlen;//标识符数量}identifier;//常量结构体typedefstruct{intcont[300];//存放常量的数组intlen;//常量的数目}constnumber;//读入一个字符,从输入流中读入一个字符到变量character中。voidgetNextChar(FILE*ifp){if((character=getc(ifp))==EOF)exit(1);}//读入非空白字符,检查变量character中的字符是否为空白字符或回车或换行符。若是,//则调用getNextChar()读入下一个字符,直到character中的字符满足条件.voidgetnbc(FILE*ifp){while(character==''||character=='\n'||character==9){getNextChar(ifp);}}//连接字符串,把character中的字符连接到token数组的结尾。voidconcat(){char*ct=&character;strcat(token,ct);}南华大学计算机科学与技术学院实验报告//判断是否为字母。intletter(){returnisalpha(character);}//判断是否为数字intdigit(){returnisdigit(character);}//回退字符,将刚读入的character中的字符回退到输入流中。并把character中的值置为空。voidretract(FILE*ifp){(ifp-_cnt)++;(ifp-_ptr)--;character='';}//处理保留字,对存放在token中的字符串查保留字,若查到,则返回该保留字的类别编码,否则返回0.intreserve(char**k){inti;for(i=0;iLENGTH1;i++)if(strcmp(token,k[i])==0)returni+1;return0;}//处理标识符,对存放在token中的字符串查找符号表,若查到,则返回它在符号表的位置,//存入常数表中,并返回它在常数表中的位置编号。intsymbol(identifier*id){inti;for(i=0;iid-len;i++)if(strcmp(token,id-I[i])==0)returni+1;if(id-len256)assert(0);id-I[id-len]=token;id-len++;returnid-len;}//将数字字符串转化为整数。intstrtonumber(){南华大学计算机科学与技术学院实验报告inti;intsum=0;for(i=0;istrlen(token);i++){sum=10*sum+(token[i]-'0');}returnsum;}//常数存入常数表的函数,将token中的数字串(实际上是字符串),转化成标准的二进制值(整数值)//存入常数表中,并返回它在常数表中的位置编号。intconstant(constnumber*con){con-cont[con-len]=strtonumber();con-len++;returncon-len;}//将整数值转化为字符串char*numbertoString(intnum){chars[3];inti=num/10;while(i0){charc=i+'0';strcat(s,&c);}returns;}//将结果写入到文件并且输出到屏幕。voidreturntofile(intnum,intval,identifier*id,constnumber*con){inti;int_num=num;charc;c='(';putc(c,fw);printf(%c,c);i=_num/10;while(i0){_num=_num-10*i;c=(i+'0');printf(%c,c);putc(c,fw);i=_num/10;}c=_num+'0';南华大学计算机科学与技术学院实验报告printf(%c,c);putc(c,fw);printf(,);putc(',',fw);//如果是标识符或常数则放入括号内。if(num==1)//处理标识符{printf(%s,id-I[val-1]);printf());printf(\n);fputs(id-I[val-1],fw);putc(')',fw);putc('\n',fw);}if(num==2)//处理常数{_num=con-cont[val-1];i=_num/10;while(i0){_num=_num-10*i;c=(i+'0');printf(%c,c);putc(c,fw);i=_num/10;}c=_num+'0';printf(%c,c);printf());printf(\n);putc(c,fw);putc(')',fw);putc('\n',fw);}if(num==3)//保留字{printf(-);printf());printf();printf(#);printf(%s,k[val-1]);printf(#);printf(\n);putc('-',fw);putc(')',fw);fputs(,fw);putc('#',fw);fputs(k[val-1],fw);南华大学计算机科学与技术学院实验报告putc('#',fw);putc('\n',fw);}if(num3)//处理界符{printf(-);printf());printf();printf(#);printf(%s,CODE[num-1]);printf(#);printf(\n);putc('-',fw);putc(')',fw);fputs(,fw);putc('#',fw);fputs(CODE[num-1],fw);putc('#',fw);putc('\n',fw);}}//将错误写入到文件或输出到屏幕voiderror(){printf((ERROR,);printf(%c,character);printf());printf(\n);fputs((ERROR,,fw);putc(character,fw);putc(')',fw);putc('\n',fw);}//词法分析函数voidLexAnalyze(char**k,char**CODE,identifier*id,constnumber*con,FILE*fp,FILE*fw){intnum,val;strcpy(token,);getNextChar(fp);getnbc(fp);switch(character){case'a':case'b':case'c':case'd':case'e':南华大学计算机科学与技术学院实验报告case'f':case'g':case'h':case
本文标题:C语言词法分析器
链接地址:https://www.777doc.com/doc-3970504 .html