实验二词法分析器.doc_第1页
实验二词法分析器.doc_第2页
实验二词法分析器.doc_第3页
实验二词法分析器.doc_第4页
实验二词法分析器.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

魏陈强 23020092204168实验二 词法分析器一、实验目的掌握词法分析器的构造原理,掌握手工编程或LEX编程方法之一。二、实验内容编写一个词法分析器,能够输入的源程序转换为单词序列输出。三、实验要求 1可以采用手工或LEX开发工具,采用VC环境。2源语言定义见教材附录 A.1,其中的终结符即词法分析需要得到的tokens。(1)该语言的关键字:if while do break real true false int char bool float (其中,int、char、boolean、float在产生式中为basic)所有的关键字都是保留字,并且必须是小写。(2)id和num的正则表达式定义;(3)专用符号:+ - * / = = != = ; , ( ) /* */(4)空格由空白、换行符和制表符组成。空格通常被忽略,除了它必须分开I D、N U M关键字。(5)考虑注释。注释由/*和*/包含。注释可以放在任何空白出现的位置,且可以超过一行。注释不能嵌套。3实现词法分析器的注意要点:(1) 关键字和标识符名的区别;(2) 数字的转换处理;(3) “=”和“”这类单词的处理;4、 实验思路 本次实验,打算两种方法都使用。1、采用LEX开发工具编写,熟悉LEX语言的编写格式即可。2、手工编写 定义一个关键字数组,预先存入所以可能出现的关键字,并分 别创建两个关键字表、ID表、num表、专用符号表、注释表,以及一个作为缓存的数组。采用命令行读入语句形式,读入一行语句,设置while(1)循环分别读取每个字符,以n作为结束。读入一个字符,判断其属于哪个类别,然后通过调用函数转向那个类别所属的子程序去执行。比如,读入一个字符,判断出为字母,因此调用void alpha();进入字母处理子程序去,读取下个字符,如果为字母或者数字,则继续往下读,直到其既不是字母也不是数字为止,然后将从上个断点开始到目前为止的字符串存入缓存数组,并且把该缓存数组和关键字数组逐一比对,若该字符串为关键字,则存入关键字表,否则存入ID表。同理,如果接下去遇到数字,则转入void digit();中去,取得一个字符串后,判断字符串中是否有字母,如果有则存入ID表,如果没有,则存入digit表,即数字表。如果接下去遇到t和 ,则不做动作。如果遇到/,则转入void note();判断是否是注释,在注释判断中,通过判断字符串是否以/*开头并且以*/结尾,如果是,则存入注释表中,如果不是,则报错,因为出现了非法字符。最后,如果是都不属于上面任何一种情况的字符,则转入void otherchar();去判断是否是专用符号,void otherchar();中使用switch case,列出所有的专用符号。在遇到或者时,应该继续判断下一个字符是否是=,如果是,则匹配=。如果对case中所有情况都不满足,则输出错误,因为出现了非法字符。当语句扫描结束后,各个表中已经有了语句中出现的所有类型的字符串,现在要做的就是把各个表中重复出现的字符串去掉,通过分别再建一个与原表一样大小的表,如果原表中有东西,则把第一项复制到新表中,然后取原表第二项(如果有),与新表中所有项比较,如果都不一样,则加入新表,否则不加入,继续取下个项。最后输出各个表内容即可。5、 实验代码 1、手工编写#include#include#include char *keyword8=if,for,else,while,do,float,int,break;char keywordtable2020,re_keywordtable2020;char digittable2020,re_digittable2020;char otherchartable2020,re_otherchartable2020;char idtable2020,re_idtable2020;char notetable2020;char word20;void initialize();void alpha();void digit();void error();void otherchar();void print();void check();void note();int digit_num=0,keyword_num=0,otherchar_num=0,id_num=0,note_num=0; int redigit_num=1,rekeyword_num=1,reotherchar_num=1,reid_num=1; int flag_error=0;char lookahead;void main()printf(请输入要分析的语句:n);initialize();lookahead=getchar();while(1)if(isalpha(lookahead)alpha();initialize();else if(isdigit(lookahead)digit();initialize();else if(lookahead=t|lookahead= );else if(lookahead=n)break;else if(lookahead=/)lookahead=getchar();if(lookahead=*)note();initialize();elseungetc(lookahead,stdin);strcpy(otherchartableotherchar_num+,/);initialize();elseotherchar();initialize();lookahead=getchar();check();if(flag_error=0)print();void alpha()int i=1,flag;char ch;ch=lookahead;word0=ch;ch=getchar();while(isalpha(ch)|isdigit(ch)wordi+=ch;ch=getchar();ungetc(ch,stdin);flag=0;for(i=0;i8;i+)if(strcmp(word,keywordi)=0)flag=1;if(flag=1)strcpy(keywordtablekeyword_num+,word);elsestrcpy(idtableid_num+,word);void digit()int i=1,flag;char ch;ch=lookahead;word0=ch;ch=getchar();while(isalpha(ch)|isdigit(ch)wordi+=ch;ch=getchar();ungetc(ch,stdin);flag=0;for(i=0;wordi!=0;i+)if(wordi9)flag=1;if(flag=1)strcpy(idtableid_num+,word);elsestrcpy(digittabledigit_num+,word);void otherchar()char ch;ch=lookahead;switch(ch)case !:ch=getchar();if(ch=)strcpy(otherchartableotherchar_num+,!=);elseungetc(ch,stdin);error();break;case =:ch=getchar();if(ch=)strcpy(otherchartableotherchar_num+,=);elsestrcpy(otherchartableotherchar_num+,=);ungetc(ch,stdin);break;case (:strcpy(otherchartableotherchar_num+,();break;case ):strcpy(otherchartableotherchar_num+,);break;case ;:strcpy(otherchartableotherchar_num+,;);break;case :strcpy(otherchartableotherchar_num+,);break;case :strcpy(otherchartableotherchar_num+,);break;case |:strcpy(otherchartableotherchar_num+,|);break;case &:strcpy(otherchartableotherchar_num+,&);break;case +:strcpy(otherchartableotherchar_num+,+);break;case :ch=getchar();if(ch=)strcpy(otherchartableotherchar_num+,=);elsestrcpy(otherchartableotherchar_num+,);ungetc(ch,stdin);break;case :ch=getchar();if(ch=)strcpy(otherchartableotherchar_num+,=);elsestrcpy(otherchartableotherchar_num+,);ungetc(ch,stdin);break;default:error();break;void error()flag_error=1;printf(输入有误!n);void initialize()int i;for(i=0;i20;i+)wordi=0;void check()int i,j,flag;strcpy(re_keywordtable0,keywordtable0);for(i=1;ikeyword_num;i+)flag=0;for(j=0;jrekeyword_num;j+)if(strcmp(keywordtablei,re_keywordtablej)=0)flag=1;break;if(flag=0)strcpy(re_keywordtablerekeyword_num+,keywordtablei);strcpy(re_digittable0,digittable0);for(i=1;idigit_num;i+)flag=0;for(j=0;jredigit_num;j+)if(strcmp(digittablei,re_digittablej)=0)flag=1;break;if(flag=0)strcpy(re_digittableredigit_num+,digittablei);strcpy(re_otherchartable0,otherchartable0);for(i=1;iotherchar_num;i+)flag=0;for(j=0;jreotherchar_num;j+)if(strcmp(otherchartablei,re_otherchartablej)=0)flag=1;break;if(flag=0)strcpy(re_otherchartablereotherchar_num+,otherchartablei);strcpy(re_idtable0,idtable0);for(i=1;iid_num;i+)flag=0;for(j=0;jreid_num;j+)if(strcmp(idtablei,re_idtablej)=0)flag=1;break;if(flag=0)strcpy(re_idtablereid_num+,idtablei);void note()char ch;int i=0;ch=getchar();while(1)if(ch=*)ch=getchar();if(ch=/)break;elseungetc(ch,stdin);wordi+=ch;elsewordi+=ch;ch=getchar();strcpy(notetablenote_num+,word);void print()int i;/printf(Keywords:n);if(keyword_num!=0)for(i=0;irekeyword_num;i+)printf(n,re_keywordtablei);/printf(nDigits:n);if(digit_num!=0)for(i=0;iredigit_num;i+)printf(n,re_digittablei);/printf(nOtherchars:n);if(otherchar_num!=0)for(i=0;ireotherchar_num;i+)printf(n,re_otherchartablei);/printf(nId:n);if(id_num!=0)for(i=0;ireid_num;i+)printf(n,re_idtablei);if(note_num!=0)printf(注释:n);for(i=0;inote_num;i+)printf(%s ,notetablei);printf(n词法分析完成!n);2、 LEX%option noyywrap% #include #include #include %delim tnws delim+letter A-Za-zdigit 0-9id letter(letter|digit)*%ws if|while|do|break|real|true|false|int|char|bool|float printf(关键字:%sn,yytext);id printf(表示符:%sn,yytext);digit+ printf(整数:%sn,yytext);digit+.digit* printf(float型:%sn,yytext);+|-|*|/|=|=|!=|=|;|,|(|)|/*|*/ printf(算符:%sn,yytext);%int main() extern FILE *yyin; yyin=fopen(d:1.txt,r); yylex(); return 0;6、 实验结果1、手工编写2、 Lex 7、 实验心得遇到的问题:手工编写中,在判断字符串所属类别时,由于分支比较多,看得比较混乱,出现问题时调试比较麻烦。解决办法:假设输入的字符串只属于一种类别,然后编写各个分支情况的代码,最后再整合起来,这样至少可以保证,每个分支模块不会出错,调试的时候,只要把握大体即可发现问题。遇到的问题:曾经试图用0作为判断输入语句的结尾,结果导致错误。解决办法

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论