计算机22班编译原理实验报告词法_第1页
计算机22班编译原理实验报告词法_第2页
计算机22班编译原理实验报告词法_第3页
计算机22班编译原理实验报告词法_第4页
计算机22班编译原理实验报告词法_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

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

文档简介

1、编译原理词法分析器实验报告计算机 22 班2120505027郭朝彤二O 一四年十月一、实验目的:1强化对系统综合工程实现能力的训练;2加强对词法分析原理、方法和基本实现技术的理解;二、实验内容:用C 语言或者其他的高级语言作为宿主语言完成C1 语言的词法分析器的设计。三、实验流程图及状态转换图:四、源代码:(一)Lex:%#include #include #include yywrap(); lineno=1;%/给行号赋初值delim t ws delim+letter A-Za-zdigit 0-9/table 键/table 键的组合/字母/数字id letter(letter|di

2、git)* /id 是字母或字母和数字的组合number digit+error_id (digit)+(letter)+ enter n/数字的组合/在数字后面写字母是不合法的/ n 代表换行spchar (|(|)|;|=|,) ariop (+|-|*|/)relop (|=|=|!=)comment /*(*/|*)*/ reswd (|else|return|void|if|while)/给这些字符定义其属性%ws comment enter lineno+;/如果遇到“n”那么行数加 1reswd fprf(yyout,%d 行tkeywodt%sn,lineno,yytext);

3、 /输出行,字符,属性spchar fprf(yyout,%d 行tspchart%sn,lineno,yytext);id fprf(yyout,%d 行tidentifiert%sn,lineno,yytext);number fprf(yyout,%d 行tnumbert%sn,lineno,yytext);error_id fprf(yyout,%d 行terror_idt%sn,lineno,yytext);ariop fprf(yyout,%d 行tari_opt%sn,lineno,yytext);relop fprf(yyout,%d 行trel_opt%sn,lineno,y

4、ytext);%yywrap() return 1;main(void)yylex();return 0;(二)C 语言:#include #include #include #include #include #define KEYWORD_LEN 32#define STR_MAX_LEN 300#define PRO_MAX_LEN 20480#define STB_MAX_LEN 1000#define CTB_MAX_LEN 1000/保留字个数/标识符最大长度/源程序最大长度/符号表最大容量/常数表最大容量#define ERROR #define ID #define CONST

5、#define OPERAT0/错误(KEYWORD_LEN+1) (KEYWORD_LEN+2)(KEYWORD_LEN+3)/标识符/常量/运算符#define DIVIDE(KEYWORD_LEN+4)/界符errorLine=0; char proBuffchar ch;RO_MAX_LEN = ;/程序代码的全局缓冲区/读出来的当前字符/标识符 或 常量/源程序当前位置指针char wordgetSTR_MAX_LEN;po= 0;char signTabSTB_MAX_LENSTR_MAX_LEN;/符号表poSTB = 0;/符号表指针char constTabCTB_MAX_L

6、ENSTR_MAX_LEN;/常量表poCTB = 0;char kwTabKEYWORD_LEN10=/常数表指针/保留字表 C 语言一共有 32 个保留字关键字auto, continue, enum,if,short,switch, volatile,char errorTab50=break, default,extern,case,do,float,long,char,double,for,register,const,else,goto,return,signed, typedef,while;sizeof,union,sic,struct,unsigned,void,/错误代码表

7、/*0*/未知错误,/*1*/的字符,/*2*/不正确的字符常量表达,/*3*/不正确的字符串表达, row = 1;typedef struct signDualitykind; value;*pDualistic, Dualistic;/*4*/不正确的数字表达,/*5*/注释丢失*/;void pretreatment();/预处理/错误/获得一个字符不包括结束标记/获得一个非空白字符/将 ch 连接到 str 后/对 str 字符串查找保留字表 若是一个保留字-返回其编码 否则返void ProcError(bool GetChar(); bool GetBC();id);void C

8、oncat(char *str); Reserve(char *str);回 0void Retract();/将搜索指示器回调一个字符位置InsertId(char *str);/将 str 串以标识符符号表,并返回符号表指针InsertConst(char *str);/将 str 串以常数/词法分析 true 正常符号表,并返回常数表指针bool wordyse(pDualistic pDu);/预处理 将缓冲区内的源代码去掉注释和无效空格void pretreatment()lines=0;char tmpPRO_MAX_LEN;tmpp = 0;/先将处理结果保存到临时空间/这个临时

