logo资料库

河北工业大学编译原理实验报告.docx

第1页 / 共45页
第2页 / 共45页
第3页 / 共45页
第4页 / 共45页
第5页 / 共45页
第6页 / 共45页
第7页 / 共45页
第8页 / 共45页
资料共45页,剩余部分请下载后查看
实验一 词法分析程序设计与实现
一.实验目的
二.基本实验内容与要求
三.设计过程
四.分析过程:
五.代码:
六.实验感想
实验二 语法分析程序设计与实现
一.实验目的
二.基本实验内容与要求
三.实现方法
2.算符优先分析法的语法分析程序
3.SLR(1)分析器的开发
四、扩展实验
五.实验分析与代码实现
1.算符优先分析法
2.SLR(1)法:
六.实验感想
实验三 语义分析程序设计与实现
一、实验目的
二、基本实验内容及要求
三、分析设计过程
四、代码实现
五.实验感想
实验一 词法分析程序设计与实现 一.实验目的 通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫 描的过程中,将字符流形式的源程序转化为一个由各类单词构成的序列的词法分 析方法。 二.基本实验内容与要求 假定一种高级程序设计语言中的单词主要包括关键字 begin、end、if、then、 else、while、do;标识符;浮点常数;六种关系运算符;一个赋值符和四个算术 运算符,试构造能识别这些单词的词法分析程序(各类单词的分类码可参见表 1)。 输入:由符合和不符合所规定的单词类别结构的各类单词组成的源程序文件。 输出:把所识别出的每一单词均按形如(CLASS,VALUE)的二元式形式 输出,并将结果放到某个文件中。对于标识符和浮点常数,CLASS 字段为相应 的类别码的助记符;VALUE 字段则是该标识符、常数的具体值;对于关键字和 运算符,采用一词一类的编码形式,仅需在二元式的 CLASS 字段上放置相应单 词的类别码的助记符,VALUE 字段则为“空”。 要求: 1、上机前完成词法分析程序的程序流程设计,并选择好相应的数据结构。 2、用于测试扫描器的实例源文件中至少应包含两行以上的源代码。 3、对于输入的测试用例的源程序文件,词法正确的单词分析结果在输出文 件中以二元式形式输出,错误的字符串给出错误提示信息。 4、扩充关键字的数目、增加逻辑运算符等单词类别、将常数再细分成字符 串常量、整型常量和无符号数常量等;添加词法分析中单词出错的位置和错误类 型,以及删除注释部分等 三.设计过程 语言中的各类单词符号及其分类码表: 表 1 语言中的各类单词符号及其分类码表 单词符号 类别编码 类别码的助记符 单词值 begin end if then else 1 2 3 4 5 BEGIN END IF THEN ELSE
while do 标识符 浮点常数 < <= = <> > >= + - * / := 整形 浮点型 双精度 长整形 ||,!,&& //,/* */ 字符串常量 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 WHILE DO ID UCON LT LE EQ NE GT GE PL MI MU DI IS INT FLOAT DOUBLE LONG LOGIC ZHISHI STRING 主要函数: 函数 void scanner_example(FILE *fp) int lookup(char p[]) void out(int a,char *p) void report_error() void main() 字母打头的字母数字 串 机内二进制表示 机内二进制表示 机内二进制表示 机内二进制表示 机内二进制表示 功能 扫描器函数 查找是否为关键字 输出 出现错误时强制退出 主函数
四.分析过程:
五.代码: 3 #include #include #include #include #define BEGIN 1 #define END 2 #define IF #define THEN 4 #define ELSE 5 #define WHILE 6 #define DO 7 #define ID 8 #define UCON 9 #define LT 10 #define LE 11 #define EQ 12 #define NE 13 #define GT 14 #define GE 15 #define PL 16 #define MI 17 #define MU 18 #define DI 19 #define IS 20 #define INT 21 #define FLOAT 22 #define DOUBLE 23 #define LONG 24 #define LOGIC 25 #define ZHUSHI 26 #define STRING 27 #define TOKEN_SIZE 64 #define TAB_SIZE 15 char TOKEN[TOKEN_SIZE]; char ch; extern int lookup(char*); extern void out(int,char*); extern void report_error(); //信息表保留 7 个关键字 typedef struct { int ad;
char id[10]; }info_ele; info_ele Tab[TAB_SIZE]={{1,"begin"},{2,"end"},{3,"if"},{4,"then"},{5,"else"},{6,"while"},{7,"do"},{21, "int"},{22,"float"},{23,"double"},{24,"long"},{27,"string"}}; void scanner_example(FILE *fp)//扫描器函数 { int i,c; ch=fgetc(fp); if(ch==' '||ch=='\n'); else if(isalpha(ch)) { //遇见空格、回车继续 //是否为字母 TOKEN[0]=ch; i=1; ch=fgetc(fp); while(isalnum(ch)||(ch=='_')) { //为字母或数字或下划线时进行循环 TOKEN[i]=ch; i++; ch=fgetc(fp); } fseek(fp,-1,1); TOKEN[i]='\0'; c=lookup(TOKEN); if (c==0) //非字母或数字,下划线时回退一个字符 //检查保留字表 out(ID,TOKEN);//调用输出函数 out() else out(c,TOKEN); } else if(isdigit(ch)) { //是否为数字 int flag=0; TOKEN[0]=ch; i=1; ch=fgetc(fp); while(isdigit(ch)||(ch=='.')) { if(ch=='.') flag++; TOKEN[i]=ch; i++; ch=fgetc(fp); } TOKEN[i]='\0';
fseek(fp,-1,1); if(flag==0) //小数点个数为 0 为整形 out(INT,TOKEN); if(flag==1) //判断是否为浮点型 out(DOUBLE,TOKEN); if(flag>1) printf("数字出错!\n"); } else if(ch=='"') { //是否为字符串常量 TOKEN[0]=ch; i=1; ch=fgetc(fp); while(isalnum(ch)) { TOKEN[i]=ch; i++; ch=fgetc(fp); } if(ch=='"') { TOKEN[i]=ch; out(STRING,TOKEN); } else { printf("字符串常量格式错误!\n"); } TOKEN[i+1]='\0'; } else { switch(ch) //判断运算符 case '=':out(EQ,"=");break; case ':':ch=fgetc(fp); if(ch=='=') out(IS,":=");break; case '>':ch=fgetc(fp); if(ch=='=')out(GE,">="); else
{ fseek(fp,-1,1); out(GT,">"); } break; case '&':ch=fgetc(fp); if(ch=='&') out(LOGIC,"&&"); else{ fseek(fp,-1,1); } break; case '|':ch=fgetc(fp); if(ch=='|') out(LOGIC,"||"); else{ fseek(fp,-1,1); } break; case '!':out(LOGIC,"!");break; case '<':ch=fgetc(fp); if(ch=='=') out(LE,"<="); else if(ch=='>') out(NE,"<>"); else{ fseek(fp,-1,1); out(LT,"<"); } break; case '+':out(PL,"+");break; case '-':out(MI,"-");break; case '*':out(MU,"*");break; case '/': { ch=fgetc(fp); if(ch=='/') { 扫描分析 //判断是否为注释或是除运算,注释内容不 //单行注释 while(ch!='\n') ch=fgetc(fp); out(ZHUSHI," "); } else if(ch=='*') //多行注释
{ } else { } char a,d; d=fgetc(fp); a=fgetc(fp); while(a!=EOF&&(a!='/'||d!='*')) { d=a; a=getc(fp); } if(a=='/'&&d=='*') out(ZHUSHI," "); else { } printf("注释格式错误!\n"); fseek(fp,-1,1); out(DI,"/"); } break; default: break; } } int lookup(char p[]) { int i=0; for(i;i
分享到:
收藏