下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年兰溪市卫健系统第一批面向高校公开招聘医学类应届毕业生17人的备考题库及一套答案详解
- 2025年民生银行沈阳分行社会招聘备考题库及参考答案详解一套
- 2026年度新疆生产建设兵团医院高层次人才引进20人备考题库及一套完整答案详解
- 2025年民生银行天津分行社会招聘备考题库及1套参考答案详解
- 跨境电商平台入驻协议(合规·引流版)
- 2025年宁波市机关事务管理局下属事业单位公开选聘工作人员备考题库及一套完整答案详解
- 洛阳市城乡一体化示范区招聘城市管理辅助人员笔试真题2024
- 2026年中国人民银行上海票据交易所校园招聘备考题库及答案详解参考
- 2025年上海市化工职业病防治院(上海市职业安全健康研究院)工作人员公开招聘18人备考题库含答案详解
- 2025年复旦大学类脑智能科学与技术研究院招聘产业化科研助理岗位备考题库完整答案详解
- 国际法学(山东联盟)知到智慧树章节测试课后答案2024年秋烟台大学
- 餐厅治安事件应急预案
- 新版投资合同样本
- 智能垃圾分类设备
- 第五版DFMEA和PFMEA的措施优先级AP
- OSCE考核设计案例
- 部编版二年级语文上册第八单元测试卷
- DL-T5394-2021电力工程地下金属构筑物防腐技术导则
- QCT1011-2023汽车离合器总泵
- HYT 082-2005 珊瑚礁生态监测技术规程(正式版)
- MA01C智能电源监测系统使用手册
评论
0/150
提交评论