编译原理课程设计报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

编译原理课程设计报告实验1:用Lex设计词法分析器1实验目的:学会用lex设计一个词法分析器。实验内容:使用lex为下述文法语言写一个词法分析器。实验要求:输入为用该语言所写的源程序文件;输出为记号序列,每个记号显示为二元组(记号名,记号属性值)的形式。输出可以在屏幕上,也可以输出到文件中。不要求建立符号表。在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的test1.p测试例的测试。实验参考:exam1.l和exam2.l。语言文法:程序PROGRAM标识符;分程序分程序变量说明BEGIN语句表END.变量说明VAR变量说明表;变量说明表变量表:类型|变量表:类型;变量说明表类型INTEGER|REAL变量表变量|变量,变量表语句表语句|语句;语句表语句赋值语句|条件语句|WHILE语句|复合语句赋值语句变量:=算术表达式条件语句IF关系表达式THEN语句ELSE语句WHILE语句WHILE关系表达式DO语句复合语句BEGIN语句表END算术表达式项|算术表达式+项|算术表达式-项项因式|项*因式|项/因式因式变量|常数|(算术表达式)关系表达式算术表达式关系符算术表达式变量标识符标识符标识符字母|标识符数字|字母常数整数|浮点数整数数字|数字整数浮点数.整数|整数.整数关系符|=|=||=|字母A|B|…|X|Y|Z|a|b|…|x|y|z数字0|1|2|…|9程序代码:%{#includestdio.h#defineLT1#defineLE2#defineGT3#defineGE4#defineEQ5#defineNE6#definePROGRAM7#defineEND13#defineVAR9#defineIF10#defineTHEN11#defineELSE12#defineWHILE18#defineDO19#defineID20#defineNUMBER21#defineRELOP22#defineNEWLINE23#defineERRORCHAR24%}delim[\t\n]ws{delim}+letter[A-Za-z]digit[0-9]id_|{letter}({letter}|{digit})*number{digit}+(\.{digit}+)?(E[+-]?{digit}+)?int1{digit}|{digit}{int1}*/%sCOMMENT%%INITIAL/*{BEGINCOMMENT;ECHO;}COMMENT*/{BEGININITIAL;ECHO;}COMMENT.|\n{ECHO;}/*ECHO是一个宏,相当于fprintf(yyout,%s,yytext)*/INITIAL{ws}{;}INITIALwhile{return(WHILE);}INITIALdo{return(DO);}INITIALPROGRAM{return(PROGRAM);}INITIALend{return(END);}INITIALVAR{return(VAR);}INITIALif{return(IF);}INITIALthen{return(THEN);}INITIALelse{return(ELSE);}INITIAL{id}{return(ID);}INITIAL{number}{return(NUMBER);}INITIAL{return(RELOP);}INITIAL={return(RELOP);}INITIAL={return(RELOP);}INITIAL{return(RELOP);}INITIAL{return(RELOP);}INITIAL={return(RELOP);}INITIAL+{return(RELOP);}INITIAL-{return(RELOP);}INITIAL*{return(RELOP);}INITIAL/{return(RELOP);}INITIAL:={return(RELOP);}INITIAL;{return(RELOP);}INITIAL.{return(RELOP);}INITIAL,{return(RELOP);}INITIAL.{returnERRORCHAR;}%%intyywrap(){return1;}voidwriteout(intc){switch(c){caseERRORCHAR:fprintf(yyout,(ERRORCHAR,\%s\),yytext);break;caseRELOP:fprintf(yyout,(RELOP,\%s\),yytext);break;caseWHILE:fprintf(yyout,(WHILE,\%s\),yytext);break;caseDO:fprintf(yyout,(DO,\%s\),yytext);break;caseNUMBER:fprintf(yyout,(NUM,\%s\),yytext);break;caseID:fprintf(yyout,(ID,\%s\),yytext);break;caseNEWLINE:fprintf(yyout,\n);break;casePROGRAM:fprintf(yyout,(PROGRAM,\%s\),yytext);break;caseEND:fprintf(yyout,(END,\%s\),yytext);break;caseVAR:fprintf(yyout,(VAR,\%s\),yytext);break;caseIF:fprintf(yyout,(IF,\%s\),yytext);break;caseTHEN:fprintf(yyout,(THEN,\%s\),yytext);break;caseELSE:fprintf(yyout,(ELSE,\%s\),yytext);break;default:break;}return;}intmain(intargc,char**argv){intc,j=0;if(argc=2){if((yyin=fopen(argv[1],r))==NULL){printf(Can'topenfile%s\n,argv[1]);return1;}if(argc=3){yyout=fopen(argv[2],w);}}while(c=yylex()){writeout(c);j++;if(j%5==0)writeout(NEWLINE);}if(argc=2){fclose(yyin);if(argc=3)fclose(yyout);}return0;}测试文件为Test1.p:PROGRAMtest;VARi,j,k:INTEGER;f0:REAL;BEGINi:=1;j:=1;k:=0;f0:=3.2;WHILEk=100DOBEGINIFj20THENBEGINj:=i;k:=k+1;f0:=f0*0.2ENDELSEBEGINj:=k;k:=k-2;f0:=f0/.2ENDENDEND.运行结果:实验2:用Lex设计词法分析器2实验目的:学会用lex设计一个词法分析器,并考虑其与后续语法分析器的链接问题。实验内容:修改上次实验1的词法分析器,使其满足下列要求。实验要求:1.要求每次调用词法分析函数yylex时,只返回一个记号(token);2.为记号选择适当的属性值,并且每次词法分析函数返回记号前,都将记号的属性值存入全局变量yylval中。(yylval可以自己定义为全局变量);3.记号属性值的选择:标识符的属性为标识符的名字字符串(例如,标识符name1的属性为字符串”name1”),整数的属性为整数值,浮点数的属性为浮点数值。其他记号属性值可自己选择。关键字可以省略属性。4.注意:由于属性值需要存入yylval中,并且记号属性值的类型比较多(可能为字符串、整数、浮点数等),因此yylval必须能同时存放各种类型的值(提示:将yylval设置为union类型)。5.在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的test1.p测试例的测试。实验3:熟悉Yacc的使用实验目的:熟悉语法分析器生成工具Yacc的使用,并学会在cygwin下使用bison工具编译Yacc文法说明文件。学习如何使用lex和yacc合作进行语法分析。实验内容:根据给出的calculator例子(calculator0,calculator1,calculator2,calculator3)完成下面题目:用lex和yacc写一个计算布尔表达式真值的计算器。实验要求:输入为一个布尔表达式,以换行结束。输出为这个布尔表达式的真值(true或false)。必须用二义文法实现。布尔表达式二义文法为:S–SorS|SandS|notS|(S)|true|false,其中优先级orandnot,or和and左结合,not右结合。用非二义文法实现作为选作内容,非二义文法请参照表达式非二义文法自己写出来。在cygwin下用flex,bison和gcc工具将实验调试通过,并写出测试例测试正确性。实验参考:calculator0-3这四个例子。程序代码:Cal.y文件:%{intyylex();#defineYYSTYPEdouble/*将Yacc栈定义为double类型printf(\nThevalueoftheexpressionis%lf.\n,$1);*/%}%tokenNUMLPARENRPARENENTER%leftOR%leftAND%rightNOT%leftPLUSMINUS%leftTIMESDIVIDE%rightUMINUS%%/*这样写prog可以让分析器每次读入一行进行分析,下一行重新分析expr*/prog:progexprp|exprp;exprp:exprENTER{printf(1表示true;0表示false%lf.\n,$1);shuchu($1);};expr:exprPLUSexpr{$$=$1+$3;}|exprMINUSexpr{$$=$1-$3;}|exprTIMESexpr{$$=$1*$3;}|exprDIVIDEexpr{$$=$1/$3;}|LPARENexprRPAREN{$$=$2;}|MINUSexpr{$$=-$2;}|NUM{$$=$1;}|exprORexpr{$$=panduan($1*$1+$3*$3);}|exprANDexpr{$$=panduan($1*$3);}|NOTexpr{$$=panduan2($2);};%%intmain(){yyparse();return0;}Cal.l文件:%{#includecal.tab.h#includestdio.hintyywrap(void){return1;}#defineLT1#defineLE2#defineGT3#defineGE4#defineEQ5#defineNE6#definePROGRAM7#defineEND13#defineVAR9#defineIF10#defineTHEN11#defineELSE12#defineWHILE18#defineDO19#defineID20#defineRELOP22#defineNEW

1 / 24
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功