9、空间的末尾指针bool;char tmpc;/去掉注释先/注释有两种 一种是/ 另一种是/*/po do= 0;= GetChar();if(ch = /)= GetChar(); switch(ch)case /:do= GetChar();while(!(ch = n | if(ch = n)Retract(); break;case *:do= GetChar(); tmpc = ch;= false);/注释一直到行尾或文件结束/归还换行*/为了保证出错处理程序能正确定位出错位置 保留注释中的换行if(tmpc = n)tmptmpp+ = tmpc;= GetChar();Retra

10、ct();/归还一个字符while(& !(& tmpc = * & ch = /);= GetChar(); if (!)ProcError(5);break; default:Retract();Retract();/不是任何一种注释GetChar(); tmptmpp+ = ch;= GetChar();tmptmpp+ = ch;elsetmptmpp+ = ch;while();tmptmpp = 0; strcpy(proBuffer,tmp);/错误void ProcError(id)prf(nError:第%d 行,%sn,errorLine, errorTabid);/获得一

11、个字符 bool GetChar()if(po PRO_MAX_LEN & proBuffo != 0)/如果当前下标合法且当前字符为结束标记则取字符增游标ch = proBuffif (ch = n)o+;errorLine +;return true;ch = 0; return false;/获得一个非空白字符 bool GetBC()doif(ch = n)row+;/检测当前字所在的行数if(!GetChar()ch = 0;/获取字符失败return false;while(isspace(ch); return true;/直到获得一个非空白字符/将 ch 连接到 str 后vo

12、id Concat(char *str)i;for(i=0; stri; +i); stri = ch;stri+1 = 0;/对 str 字符串查找保留字表 若是一个保留字-返回其编码 否则返回 0 Reserve(char *str)i;for(i=0; i 0)errorLine -;-;po/将 str 串以标识符InsertId(char *str)i;for(i=0; i poSTB; +i)if(0 = strcmp(signTabi, str) return i;strcpy(signTabpoSTB+, str);return (poSTB-1);符号表,并返回符号表指针/将

13、 str 串以常数常量表,并返回常数表指针InsertConst(char *str)i;for(i=0; i kind = ID;pDu-value = value;elsepDu-kind = code;pDu-value = -1;return true; case D:while(isdigit(ch)wordgeti+ = ch; GetChar();wordgeti = 0; Retract();value = InsertConst(wordget); pDu-kind = CONST;pDu-value= value;return true;/(|/)|=-?:-+-.,+-=

14、! !=sizeof=&=|kind = ERROR;pDu-value = 0;elsevalue = InsertConst(wordget); pDu-kind = CONST;pDu-value = value;return true;/字符常量 case :wordgeti+ = ch;GetChar();/ wordgeti+ = ch;if(ch = )/ n/如果是转义字符则要多接收一个字符GetChar();wordgeti+ = ch;/ ch = GetChar(); wordgeti+ = ch; wordgeti = 0;if(ch != )/bprf(%s,word

15、get); ProcError(2);pDu-kind = ERROR; pDu-value = 0;elsevalue = InsertConst(wordget); pDu-kind = CONST;pDu-value = value;return true; case (:case ):case :case :case .:case ,:case :case ?:case :case ;:case :case :case #:wordgeti+ = ch;wordgeti = 0;pDu-kind = DIVIDE; /界符 pDu-value = -1;return true; cas

16、e !:/!=wordgeti+ = ch;GetChar();if (ch=) wordgeti+ = ch; else Retract();wordgeti=0; break;case :/ = wordgeti+ = ch; GetChar();if (ch = :/ = wordgeti+ = ch; GetChar();if (ch = | ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case =:/ =wordgeti+ = ch; GetChar();if (ch = =) wordgeti+ = ch; el

17、se Retract();wordgeti=0; break;case &:/ & &= wordgeti+ = ch; GetChar();if (ch = & | ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case |:/ | |= wordgeti+ = ch; GetChar();if (ch = | | ch = =) wordgeti+ = ch; else Retract();wordgeti=0;break; case +:/ + += wordgeti+ = ch; GetChar();if (ch =

18、+ | ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case -:/ - -= -wordgeti+ = ch; GetChar();if (ch = - | ch = = | ch = ) wordgeti+ = ch; else Retract();wordgeti=0; break;case *:/ * *= wordgeti+ = ch; GetChar();if (ch = * | ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case /:/ /

19、=wordgeti+ = ch; GetChar();if (ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case %:/ %= wordgeti+ = ch; GetChar();if (ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case :/ =wordgeti+ = ch;GetChar();if (ch = =) wordgeti+ = ch; else Retract();wordgeti=0; break;case 0:return fals

20、e; default:ProcError(1); return false;pDu-kind = OPERAT; return true;main()Dualistic tmp;pDualistic ptmp = &tmp; FILE *fin, *fout;i; char c;char filename20;prf(源代码读入n);/scanf(%s,filename);/将源程序读入缓冲区if (fin=fopen(Test.txt,rb) = NULL)prf(Cannot open infilen); return 0;i = 0;/c = fgetc(fin);while(c = f

21、getc(fin) != EOF)if(i = PRO_MAX_LEN-1)/读不进来就报错prf(n 程序代码太长,无法处理a);return 0;proBufferi+ = c;fclose(fin);/关闭文件proBufferi+ = 0;prf(n*n源 代 码 读 入 成 功 , 源 代 码 如下:n%s,proBuffer);prf(n 按任意键继续n); getch();/预处理prf(n 预处理n); pretreatment();prf(n*n 预 处 理 成 功 , 去 掉 注 释 后 的 源 代 码为:n%s*,proBuffer);pr getch();prpof(n

22、 按任意键继续n);f(n 词法分析n);= 0;/词法分析if (fout=fopen(Result.txt,wb) = NULL)prf(建立文件 Result.txt 失败。n); return 0;i = 0;errorLine = 0; do/错误行归零if(i+ PRO_MAX_LEN)/防止遇到 BUG break;if(!wordyse(ptmp)break;导致程序死循环无限写文件fprf(fout, %3d 行t,row);/为保持对齐,每个行数都占 3 个字节的位置switch(ptmp-kind)case ERROR:/不同类型的不同输出fprf(fout, 出 错:t

23、%s,wordget); break;case ID:fprf(fout, 标识符:t%s,wordget); break;case CONST:fprf(fout, 常 量:t%s,wordget); break;case OPERAT:fprf(fout, 运算符:t%s,wordget);break; case DIVIDE:fprf(fout, 界 符:t%s,wordget); break;default:;if(ptmp-kind = 1 & ptmp-kind kind-1);fprf(fout, rn);while(1); fclose(fout);prf(写回常量表和标识符表

24、n);/常量表if (fout=fopen(Const.txt,wb) = NULL)prf(建立文件 Const.txt 失败。n); return 0;for(i = 0; i poCTB; +i)fprf(fout, %3d %srn,i, constTabi); fclose(fout);/标识符表if (fout=fopen(Sign.txt,wb) = NULL)prf(建立文件 Sign.txt 失败。n); return 0;for(i = 0; i poSTB; +i)fprf(fout, %3d %srn,i, signTabi); fclose(fout);prf(n 写

25、入完毕n 按任意键继续n);getch();return 0;五、运行结果:(一) Lex:在 cmd 中按照如下的语句输入:直到生成的程序输出实例)。yse.txt 文件(test.txt 里面的内容是老师给yse.txt 文件中的内容:1 行1 行1 行1 行1 行1 行1 行1 行1 行行行2 行2 行行行3 行3 行3 行3 行行行keywod identifier spchar keywod identifier spchar keywod identifier spchar spchar identifier spchar number spchar identifier spch

26、ar identifier ari_op identifier spcharspcharvoid f1(5 行5 行keywod identifiermainspchar spchar spchar keywod identifier spchar number spchar spchar keywod identifier spchar identifier identifierspcharvoid10 行10 行10 行行行11 行11 行11 行11 行11 行行行12 行12 行12 行12 行12 行行行行spchar spchar identifier spchar keywod

27、spchar identifier rel_op identifier spchar spchar identifier spchar identifier spchar identifier spchar spchar spcharspchar=a;if (cb)f1 (a,b);5 行行行行7 行7 行7 行7 行行行8 行行行9 行9 行()a,b)a= 1;b=a+b;a 100;b;float c;a b10 行10 行10 行identifierspchar identifier(二) C 语言yse.cpp 所在的文件夹中新建 Test.txt , Result.txt , Const.txt , Sign.txt,运行程序。在程序运行结束后,Result.txt 中内容为:1 行1 行1 行1 行1 行1 行1 行1 行1 行行行2 行2 行行行3 行3 行3 行3 行行行行5 行5 行行行行7 行7 行7 行7 行关键字:标识符:界 符:关键字:标识符:界 符:关键字:标识符:界 符:界 符:标识符:运算符:常 量:界 符:标识符:运

温馨提示

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

评论

0/150

提交评论