版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 实验1:用Lex设计词法分析器1实验目的:学会用lex设计一个词法分析器。实验内容:使用lex为下述文法语言写一个词法分析器。实验要求:输入为用该语言所写的源程序文件;输出为记号序列,每个记号显示为二元组(记号名,记号属性值)的形式。输出可以在屏幕上,也可以输出到文件中。不要求建立符号表。在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的测试例的测试。实验参考:和。语言文法: PROGRAM ; BEGIN END. VAR ;: | : ; INTEGER | REAL | , | ; | | | := IF THEN ELSE W
2、HILE DO BEGIN END | + | - | * | / | | () | | | | . | . | | =| A | B | | X | Y | Z | a | b | | x | y | z0|1|2|9程序代码:%#include #define LT1#defineLE2#define GT3#defineGE4#defineEQ5#define NE6#define PROGRAM 7#define END13#define VAR9#define IF10#define THEN 11#define ELSE 12#define WHILE18#defineDO19#d
3、efine ID 20#define NUMBER 21#define RELOP 22#define NEWLINE 23#define ERRORCHAR 24%delim t nwsdelim+letter A-Za-zdigit 0-9id_|letter(letter|digit)*numberdigit+(.digit+)?(E+-?digit+)?int1 digit|digitint1*/%s COMMENT%/*BEGIN COMMENT;ECHO;*/BEGIN INITIAL;ECHO;.|nECHO; /* ECHO是一个宏,相当于 fprintf(yyout, %s,
4、 yytext)*/ws ;whilereturn (WHILE);do return (DO);PROGRAM return (PROGRAM);end return (END);VAR return (VAR);if return (IF);then return (THEN);else return (ELSE);id return (ID);number return (NUMBER); return (RELOP);= return (RELOP);= return (RELOP); return (RELOP); return (RELOP);= return (RELOP);+
5、return (RELOP);- return (RELOP);* return (RELOP);/ return (RELOP);:= return (RELOP); return (RELOP);. return (RELOP);, return (RELOP);.return ERRORCHAR;%int yywrap () return 1;void writeout(int c) switch(c) case ERRORCHAR: fprintf(yyout, (ERRORCHAR, %s) , yytext);break; case RELOP: fprintf(yyout, (R
6、ELOP, %s) , yytext);break; case WHILE: fprintf(yyout, (WHILE, %s) , yytext);break; case DO: fprintf(yyout, (DO, %s) , yytext);break; case NUMBER: fprintf(yyout, (NUM, %s) , yytext);break; case ID: fprintf(yyout, (ID, %s) , yytext);break; case NEWLINE: fprintf(yyout, n);break; case PROGRAM: fprintf(y
7、yout, (PROGRAM, %s) , yytext);break; case END: fprintf(yyout, (END, %s) , yytext);break; case VAR: fprintf(yyout, (VAR, %s) , yytext);break; case IF: fprintf(yyout, (IF, %s) , yytext);break; case THEN: fprintf(yyout, (THEN, %s) , yytext);break; case ELSE: fprintf(yyout, (ELSE, %s) , yytext);break; d
8、efault:break; return;int main (int argc, char * argv)int c,j=0;if (argc=2) if (yyin = fopen(argv1, r) = NULL) printf(Cant open file %sn, argv1); return 1; if (argc=3) yyout=fopen(argv2, w); while (c = yylex()writeout(c);j+;if (j%5 = 0) writeout(NEWLINE);if(argc=2) fclose(yyin); if (argc=3) fclose(yy
9、out);return 0;测试文件为:PROGRAM test;VAR i, j, k: INTEGER; f0: REAL;BEGIN i := 1; j := 1; k := 0; f0 := ; WHILE k=100 DO BEGIN IF j S or S | S and S | not S | (S) | true | false,其中优先级or and not,or 和 and 左结合,not 右结合。用非二义文法实现作为选作内容,非二义文法请参照表达式非二义文法自己写出来。在cygwin下用flex,bison和gcc工具将实验调试通过,并写出测试例测试正确性。实验参考:ca
10、lculator0-3这四个例子。程序代码:文件:%int yylex(); #define YYSTYPE double /* 将Yacc栈定义为double类型 printf(nThe value of the expression is %lf.n, $1);*/%token NUM LPAREN RPAREN ENTER %left OR%left AND%right NOT%left PLUS MINUS%left TIMES DIVIDE%right UMINUS% /* 这样写prog可以让分析器每次读入一行进行分析,下一行重新分析expr */prog : prog exprp
11、 | exprp ;exprp : expr ENTER printf(1 表示 true;0 表示 false %lf.n, $1);shuchu($1); ;expr : expr PLUS expr$ = $1 + $3;| expr MINUS expr $ = $1 - $3;| expr TIMES expr $ = $1 * $3;| expr DIVIDE expr $ = $1 / $3;| LPAREN expr RPAREN $ = $2;| MINUS expr $ = -$2;| NUM $ = $1; | expr OR expr $=panduan($1*$1+$
12、3*$3); | expr AND expr $=panduan($1*$3); | NOT expr $=panduan2($2);%int main()yyparse();return 0;文件:%#include #include int yywrap(void) return 1;#define LT1#defineLE2#define GT3#defineGE4#defineEQ5#define NE6#define PROGRAM7#define END13#define VAR9#define IF10#define THEN 11#define ELSE 12#define W
13、HILE18#defineDO19#define ID 20#define RELOP 22#define NEWLINE 23#define ERRORCHAR 24%ws t+digit 0-9inumdigit+fnum digit*.digit+letterA-Za-zid_|letter(letter|digit)*%inum sscanf(yytext, %lf, &yylval); return NUM;fnumsscanf(yytext, %lf, &yylval); return NUM;+return PLUS;*return TIMES;-return MINUS;/re
14、turn DIVIDE;(return LPAREN;)return RPAREN;or return OR;and return AND;not return NOT;return LT;return GT;=return GE;= return EQ;!= return NQ;:= return FZ;ws;nreturn ENTER;. printf(nLEX:ERROR! c=%sn, yytext);/*BEGIN COMMENT;ECHO;*/BEGIN INITIAL;ECHO;whilereturn (WHILE);do return (DO);PROGRAM return (
15、PROGRAM);end return (END);VAR return (VAR);if return (IF);then return (THEN);else return (ELSE);id return (ID);%int panduan(double a)if(a!=0) a=1;return a;int panduan2(double a)if(a=0) a=1;else if(a!=0) a=0;return a;int shuchu(double a)if(a=0)printf(false);else if (a!=0)printf(true);return 1;运行程序:实验
16、4:用Yacc设计语法分析器1实验目的:学习如何使用Yacc设计一个语法分析器,并与用lex写的词法分析器链接起来。实验内容:使用yacc为课程设计实验1所给的语言写一个语法分析器(你可以重新设计该语言的文法,但不能改变语言)。其中,词法分析使用课程设计实验2中已完成的词法分析器(即,你需要将本实验的语法分析器和实验2的词法分析器链接起来)。实验要求:输入为实验1所给语言写的源程序文件;输出为屏幕显示语法分析是否成功。在语法分析中不能出现任何的冲突(移进-归约或归约-归约冲突),或者虽然有冲突,但是你能够说清楚冲突是如何解决的。在cygwin下用flex,bison和gcc工具将实验调试通过,
17、并且你写的语法分析器至少应该能通过例子parser0中testcases目录下的和两个测试例的测试。实验参考:可以在例子parser0的基础上进行修改;如果你尚不能将实验2的词法分析器和本实验的语法分析器链接起来,可以暂时使用parser0给出的词法分析器(前提是你的语法分析器中终结符名的定义与parser0的相同)。程序代码:%int yylex(); #define YYSTYPE double /* 将Yacc栈定义为double类型 printf(nThe value of the expression is %lf.n, $1);*/%token NUM LPAREN RPAREN
18、ENTER %left OR%left AND%right NOT%left PLUS MINUS%left TIMES DIVIDE END%right UMINUS BEGIN VAR %nonassoc PROGRAM%union int inum; double fnum; char * id;% /* 这样写prog可以让分析器每次读入一行进行分析,下一行重新分析expr prog : prog exprp | exprp ;exprp : expr ENTER printf(1 表示 true;0 表示 false %lf.n, $1);shuchu($1); ;expr : ex
19、pr PLUS expr$ = $1 + $3;| expr MINUS expr $ = $1 - $3;| expr TIMES expr $ = $1 * $3;| expr DIVIDE expr $ = $1 / $3;| LPAREN expr RPAREN $ = $2;| MINUS expr $ = -$2;| NUM $ = $1; | expr OR expr $=panduan($1*$1+$3*$3); | expr AND expr $=panduan($1*$3); | NOT expr $=panduan2($2);*/prog : PROGRAM biaosh
20、ifu fenpro |fenpro |biaoshifu ;biaoshifu:ID ;fenpro :blsm BEGIN yjb END |blsm printf(BEGIN n ); |yjb printf(END n); ;blsm: VAR blsmb printf(VAR); |blsmb ;blsmb:blb MH leixing |blb MH leixing blsmb |blb |leixing ;leixing:INTEGER printf(INTEGER); |REAL printf(REAL); ;blb:bl$ = $1; |bl DH blb ;bl:NUM $
21、 = $1; ;yjb:yj |yj yjb ;yj:fzyj |tjyj |whileyj |fhyj ;fzyj:bl FZ bds $ = $3; |bl |bds ;bds:guanxi $ = $1; |suanshu $ = $1; ;tjyj:IF guanxi THEN yj ELSE yj |guanxi |yj ;whileyj:WHILE guanxi DO yj printf(WHILE); |guanxiprintf(DO); |yj ;fhyj:BEGIN yjb ENDprintf(BEGIN); |yjb printf(END); ;suanshu:xiang
22、|suanshu PLUS suanshu $ = $1 + $3; |suanshu MINUS xiang$ = $1 - $3; ;xiang:yinshi |xiang*yinshi$ = $1 * $3; |xinag/yinshi$ = $1 / $3; ;yinshi:bl$ = $1; |NUM$ = $1; |LPAREN suanshu RPAREN $ = $2; ;guanxi:suanshu LT suanshu $=bijiao1($1,$3); |suanshu GT suanshu $=bijiao2($1,$3); |suanshu LQ suanshu $=
23、bijiao3($1,$3); |suanshu GQ suanshu $=bijiao4($1,$3); |suanshu EQ suanshu $=bijiao5($1,$3); |suanshu NQ suanshu $=bijiao6($1,$3); ;%int main()yyparse();return 0;%#include #include int yywrap(void) return 1;#define LT1#defineLE2#define GT3#defineGE4#defineEQ5#define NE6#define IF10#define THEN 11#def
24、ine ELSE 12#define WHILE18#defineDO19#define ID 20#define RELOP 22#define NEWLINE 23#define ERRORCHAR 24%ws t+digit 0-9inumdigit+fnum digit*.digit+letterA-Za-zid_|letter(letter|digit)*%s COMMENT%inum sscanf(yytext, %lf, &yylval); return INUM;fnumsscanf(yytext, %lf, &yylval); return FNUM;+return PLUS
25、;*return TIMES;-return MINUS;/return DIVIDE;(return LPAREN;)return RPAREN;or return OR;and return AND;not return NOT;return LT;return GT;=return GE;= return EQ;!= return NQ;:= return FZ;: return MH;, return DH; teturn FH;ws;nreturn ENTER;. printf(nLEX:ERROR! c=%sn, yytext);/*BEGIN COMMENT;ECHO;*/BEG
26、IN INITIAL;ECHO;whilereturn (WHILE);do return (DO);PROGRAM return (PROGRAM);end return (END);VAR return (VAR);if return (IF);then return (THEN);else return (ELSE);id return (ID);%int panduan(double a)if(a!=0) a=1;return a;int panduan2(double a)if(a=0) a=1;else if(a!=0) a=0;return a;int shuchu(double
27、 a)if(a=0)printf(false);else if (a!=0)printf(true);return 1;int bijiao1(double a,double b)if(ab)return 1;else return -1;int bijiao3(double a,double b)if(a=b)return 1;else return -1;int bijiao5(double a,double b)if(a=b)return 1;else return -1;int bijiao6(double a,double b)if(a!=b)return 1;else return
28、 -1;实验5:用Yacc设计语法分析器2实验目的:学习如何使用Lex和Yacc设计一个语法分析器,并学习如何在语法分析的同时生成分析树。实验内容:修改实验4,给产生式加上动作,动作为生成一棵语法分析树。这棵分析树的结构可以使用或参照例子parser1中文件中定义的分析树结构。实验要求:输入为实验1所给语言写的源程序文件;输出为一棵语法分析树,这棵语法分析树的表示方法可以是这样两种:1.将分析树的数据结构打印出来;2.按分析树的结构输出一个C语言源程序文件(即输入是所给语言的源程序文件,输出为语义相同的C语言源程序文件)。在cygwin下用flex,bison和gcc工具将实验调试通过,并且你
29、写的语法分析器至少应该能通过例子parser1中testcases目录下的和两个测试例。实验参考:可以参考例子parser1或在它的基础上进行修改;如果你尚不能将实验2的词法分析器和本实验的语法分析器链接起来,可以暂时使用parser1给出的词法分析器(前提是你的语法分析器中终结符名的定义与parser1的相同)。你也可以在自己的语法分析器中直接使用parser1已经提供的输出方式(打印分析树的数据结构),但前提是你必须使用parser1提供的分析树结构()。程序代码:%#include #include */ PROGRAM BEGINN END VAR IF WHILE DO /* 关键字
30、:PROGRAM BEGIN END VAR IF WHILE Do */ THEN ELSE /* 关键字:THEN ELSE */ ASSIGN EQ NEQ LT LE GT GE /* 符号 := = = */ PLUS MINUS TIMES DIVIDE /* 符号 + = * / */%start program /* 定义各个非终结符的属性值类型,实验8需要修改此处 */%type program%type bianliangbiao declist vardec%type fuhe xunhuan tiaojian fuzhi yuju stmts%type exp yins
31、hi xiang suanshu %type guanxi%program:PROGRAM ID SEMICOLON vardec BEGINN stmts END PERIODprogram = A_Prog(EM_tokPos, $2, $4, $6);vardec : VAR declist $ = $2;declist : bianliangbiao COLON INTEGER SEMICOLON $ = A_DecList(A_VarDec(EM_tokPos, $1, T_int), NULL); | bianliangbiao COLON INTEGER SEMICOLON de
32、clist $ = A_DecList(A_VarDec(EM_tokPos, $1, T_int), $5); | bianliangbiao COLON REAL SEMICOLON $ = A_DecList(A_VarDec(EM_tokPos, $1, T_real), NULL); | bianliangbiao COLON REAL SEMICOLON declist $ = A_DecList(A_VarDec(EM_tokPos, $1, T_real), $5); bianliangbiao : ID $ = A_VarList(A_Id(EM_tokPos, $1), N
33、ULL); | ID COMMA bianliangbiao $ = A_VarList(A_Id(EM_tokPos, $1), $3); ; stmts : yuju $ = A_StmList($1,NULL); | yuju SEMICOLON stmts $ = A_StmList($1,$3); ;yuju : fuzhi $ = $1; | tiaojian $ = $1; | xunhuan $ = $1; | fuhe $ = $1; ; fuzhi : ID ASSIGN suanshu$ = A_Assign(EM_tokPos, A_Id(EM_tokPos, $1),
34、 $3);tiaojian : IF guanxi THEN yuju ELSE yuju $ = A_If(EM_tokPos, $2, $4, $6); ;xunhuan : WHILE guanxi DO yuju $ = A_While(EM_tokPos, $2, $4); ; fuhe : BEGINN stmts END $ = A_Seq(EM_tokPos, $2); ; suanshu : xiang $ = $1; | suanshu PLUS xiang $ = A_OpExp(EM_tokPos, A_plusOp, $1, $3); | suanshu MINUS xiang$ = A_OpExp(EM_tokPos, A
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宾馆信息守秘保证承诺书3篇
- 山东省济南市高新区重点名校2026年语文试题基地校初三毕业班总复习平面向量、复数形成性测试卷语文试题试卷含解析
- 企业网络安全防护年度评估IT部门预案
- 粮库储存粮质量保证承诺书(8篇)
- 2026年财务数据分析与可视化报告
- 2026年高值医用耗材行业未来五年集采影响预测
- 历史隋唐时期的科技与文化课件2025-2026学年统编版七年级历史下册
- 餐饮服务双语·第二版课件 项目七 席间服务
- 水土保持方案报告表公示(模板)
- 管网回填施工方案(3篇)
- 矿山爆破技术规定方案
- 汽车评估考试题及答案
- 三国演义经典三顾茅庐剧本
- 校企联合人才培养制度实施细则
- 北京市房屋修缮工程计价依据-预算消耗量标准古建筑工程(下册)2021
- 毛概教学课件
- 角磨机安全教育培训课件
- 2024年医学影像检查技术专升本试题(含参考答案)
- 阿克苏热力管理办法
- 热风炉燃烧与平衡计算
- 西工大航空发动机燃烧学讲义
评论
0/150
提交评论