编译原理课程设计报告
实验1:用Lex设计词法分析器1
实验目的:学会用lex设计一个词法分析器。
实验内容:使用lex为下述文法语言写一个词法分析器。 实验要求:
输入为用该语言所写的源程序文件;输出为记号序列,每个记号显示为二元组(记号名,记号属性值)的形式。输出可以在屏幕上,也可以输出到文件中。不要求建立符号表。
在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的test1.p测试例的测试。
实验参考:exam1.l和exam2.l。
语言文法:
<程序>? PROGRAM <标识符> ; <分程序>
<分程序>? <变量说明> BEGIN <语句表> END. <变量说明> ? VAR <变量说明表>;
<变量说明表>?<变量表>: <类型> | <变量表>: <类型>; <变量说明表> <类型>? INTEGER | REAL
<变量表>? <变量> | <变量>, <变量表>
<语句表>? <语句> | <语句>; <语句表>
<语句>? <赋值语句> | <条件语句> |
<条件语句>? IF <关系表达式> THEN <语句> ELSE <语句>
<算术表达式> ? <项> | <算术表达式> + <项> | <算术表达式> - <项> <项> ? <因式> | <项> * <因式> | <项> / <因式> <因式>? <变量> | <常数> | (<算术表达式>)
<关系表达式>? <算术表达式> <关系符> <算术表达式> <变量>? <标识符>
<标识符>? <标识符><字母> | <标识符><数字> | <字母> <常数>? <整数> | <浮点数> <整数>? <数字> | <数字> <整数> <浮点数>? .<整数> | <整数>.<整数> <关系符>? < | <= | = | > | >=| <>
<字母>? A | B | …| X | Y | Z | a | b | …| x | y | z <数字>?0|1|2|…|9
程序代码: %{
#include
1 2 3 4 5 6
#define EQ
#define PROGRAM #define END #define VAR
#define IF #define THEN
7 13
9 10 11
#define ELSE 12 #define WHILE 18 #define DO 19 #define ID 20 #define NUMBER 21 #define RELOP 22 #define NEWLINE 23 #define ERRORCHAR 24 %} delim ws letter digit id
[ \\t \\n] {delim}+ [A-Za-z]
[0-9] _|{letter}({letter}|{digit})*
number {digit}+(\\.{digit}+)?(E[+-]?{digit}+)?
int1 {digit}|{digit}{int1}*/ %s COMMENT %%
{BEGIN COMMENT;ECHO;} {BEGIN INITIAL;ECHO;}
/* ECHO是一个宏,相当于 fprintf(yyout, \
{return (PROGRAM);}
{return (END);} {return (VAR);}
{return (THEN);} {return (ELSE);} {return (ID);}
{return (NUMBER);}
{return (RELOP);}
{return (RELOP);}
{return (RELOP);} {return (RELOP);}
int yywrap (){ return 1; }
void writeout(int c){ switch(c){
case ERRORCHAR: fprintf(yyout, \ case RELOP: fprintf(yyout, \, \\\ case WHILE: fprintf(yyout, \ case DO: fprintf(yyout, \
case NUMBER: fprintf(yyout, \ case ID: fprintf(yyout, \ case NEWLINE: fprintf(yyout, \
case PROGRAM: fprintf(yyout, \ case END: fprintf(yyout, \ case VAR: fprintf(yyout, \AR, \\\ case IF: fprintf(yyout, \, \\\ case THEN: fprintf(yyout, \ case ELSE: fprintf(yyout, \ default:break; }
{return ERRORCHAR;}
return;
}
int main (int argc, char ** argv){
int c,j=0; if (argc>=2){
if ((yyin = fopen(argv[1], \ printf(\ return 1; }
if (argc>=3){
yyout=fopen(argv[2], \ } }
while (c = yylex()){ writeout(c); j++; }
if(argc>=2){ fclose(yyin);
if (argc>=3) fclose(yyout); }
if (j%5 == 0) writeout(NEWLINE);
return 0; }
测试文件为Test1.p: PROGRAM test;
VAR i, j, k: INTEGER; f0: REAL; BEGIN i := 1; j := 1; k := 0; f0 := 3.2;
WHILE k<=100 DO BEGIN
IF j <20 THEN BEGIN j := i; k := k+1; f0 := f0*0.2 END
ELSE BEGIN j := k; k := k-2; f0 := f0/.2 END END END.
运行结果:
实验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测试例的测试。
搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新小学教育编译原理课程设计报告 全文阅读和word下载服务。
相关推荐: