您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 编译原理课程设计报告
实验1:用Lex设计词法分析器1实验目的:学会用lex设计一个词法分析器。实验内容:使用lex为下述文法语言写一个词法分析器。实验要求:输入为用该语言所写的源程序文件;输出为记号序列,每个记号显示为二元组(记号名,记号属性值)的形式。输出可以在屏幕上,也可以输出到文件中。不要求建立符号表。在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的测试例的测试。实验参考:和。语言文法:程序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程序代码:%{#include#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;}测试文件为:PROGRAMtest;VARi,j,k:INTEGER;f0:REAL;BEGINi:=1;j:=1;k:=0;f0:=;WHILEk=100DOBEGINIFj20THENBEGINj:=i;k:=k+1;f0:=f0*ENDELSEBEGINj:=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目录下的测试例的测试。实验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这四个例子。程序代码:文件:%{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;}文件:%{#include#includeintyywrap(void){return1;}#defineLT1#defineLE2#defineGT3#defineGE4#defineEQ5#defineNE6#definePROGRAM7#defineEND13#defineVAR9#defineIF10#defineTHEN11#defineELSE12#defineWHILE18#defineDO19#defineID20#defineRELOP22#defineNEWLINE23#defineERRORCHAR24%}ws[\t]+digit[0-9]inum{digit}+fnum{digit}*\.{digit}+letter[A-Za-z]id_|{letter}({let
本文标题:编译原理课程设计报告
链接地址:https://www.777doc.com/doc-5177240 .html