编译原理实验(议程管理系统Agenda)

合集下载

编译原理 实验报告

编译原理 实验报告

编译原理实验报告编译原理实验报告引言编译原理是计算机科学中的重要课程,它研究的是如何将高级语言程序转化为机器语言程序的过程。

在本次实验中,我们学习了编译原理的基本概念和技术,并通过实践来加深对这些概念和技术的理解。

本报告将对我们在实验中遇到的问题、解决方案以及实验结果进行总结和分析。

实验目的本次实验的主要目的是设计并实现一个简单的编译器,能够将类C语言的源代码翻译成目标代码。

通过这个实验,我们可以更好地理解编译器的工作原理,掌握编译器设计的基本方法和技术。

实验过程在实验中,我们首先对给定的类C语言的语法进行了分析,并根据语法规则设计了相应的语法分析器。

然后,我们使用了自顶向下的递归下降分析法来实现语法分析器。

在实现语法分析器的过程中,我们遇到了一些问题,例如如何处理语法规则中的左递归、如何处理语法规则中的优先级和结合性等。

通过仔细研究相关的文献和资料,我们成功地解决了这些问题,并完成了语法分析器的设计和实现。

接下来,我们对语法分析器进行了测试,并对测试结果进行了分析。

通过测试,我们发现语法分析器在处理简单的源代码时能够正确地识别出语法错误,并给出相应的错误提示。

然而,在处理复杂的源代码时,语法分析器可能会出现一些错误,例如无法正确地处理嵌套的语法结构、无法正确地处理运算符的优先级和结合性等。

为了解决这些问题,我们对语法分析器进行了改进,并进行了多次测试,最终得到了令人满意的结果。

实验结果通过本次实验,我们成功地设计并实现了一个简单的编译器,能够将类C语言的源代码翻译成目标代码。

在实验中,我们对编译器的工作原理有了更深入的了解,掌握了编译器设计的基本方法和技术。

同时,我们也发现了一些问题,并通过不断地改进和测试,最终得到了令人满意的结果。

结论编译原理是一门重要的计算机科学课程,它研究的是如何将高级语言程序转化为机器语言程序的过程。

通过本次实验,我们对编译原理的基本概念和技术有了更深入的了解,并通过实践来加深了对这些概念和技术的理解。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。

二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。

三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。

在本次实验中,我们使用有限自动机的理论来设计词法分析器。

首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。

然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。

在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。

(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。

在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。

首先,我们根据给定的语法规则,编写了相应的递归函数。

每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。

在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。

(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。

在本次实验中,我们使用了四元式作为中间代码的表示形式。

在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。

同时,根据语法树的结构,生成相应的四元式中间代码。

(四)代码优化代码优化的目的是提高生成代码的质量和效率。

在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。

通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。

实验报告编译原理

实验报告编译原理

北京科技大学计算机与通信工程学院实验报告实验名称:_________编译原理实验报告_______学生姓名:_________ ________________专业:_________ _________________班级:_________ _________________学号:_________________________指导教师:_________ _________________实验成绩:________________________________实验地点:________________________________实验时间:____2015___年___07__月_______日一、实验目的与实验要求1、实验目的通过一个词法分析程序将一段给出的C语言代码的词法部分分析出来;通过一个语法分析程序将一段给出的C语言代码的语法分析出来。

2、实验要求二、实验设备(环境)及要求Win7家庭普通版;Visual Studio 2013;三、实验内容与步骤1、实验1(1)实验内容对于给定一段代码,通过词法分析程序将程序中的各个类型的字表分析,包括保留字、分隔符表、运算符表、标识符、整型数、浮点类型数、字符类型、字符串类型等表文件。

(2)主要步骤通过读入程序的文本文件,然后将分析的结果一次保存在本地文本文件。

然后通过指定的命令来将分析的结果读取出来。

附录:源码#include<stdio.h>#include<string.h>#include<stdlib.h>char*key0[] = { " ", "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "_Complex", "_Imaginary", "union", "unsigned", "void", "volatile", "while" };/*保留字表*/char *key1[] = { " ", "(", ")", "[", "]", "{", "}", ",", ";", "'" };/*分隔符表*/char *key2[] = { " ", "+", "-", "*", "/", "%", "<", ">", "==", ">=", "<=", "!=", "!", "&&", "||", "<<", ">>", "~", "|", "^", "&", "=", "?:", "->", "++", "--", ".", "+=", "-=", "*=", "/=" };/*运算符表*/int xx0[35], xx1[10], xx2[31];int temp_key3 = 0, temp_c40 = 0, temp_c41 = 0, temp_c42 = 0, temp_c43 = 0;/******* 初始化函数 *******/void load(){int mm;for (mm = 0; mm <= 34; mm++){xx0[mm] = 0;}for (mm = 0; mm <= 9; mm++){xx1[mm] = 0;}for (mm = 0; mm <= 30; mm++){xx2[mm] = 0;}FILE *floading;if ((floading = fopen("key0.txt", "w")) == NULL){printf("Error! Can't create file : key0.txt");return;}fclose(floading);/*建立保留字表文件:key0.txt*/if ((floading = fopen("key1.txt", "w")) == NULL){printf("Error! Can't create file : key1.txt");return;}/*建立分隔符表文件:key1.txt*/if ((floading = fopen("key2.txt", "w")) == NULL){printf("Error! Can't create file : key2.txt");return;}fclose(floading);/*建立运算符表文件:key2.txt*/if ((floading = fopen("key3.txt", "w")) == NULL){printf("Error! Can't create file : key3.txt");return;}fclose(floading);/*建立标识符表文件:key3.txt*/if ((floading = fopen("c40.txt", "w")) == NULL){printf("Error! Can't create file : c40.txt");return;}fclose(floading);/*建立整数类型常量表文件:c40.txt*/if ((floading = fopen("c41.txt", "w")) == NULL){printf("Error! Can't create file : c41.txt");return;}fclose(floading);/*建立浮点类型常量表文件:c41.txt*/if ((floading = fopen("c42.txt", "w")) == NULL){printf("Error! Can't create file : c42.txt");return;}fclose(floading);/*建立字符类型常量表文件:c42.txt*/if ((floading = fopen("c43.txt", "w")) == NULL){printf("Error! Can't create file : c43.txt");return;}fclose(floading);/*建立字符串类型常量表文件:c43.txt*/if ((floading = fopen("defination.txt", "w")) == NULL) {printf("Error! Can't create file : defination.txt");return;}fclose(floading);/*建立注释文件:defination.txt*/if ((floading = fopen("output.txt", "w")) == NULL){printf("Error! Can't create file : output.txt");return;}fclose(floading);/*建立内部码文件:output.txt*/if ((floading = fopen("temp_key1", "w")) == NULL){printf("Error! Can't create file : temp_key1");return;}fclose(floading);/*建立保留字临时表文件:temp_key1*/if ((floading = fopen("temp_key3", "w")) == NULL){printf("Error! Can't create file : temp_key3");return;}fclose(floading);/*建立标识符临时文件:temp_key3*/if ((floading = fopen("temp_c40", "w")) == NULL){printf("Error! Can't create file : temp_c40");return;}fclose(floading);/*建立整数类型常量临时文件:temp_c40*/if ((floading = fopen("temp_c41", "w")) == NULL){printf("Error! Can't create file : temp_c41");return;}fclose(floading);/*建立浮点类型常量临时文件:temp_c41*/if ((floading = fopen("temp_c42", "w")) == NULL){printf("Error! Can't create file : temp_c42");return;}fclose(floading);/*建立字符类型常量临时文件:temp_c42*/if ((floading = fopen("temp_c43", "w")) == NULL){printf("Error! Can't create file : temp_c43");return;}fclose(floading);/*建立字符串类型常量临时文件:temp_c43*/}/******* 保留字及标识符判断函数 *******/void char_search(char *word){int m, line = 0, csi = 0;int value = 0;int value2 = 0;char c, cs[100];FILE *foutput, *finput;for (m = 1; m <= 34; m++){if (strcmp(word, key0[m]) == 0){value = 1;break;}}if (value == 1){if (xx0[m] == 0){foutput = fopen("key0.txt", "a");fprintf(foutput, "0\t%d\t\t%s\n", m, word);fclose(foutput);xx0[m] = 1;}foutput = fopen("output.txt", "a");fprintf(foutput, "0\t%d\t\t%s\n", m, word);fclose(foutput);}else{if (temp_key3 == 0){foutput = fopen("temp_key3", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_key3++;foutput = fopen("key3.txt", "a");fprintf(foutput, "3\t1\t\t%s\n", word);fclose(foutput);}finput = fopen("temp_key3", "r");c = fgetc(finput);while (c != EOF){while (c != '\n'){cs[csi++] = c;c = fgetc(finput);}cs[csi] = '\0';csi = 0;line++;if ((strcmp(cs, word)) == 0){value2 = 1;break;}else{value2 = 0;c = fgetc(finput);}}fclose(finput);if (value2 == 1){foutput = fopen("output.txt", "a");fprintf(foutput, "3\t%d\t\t%s\n", line, word);fclose(foutput);}else{foutput = fopen("temp_key3", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_key3++;foutput = fopen("output.txt", "a");fprintf(foutput, "3\t%d\t\t%s\n", temp_key3, word);fclose(foutput);foutput = fopen("key3.txt", "a");fprintf(foutput, "3\t%d\t\t%s\n", temp_key3, word);fclose(foutput);}}}/******* 整数类型判断函数 *******/void inta_search(char *word){FILE *foutput, *finput;char c;char cs[100];int csi = 0;int line = 0;int value2 = 0;if (temp_c40 == 0){foutput = fopen("temp_c40", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c40++;foutput = fopen("c40.txt", "a");fprintf(foutput, "4\t0\t1\t%s\n", word);fclose(foutput);}finput = fopen("temp_c40", "r");c = fgetc(finput);while (c != EOF){while (c != '\n'){cs[csi++] = c;c = fgetc(finput);}cs[csi] = '\0';csi = 0;line++;if (strcmp(cs, word) == 0){value2 = 1;break;}c = fgetc(finput);}fclose(finput);if (value2 == 1){foutput = fopen("output.txt", "a");fprintf(foutput, "4\t0\t%d\t%s\n", line, word);fclose(foutput);}else{foutput = fopen("temp_c40", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c40++;foutput = fopen("output.txt", "a");fprintf(foutput, "4\t0\t%d\t%s\n", temp_c40, word);fclose(foutput);foutput = fopen("c40.txt", "a");fprintf(foutput, "4\t0\t%d\t%s\n", temp_c40, word);fclose(foutput);}}/******* 浮点类型判断函数 *******/void intb_search(char *word){FILE *foutput, *finput;char c;char cs[100];int csi = 0;int line = 0;int value2 = 0;if (temp_c41 == 0){foutput = fopen("temp_c41", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c41++;foutput = fopen("c41.txt", "a");fprintf(foutput, "4\t1\t1\t%s\n", word);fclose(foutput);}finput = fopen("temp_c41", "r");c = fgetc(finput);while (c != EOF){while (c != '\n'){cs[csi++] = c;c = fgetc(finput);}cs[csi] = '\0';csi = 0;line++;if (strcmp(cs, word) == 0){value2 = 1;break;}c = fgetc(finput);}fclose(finput);if (value2 == 1){foutput = fopen("output.txt", "a");fprintf(foutput, "4\t1\t%d\t%s\n", line, word);fclose(foutput);}else{foutput = fopen("temp_c41", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c41++;foutput = fopen("output.txt", "a");fprintf(foutput, "4\t1\t%d\t%s\n", temp_c41, word);fclose(foutput);foutput = fopen("c40.txt", "a");fprintf(foutput, "4\t1\t%d\t%s\n", temp_c41, word);fclose(foutput);}}/******* 字符串常量判断函数 *******/void cc_search(char *word){FILE *foutput, *finput;char c;char cs[100];int csi = 0;int line = 0;int value2 = 0;if (temp_c43 == 0){foutput = fopen("temp_c43", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c43++;foutput = fopen("c43.txt", "a");fprintf(foutput, "4\t3\t1\t%s\n", word);fclose(foutput);}finput = fopen("temp_c43", "r");c = fgetc(finput);while (c != EOF){while (c != '\n'){cs[csi++] = c;c = fgetc(finput);}cs[csi] = '\0';csi = 0;line++;if (strcmp(cs, word) == 0){value2 = 1;break;}c = fgetc(finput);}fclose(finput);if (value2 == 1){foutput = fopen("output.txt", "a");fprintf(foutput, "4\t3\t%d\t%s\n", line, word);fclose(foutput);}else{foutput = fopen("temp_c43", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c43++;foutput = fopen("output.txt", "a");fprintf(foutput, "4\t3\t%d\t%s\n", temp_c43, word);fclose(foutput);foutput = fopen("c43.txt", "a");fprintf(foutput, "4\t3\t%d\t%s\n", temp_c43, word);fclose(foutput);}}/******* 字符常量判断函数 *******/void c_search(char *word){FILE *foutput, *finput;char c;char cs[100];int csi = 0;int line = 0;int value2 = 0;if (temp_c42 == 0){foutput = fopen("temp_c42", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c42++;foutput = fopen("c42.txt", "a");fprintf(foutput, "4\t2\t1\t%s\n", word);fclose(foutput);}finput = fopen("temp_c42", "r");c = fgetc(finput);while (c != EOF){while (c != '\n'){cs[csi++] = c;c = fgetc(finput);}cs[csi] = '\0';csi = 0;line++;if (strcmp(cs, word) == 0){value2 = 1;break;}c = fgetc(finput);}fclose(finput);if (value2 == 1){foutput = fopen("output.txt", "a");fprintf(foutput, "4\t2\t%d\t%s\n", line, word);fclose(foutput);}else{foutput = fopen("temp_c42", "a");fprintf(foutput, "%s\n", word);fclose(foutput);temp_c42++;foutput = fopen("output.txt", "a");fprintf(foutput, "4\t2\t%d\t%s\n", temp_c42, word);fclose(foutput);foutput = fopen("c42.txt", "a");fprintf(foutput, "4\t2\t%d\t%s\n", temp_c42, word);fclose(foutput);}}/******* 主扫描函数 *******/void scan(){int count;char chin;FILE *fin;FILE *fout;char filename[50];char temp[100];char target[3] = "'";printf("请输入文件名:");scanf("%s", filename);if ((fin = fopen(filename, "r")) == NULL){printf("Error! Can't open file : %s\n", filename);return;}chin = fgetc(fin);while (chin != EOF){/*对文件包含、宏定义进行处理*/if (chin == '#'){while (chin != '>')chin = fgetc(fin);/*chin=fgetc(fin);*/}/*对空格符、水平制表符进行处理*/else if ((chin == ' ') || (chin == '\t')){;}/*对回车符进行处理*/else if (chin == '\n'){;}/*对单引号内的字符常量进行处理*/else if (chin == target[0]){if (xx1[9] == 0){fout = fopen("key1.txt", "a");fprintf(fout, "1\t9\t\t%c\n", target[0]);fclose(fout);xx1[9] = 1;}temp[0] = chin;chin = fgetc(fin);temp[1] = chin;chin = fgetc(fin);if (chin != target[0]){temp[2] = chin;chin = fgetc(fin);temp[3] = chin;temp[4] = '\0';}else{temp[2] = chin;temp[3] = '\0';}c_search(temp);}/*对双引号内的字符串常量进行处理*/else if (chin == '"'){int i = 0;temp[i++] = '"';chin = fgetc(fin);while (chin != '"'){temp[i++] = chin;chin = fgetc(fin);}temp[i] = '"';temp[i + 1] = '\0';cc_search(temp);}/*对保留字、标识符进行处理*/else if (((chin >= 'A') && (chin <= 'Z')) || ((chin >= 'a') && (chin <= 'z')) || (chin == '_')){int i = 0;while (((chin >= 'A') && (chin <= 'Z')) || ((chin >= 'a') && (chin <= 'z')) || (chin == '_') || ((chin >= '0') && (chin <= '9'))){temp[i++] = chin;chin = fgetc(fin);}temp[i] = '\0';char_search(temp);if (chin != EOF)fseek(fin, -1L, SEEK_CUR);}/*对整型、浮点型数据进行处理*/else if ((chin >= '0') && (chin <= '9')){int dotcount = 0;int i = 0;while (((chin >= '0') && (chin <= '9')) || (chin == '.')){if (chin == '.')dotcount++;if (dotcount == 2)break;temp[i++] = chin;chin = fgetc(fin);}temp[i] = '\0';if (dotcount == 1)intb_search(temp);elseinta_search(temp);if (chin != EOF)fseek(fin, -1L, SEEK_CUR);}/*对注释进行处理*/else if (chin == '/'){chin = fgetc(fin);if (chin == '='){fout = fopen("output.txt", "a");fprintf(fout, "2\t30\t\t/=\n");fclose(fout);}else if (chin != '*'){fout = fopen("output.txt", "a");fprintf(fout, "2\t4\t\t/\n");fclose(fout);fseek(fin, -1L, SEEK_CUR);}else if (chin == '*'){count = 0;chin = fgetc(fin);fout = fopen("defination.txt", "a");fprintf(fout, "/*");while (count != 2){count = 0;while (chin != '*'){fprintf(fout, "%c", chin);chin = fgetc(fin);}count++;fprintf(fout, "%c", chin);chin = fgetc(fin);if (chin == '/'){count++;fprintf(fout, "%c\n", chin);}else{fprintf(fout, "%c", chin);chin = fgetc(fin);}}}}/*对运算符、分隔符进行处理*/else{int time = 0;int firstblood = 0;temp[0] = chin;chin = fgetc(fin);if (chin != EOF){temp[1] = chin;temp[2] = '\0';for (time = 1; time <= 30; time++){if (strcmp(temp, key2[time]) == 0){firstblood = 1;if (xx2[time] == 0){fout = fopen("key2.txt", "a");fprintf(fout, "2\t%d\t\t%s\n", time, temp);fclose(fout);xx2[time] = 1;}fout = fopen("output.txt", "a");fprintf(fout, "2\t%d\t\t%s\n", time, temp);fclose(fout);break;}}if (firstblood != 1){fseek(fin, -1L, SEEK_CUR);temp[1] = '\0';for (time = 1; time <= 9; time++){if (strcmp(temp, key1[time]) == 0){if (xx1[time] == 0){fout = fopen("key1.txt", "a");fprintf(fout, "1\t%d\t\t%s\n", time, temp);fclose(fout);xx1[time] = 1;}fout = fopen("output.txt", "a");fprintf(fout, "1\t%d\t\t%s\n", time, temp);fclose(fout);break;}}for (time = 1; time <= 30; time++){if (strcmp(temp, key2[time]) == 0){if (xx2[time] == 0){fout = fopen("key2.txt", "a");fprintf(fout, "2\t%d\t\t%s\n", time, temp);fclose(fout);xx2[time] = 1;}fout = fopen("output.txt", "a");fprintf(fout, "2\t%d\t\t%s\n", time, temp);fclose(fout);break;}}}}}chin = fgetc(fin);}fout = fopen("output.txt", "a");fprintf(fout, "1\t6\t\t}\n");fclose(fout);}/******* Main函数 *******/void main(){FILE *fread;char charin;char command = 'Q';printf("\n");printf("******************** 词法分析 ********************\n");printf("* *\n");printf("* *\n");printf("* 0 --> 查看保留字表文件 *\n");printf("* 1 --> 查看分隔符表文件 *\n");printf("* 2 --> 查看运算符表文件 *\n");printf("* 3 --> 查看标识符表文件 *\n");printf("* 4 --> 查看整数类型常量表 *\n");printf("* 5 --> 查看浮点类型常量表 *\n");printf("* 6 --> 查看字符类型常量表 *\n");printf("* 7 --> 查看字符串类型常量表 *\n");//printf("* 8 --> 查看注释文件 *\n");printf("* 9 --> 查看内部码文件 *\n");printf("* -------------------------- *\n");printf("* Q --> 退出 *\n");printf("***************************************************************\n");printf("\n");load();scan();printf("\n");printf("分析完成!\n");getchar();printf("\n");printf("请输入命令:");command = getchar();while ((command != 'Q') && (command != 'q')){switch (command){case'0':{printf("*************************\n");printf("\n");fread = fopen("key0.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'1':{printf("*************************\n");printf("\n");fread = fopen("key1.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'2':{printf("*************************\n");printf("\n");fread = fopen("key2.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'3':{printf("*************************\n");printf("\n");fread = fopen("key3.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'4':{printf("*************************\n");printf("\n");fread = fopen("c40.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'5':{printf("*************************\n");printf("\n");fread = fopen("c41.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'6':{printf("*************************\n");printf("\n");fread = fopen("c42.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'7':{printf("*************************\n");printf("\n");fread = fopen("c43.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'8':{printf("*************************\n");printf("\n");fread = fopen("defination.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case'9':{printf("*************************\n");printf("\n");fread = fopen("output.txt", "r");charin = fgetc(fread);while (charin != EOF){putchar(charin);charin = fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}}command = getchar();}}2、实验2(1)实验内容输入单词串,以”#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出”error”例如:输入: begin a:=9;b:=0 end #输出: success输入: begin a=9 end #输出: error(2)主要步骤附录:源码#include<stdio.h>#include<string.h>#include<ctype.h>#include<stdlib.h>char GetChar(char *input, int *index, int length);int ClearBlank(char *input, int(*index), int length);int reserve(char *s);void lrparser(char *input, int inputLength, int *index);void yucu(char *input, int inputLength, int *index);void factor(char *input, int inputLength, int *index);void statement(char *input, int inputLength, int *index);void expression(char *input, int inputLength, int *index);void term(char *input, int inputLength, int *index);char *retab[6] = { "begin", "if", "then", "while", "do", "end" };//关键字int syn = 0;int myIsAlpha(char ch){if (islower(ch) == 2 || isupper(ch) == 1){return 1;}else{return 0;}}void scaner(char *input, int inputLength, int *index){char s[256] = ""; //保存当前的字符char ch = GetChar(input, index, inputLength);int nowPosition = 0;int j = 0;if (myIsAlpha(ch) == 1) //如果是字母{while(((ch >= '0'&& ch <= '9') || (myIsAlpha(ch) == 1)) && *index<= inputLength) {s[nowPosition] = ch; //添加到当前字符串中nowPosition++;ch = GetChar(input, index, inputLength);}if ((ch <'0' || ch>'9') && (myIsAlpha(ch) == 0))//进行回退操作,并输出结果{s[nowPosition] = '\0';//添加结束标志j = reserve(s);if (j == 0){syn = 10;}else{syn = j;}(*index)--;return;}else//超过范围{s[nowPosition++] = ch;s[nowPosition] = '\0';//添加结束标志j = reserve(s);if (j == 0){syn = 10;}else{syn = j;}getchar();exit(0);return;}}elseif (ch >= '0' && ch <= '9') //如果是数字{while (ch >= '0' && ch <= '9'&& *index <= inputLength) {s[nowPosition] = ch; //添加到当前字符串中nowPosition++;ch = GetChar(input, index, inputLength);}if (ch<'0' || ch>'9')//进行回退操作{(*index)--;syn = 11;return;}else//超过范围时{s[nowPosition] = ch;syn = 11;return;}}else{switch (ch){case'+':{syn = 13;return;}case'-':{syn = 14;return;}case'*':{syn = 15;return;}case'/':{syn = 16;return;}case'<':{ch = GetChar(input, index, inputLength);if (ch == '='){syn = 22;return;}elseif (ch == '>'){syn = 21;return;}else{syn = 20;if (*index>inputLength){return;}else{(*index)--;return;}}case'>':{ch = GetChar(input, index, inputLength);if (ch == '='){syn = 24;return;}else{syn = 23;if (*index>inputLength){return;}else{(*index)--;return;}}}case':':{ch = GetChar(input, index, inputLength);if (ch == '='){syn = 18;return;}else{if (*index>inputLength){return;}else(*index)--;return;}}}case'=':{syn = 25;return;}case';':{syn = 26;return;}case'(':{syn = 27;return;}case')':{syn = 28;return;}case'#':{syn = 0;return;}case' ':{syn = -1;return;}default:{printf("(非法符号)");。

编译原理实验报告总结

编译原理实验报告总结

编译原理实验报告总结一、实验目的编译原理是计算机科学中的一门重要课程,通过实验可以更深入地理解编译过程的各个阶段,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等。

本次编译原理实验的目的主要有以下几点:1、加深对编译原理理论知识的理解和掌握,将抽象的概念通过实际操作转化为具体的实现。

2、培养实际动手能力和解决问题的能力,通过编写代码实现编译程序的各个模块,提高编程技能和调试能力。

3、熟悉编译程序的开发流程和工具,掌握相关编程语言和开发环境的使用。

4、培养团队合作精神和沟通能力,在实验过程中与小组成员共同探讨、解决问题,提高协作效率。

二、实验环境本次实验使用的编程语言为 C/C++,开发环境为 Visual Studio 2019。

同时,使用了一些辅助工具,如调试工具、代码管理工具等,以提高开发效率和代码质量。

三、实验内容1、词法分析任务:使用正则表达式或有限自动机实现对输入源程序的词法分析,将源程序分解为一个个单词,并识别出单词的类型,如标识符、关键字、常量、运算符等。

实现方法:采用有限自动机的方法,设计状态转移图,根据输入字符的类型进行状态转移,最终确定单词的类型。

遇到的问题及解决方法:在处理一些边界情况时,如字符串中的转义字符,出现了识别错误。

通过仔细分析正则表达式和有限自动机的规则,对代码进行了相应的修改和完善,解决了问题。

2、语法分析任务:使用自顶向下或自底向上的语法分析方法,对词法分析得到的单词序列进行语法分析,构建语法树。

实现方法:选择了自顶向下的递归下降分析法,根据语法规则编写递归函数,逐个处理单词,构建语法树。

遇到的问题及解决方法:在处理复杂的语法结构时,出现了回溯和左递归的问题,导致分析效率低下。

通过消除左递归和提取公共因子,优化了语法分析算法,提高了分析效率。

3、语义分析任务:在语法分析的基础上,进行语义分析,检查语法正确的程序是否在语义上也是正确的,如类型匹配、变量未定义等。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。

本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。

二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。

此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。

三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。

在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。

首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。

然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。

在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。

对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。

(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。

在本次实验中,我们使用了递归下降的语法分析方法。

首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。

在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。

为了处理语法错误,在分析过程中添加了错误检测和处理机制。

当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。

(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。

在本次实验中,我们使用了三地址码作为中间代码的表示形式。

在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。

对于符合语义规则的语法结构,生成相应的三地址码指令。

四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。

编译原理实验报告

编译原理实验报告

编译原理实验报告编译原理实验报告一、实验目的1. 了解编译器的基本原理和工作过程;2. 掌握编译器设计和实现的基本方法和技巧;3. 通过设计和实现一个简单的编译器,加深对编程语言和计算机系统的理解和认识。

二、实验原理编译器是将高级语言程序翻译成机器语言程序的一种软件工具。

它由编译程序、汇编程序、链接程序等几个阶段组成。

本次实验主要涉及到的是编译程序的设计和实现。

编译程序的基本原理是将高级语言程序转换为中间代码,再将中间代码转换为目标代码。

整个过程可以分为词法分析、语法分析、语义分析、代码生成和代码优化几个阶段。

三、实验内容本次实验的设计目标是实现一个简单的四则运算表达式的编译器。

1. 词法分析根据规定的语法规则,编写正则表达式将输入的字符串进行词法分析,将输入的四则运算表达式划分成若干个单词(Token),例如:运算符、操作数等。

2. 语法分析根据定义的语法规则,编写语法分析程序,将词法分析得到的Token序列还原成语法结构,构建抽象语法树(AST)。

3. 语义分析对AST进行遍历,进行语义分析,判断表达式是否符合语法规则,检查语义错误并给出相应的提示。

4. 代码生成根据AST生成目标代码,目标代码可以是汇编代码或者机器码。

四、实验过程和结果1. 首先,根据输入的表达式,进行词法分析。

根据所定义的正则表达式,将输入的字符串划分成Token序列。

例如:输入表达式“2+3”,经过词法分析得到的Token序列为["2", "+", "3"]。

2. 然后,根据语法规则,进行语法分析。

根据输入的Token序列,构建抽象语法树。

3. 接着,对抽象语法树进行语义分析。

检查表达式是否符合语法规则,给出相应的提示。

4. 最后,根据抽象语法树生成目标代码。

根据目标代码的要求,生成汇编代码或者机器码。

五、实验总结通过本次实验,我对编译器的工作原理有了更深入的认识,掌握了编译器设计和实现的基本方法和技巧。

编译原理实验报告

编译原理实验报告

编译原理实验报告《编译原理》实验教学⼤纲课程编号:课程名称:编译原理/Compiler Principles实验总学时数:8学时适应专业:计算机科学与技术、软件⼯程承担实验室:计算机科学与技术学院实验中⼼⼀、实验教学的⽬的和任务1.上机实习是对学⽣的⼀种全⾯综合训练,是与课堂听讲、⾃学和练习相辅相成的必不可少的⼀个教学环节。

通常,实习题中的问题⽐平时的练习题要复杂,也更接近实际。

编译原理这门课程安排的2次上机实验都属于⼀种设计类型的实验,每个实验的训练重点在于基本的编译技术和⽅法,⽽不强调⾯⾯俱到;实验的⽬的是旨在使学⽣进⼀步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容;培养学⽣编制算法的能⼒和编程解决实际问题的动⼿能⼒。

2.要求学⽣在上机前应认真做好各种准备⼯作,熟悉机器的操作系统和语⾔的集成环境,独⽴完成算法编制和程序代码的编写;上机时应随带有关的编译原理教材或参考书;要学会程序调试与纠错;每次实验后要交实验报告。

实验报告的内容应包括:(1)封⾯:实验题⽬、班级、学号、姓名、完成⽇期;(2)简要的需求分析与概要设计;(3)详细的算法描述;(4)程序清单与运⾏结果;(5)收获与体会。

实验成绩占编译原理课程结业成绩的10-20%。

⼆、实验项⽬及学时分配三、每项实验的内容和要求要求每个实验保证每个学⽣⼀台微机。

实验⼀(4学时):单词的词法分析程序设计。

1.问题描述:对于常⽤⾼级语⾔(如Pascal、C语⾔)的各类单词进⾏词法分析。

2.实验内容:完成对某⼀种常⽤⾼级语⾔(如Pascal、C语⾔、PL/0语⾔)的各类单词进⾏词法分析,即对源程序从左到右进⾏扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。

3.实验要求:(1)选择常⽤⾼级程序设计语⾔(如 Pascal、C语⾔、PL/0语⾔)的源程序作为词法分析对象。

(2)根据教学要求和学⽣具体情况,从上列语⾔之⼀中选取它的⼀个适当⼤⼩的⼦集,可以选取⼀类典型单词,也可以尽可能使各种类型的单词都能兼顾到。

编译原理课程实验报告

编译原理课程实验报告
思考题3:如果在语法分析中遇到了语法错误,是应该中断语法分析呢,还是应该进行适当处理后继续语法分析,你是怎么处理的?
五、实验体会
指导教师评语:
日期:
编译原理课程实验报告实验2语法分析院系姓名任课教师实验地点实验课表现学号出勤表现得分操作结果得分指导教师实验时间实验报告得分实验总分一实验目的要求需分析本次实验的基本目的并综述你是如何实现这些目的的二实验内容要求对如下工作进行展开描述1给出如下语言成分的文法描述函数定义或过程定义变量说明赋值表达式循环分支2语法分析程序的总体结构及物理实现3语法分析表及其数据结构和查找算法4语法分析表的生成算法5错误处理错误的位置及类型等三实验结果要求将实验获得的结果进行描述基本内容包括1针对一测试程序输出其语法分析结果2输出针对此测试程序对应的语法错误报告注其中的测试样例需先用已编写的词法分析程序进行处理
变量说明
赋值
表达式
循环
分支
(2)语法分析程序的总体结构及物理实现
(3)语法分析表及其数据结构和查找算法
(4)语法分析表的生成算法
(5)错误处理
错误的位置及类型等
三、实验结果
要求:将实验获得的结果进行描述,基本内容包括:
(1)针对一测试程序输出其语法分析结果;
(2)输出针对此测试程序对应的语法错误报告;
编译原理课程实验报告
实验2:语法分析
姓名
院系
学号
任课教师
指导教师
实验地点
实验时间
实验课表现
出勤、表现得分
实验报告
得分
实验总分
操作结果得分
一、实验目的
要求:需分析本次实验的基本目的,并综述你是如何实现这些目的的?
二、实验内容
要求:对如下工作进行展开描述

编译原理实验范文

编译原理实验范文

编译原理实验范文1.词法分析:词法分析是编写编译器的第一步,它将源代码分解为一个个的词法单元。

在词法分析实验中,学生需要实现一个词法分析器,能够将输入的源代码按照事先定义好的词法规则进行分解。

2.语法分析:语法分析是编译器的核心部分,它负责将词法单元组织成语法树。

在语法分析实验中,学生需要实现一个语法分析器,能够根据事先定义好的文法规则生成对应的语法树,并能够检测到源代码中的语法错误。

3.语义分析:语义分析是对语法树进行进一步的处理,将其转化为中间代码或目标代码。

在语义分析实验中,学生需要实现一个语义分析器,能够对语法树进行类型检查、错误检测和语义规则的处理。

4.中间代码生成:中间代码是指在目标代码生成之前的一种中间表示形式。

在中间代码生成实验中,学生需要实现一个中间代码生成器,能够将语法树转化为中间代码,以便后续的代码优化和目标代码生成。

5.代码优化与目标代码生成:代码优化是对中间代码进行优化,以提高目标代码的质量和效率。

在代码优化与目标代码生成实验中,学生需要实现一个代码优化器和目标代码生成器,能够对中间代码进行优化,并将其转化为可执行的目标代码。

在进行编译原理实验时,学生通常需要选择一种编程语言作为实验的实现语言。

常见的选择包括C、C++、Java等。

此外,学生还可以选择使用一些现成的工具和框架,如Flex、Bison等,来简化实验的实现过程。

编译原理实验的核心目标是培养学生的编译器设计和实现能力。

通过实际编写编译器的过程,学生能够深入理解编译器的工作原理,提升编程和算法设计的能力,锻炼问题分析和解决的能力,并培养对编程语言和计算机系统的整体把握能力。

总之,编译原理实验是一门重要的课程,通过实际编写编译器的过程,学生能够提升自己的编程和算法设计的能力,加深对编译原理的理解,为日后的软件开发和系统设计奠定坚实的基础。

编译原理的实验报告

编译原理的实验报告

一、实验目的1. 理解编译原理的基本概念和原理。

2. 掌握编译器的各个阶段及其实现方法。

3. 能够运用编译原理的知识解决实际问题。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 20194. 实验内容:词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成三、实验内容1. 词法分析(1)实验目的:实现一个简单的词法分析器,将源代码中的字符序列转换为词法符号序列。

(2)实验步骤:1)定义词法符号类型,包括标识符、关键字、运算符、常量等。

2)设计词法分析器算法,对源代码进行遍历,将字符序列转换为词法符号序列。

3)实现词法分析器程序,输出词法符号序列。

(3)实验结果:输入源代码:int a = 10;输出词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}2. 语法分析(1)实验目的:实现一个简单的语法分析器,将词法符号序列转换为抽象语法树(AST)。

(2)实验步骤:1)定义语法规则,包括产生式、非终结符、终结符等。

2)设计语法分析算法,根据语法规则对词法符号序列进行解析,生成AST。

3)实现语法分析器程序,输出AST。

(3)实验结果:输入词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}输出AST:```AST:- ExpressionStatement- Expression- BinaryExpression- Identifier: a- Operator: =- Constant: 10```3. 语义分析(1)实验目的:实现语义分析器,对AST进行语义检查,确保程序的正确性。

(2)实验步骤:1)定义语义规则,包括类型检查、作用域检查等。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。

本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。

二、实验环境本次实验使用了Java编程语言及相关工具。

在开始实验前,我们需要安装Java JDK并配置好运行环境。

三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。

我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。

2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。

我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。

3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。

我们主要进行类型检查、语法错误检查等。

如果源代码存在语义错误,编译器应该能够提供相应的错误提示。

4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。

在本次实验中,我们将目标代码生成为Java字节码。

5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。

通过多个测试用例的执行,我们可以验证编译器的正确性和性能。

四、实验心得通过完成这个编译器的实验,我收获了很多。

首先,我对编译原理的知识有了更深入的理解。

在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。

其次,我提高了编程能力。

实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。

通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。

最后,我锻炼了解决问题的能力。

在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。

编译原理实验教案

编译原理实验教案

一、实验目的与要求1. 实验目的(1) 理解编译原理的基本概念和流程。

(2) 掌握常用的编译方法和技术。

(3) 熟练使用编译器开发工具。

2. 实验要求(1) 熟悉计算机专业基础知识。

(2) 掌握C/C++编程语言。

(3) 了解基本的编译原理。

二、实验环境1. 硬件环境(1) 计算机一台。

(2) 编译器开发工具(如GCC、Clang等)。

2. 软件环境(1) 操作系统(如Windows、Linux等)。

(2) 文本编辑器或集成开发环境(如Visual Studio、Eclipse等)。

三、实验内容1. 实验一:词法分析(1) 实现一个简单的词法分析器,识别出关键字、标识符、常量等。

(2) 分析输入的程序,输出词法分析结果。

2. 实验二:语法分析(1) 实现一个简单的语法分析器,根据给定的语法规则分析输入的程序。

(2) 分析输入的程序,输出语法分析树。

3. 实验三:语义分析(1) 实现一个简单的语义分析器,检查程序中的语义错误。

(2) 分析输入的程序,输出语义分析结果。

4. 实验四:中间代码(1) 实现一个简单的中间代码器,将转换为中间代码表示。

(2) 对输入的程序进行转换,输出中间代码。

5. 实验五:目标代码(1) 实现一个简单的目标代码器,将中间代码转换为目标代码。

(2) 对输入的中间代码进行转换,输出目标代码。

四、实验步骤与方法1. 实验一:词法分析(1) 编写词法分析器的代码。

(2) 测试并调试词法分析器。

2. 实验二:语法分析(1) 编写语法分析器的代码。

(2) 测试并调试语法分析器。

3. 实验三:语义分析(1) 编写语义分析器的代码。

(2) 测试并调试语义分析器。

4. 实验四:中间代码(1) 编写中间代码器的代码。

(2) 测试并调试中间代码器。

5. 实验五:目标代码(1) 编写目标代码器的代码。

(2) 测试并调试目标代码器。

五、实验注意事项1. 按照实验要求编写代码,注意代码规范和可读性。

编译原理实验报告小结

编译原理实验报告小结

一、实验背景编译原理是计算机科学的一个重要分支,主要研究如何将高级语言源代码转换为计算机可以执行的机器代码。

本实验旨在通过实践操作,加深对编译原理基本概念和算法的理解,提高编程能力和解决问题的能力。

二、实验目的1. 理解编译原理的基本概念和流程;2. 掌握词法分析和语法分析的基本方法;3. 熟悉编译过程中的中间代码生成和代码优化;4. 培养编程能力和团队协作精神。

三、实验内容1. 词法分析词法分析是编译过程的第一步,其主要任务是将源代码中的字符序列转换成一个个有意义的符号(单词)。

本实验中,我们实现了词法分析器,能够识别出标识符、关键字、运算符、常量等单词。

2. 语法分析语法分析是编译过程的核心,其主要任务是将词法分析器生成的单词序列按照一定的语法规则进行组织,形成语法树。

本实验中,我们实现了递归下降解析法,对表达式、赋值语句、函数定义等语法结构进行了分析。

3. 中间代码生成中间代码生成是编译过程中的一个重要环节,其主要任务是将语法树转换为一种抽象的、与具体机器无关的中间代码。

本实验中,我们实现了三地址代码生成,将语法树转换为三地址代码。

4. 代码优化代码优化是编译过程中的一个关键步骤,其主要任务是在保证程序正确性的前提下,提高程序的性能。

本实验中,我们实现了简单的代码优化,如常数传播、变量替换等。

四、实验结果与分析1. 实验结果通过实验,我们成功实现了词法分析、语法分析、中间代码生成和代码优化等功能。

以一个简单的C语言程序为例,我们能够将其转换为三地址代码,并进行简单的优化。

2. 实验分析(1)词法分析:本实验中,我们通过定义状态转换表和动作表,实现了对C语言源代码的词法分析。

实验结果表明,词法分析器能够准确地识别出标识符、关键字、运算符、常量等单词。

(2)语法分析:递归下降解析法是一种较为直观的语法分析方法。

本实验中,我们实现了递归下降解析法,对表达式、赋值语句、函数定义等语法结构进行了分析。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的掌握编译原理相关的基本概念和知识,学习编译器的工作原理,并通过实验加深对编译原理的理解。

二、实验环境本次实验使用C语言作为编程语言,搭建一个简单的词法分析器。

三、实验过程1.设计符号集根据编程语言的特点和需求,设计出合适的符号集。

本次实验我们选择了一些常见的C语言关键字和运算符作为符号集。

2.设计词法规则根据C语言的语法规则和词法分析的原理,设计出相应的正则表达式来识别各种符号。

例如,我们可以使用正则表达式"[a-zA-Z]+"来表示识别字母或者下划线组成的标识符。

3.实现词法分析器根据所设计的符号集和词法规则,利用C语言来实现一个简单的词法分析器。

词法分析器根据输入的源代码字符串,逐个检查字符并通过正则表达式来判断是否属于一些符号。

如果符号匹配成功,则返回相应的记号,并继续检查下一个字符,直到整个源代码字符串被扫描完毕。

4.测试词法分析器编写测试用例,测试词法分析器的正确性。

将一些C语言的源代码作为输入,观察词法分析器的输出是否符合预期结果。

四、实验结果经过一系列的实验过程,我们成功实现了一个简单的词法分析器。

通过对C语言的源代码进行输入测试,我们发现词法分析器能够正确识别各种符号,并返回相应的记号。

例如,当输入的源代码是"int main({ return 0; }"时,词法分析器能够正确返回"int"、"main"、"{"、"return"、"0"和"}"等记号。

五、实验总结通过本次实验,我们深入学习了编译原理的相关知识,并加深了对词法分析器的理解。

词法分析器是编译器中的一个重要组成部分,它负责将输入的源代码分解成一个个的符号,并通过记号的方式进行输出。

在实验过程中,我们遇到了一些问题和困难,例如如何设计合适的符号集和词法规则,以及如何正确实现词法分析器等。

编译原理课设实验报告

编译原理课设实验报告

《编译技术》课程设计报告实验名称编译器设计学号班级本课设的任务是达成一个完好的编译器,办理用户提交的切合所定文法的源程序代码,生成四元式中间代码,从而翻译成等价的X86 平台上汇编语言的目标程序。

编译程序的工作过程区分为以下 5 个过程:词法剖析,语法剖析,语义剖析和中间代码生成,代码优化,目标代码生成。

此中,词法剖析阶段的基本任务是从以字符串表示的源程序中辨别出拥有独立意义的单词符号,并以二元组的形式输出,以作为语法剖析阶段的输入。

语法剖析阶段的基本任务是将词法剖析阶段产生的二元组作为输入,依据语言的语法例则,辨别出各样语法成分,并判断该单词符号序列是不是该语言的一个句子。

语义剖析的任务是第一对每种语法单位进行静态的语义审察,而后剖析其含义,并用另一种语言形式(本课设采纳四元式 ) 来描绘这类语义。

代码优化的任务是对前阶段产生的中间代码进行等价变换或改造,以期获取更为高效即省时间和空间的目标代码。

目标代码生成的任务是将中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码(本课设生成汇编指令代码)。

在词法剖析阶段,经过 DOS环境手动输入字符串序列(以’#’作为结束标记)作为带剖析的源程序,调用词法扫描子程序将字符串以二元组的形式输出(如有不属于该语言单词符号出现,则进行犯错办理),词法扫描子程序包含了对源程序的预办理(忽视多余空格、回车换行符等空白字符),以及对单词的辨别和分类,以形成(单词种别,单词自己的值)形式的二元组,并将用户自定义变量信息存入程序变量信息表。

在语法剖析阶段,采纳自上而下的递归降落剖析法,从文法的开始符号出发,依据文法例则正向推导出给定句子。

依据递归降落剖析函数编写规则来编写相应的函数,在各个函数的剖析过程中调用词法剖析程序中的扫描程序,发出“取下一个单词符号”的命令,以获得下一个单词符号作语法剖析。

单词符号词语字符法法字符串表示的源程序分分析析器器取一下个单词符号在语义剖析和中间代码生成阶段,采纳语法制导翻译法,使用属性文法为工具来描绘程序设计语言的语义。

编译原理实验报告

编译原理实验报告

string st;
char str[20];
l=buf.length(); for(i=n;i<l;i++){
//获得小数部分的数值
if(buf[i]>='0'&&buf[i]<='9'){
s=s+(double)((double)(buf[i]-'0')/(double)base);
base=base*b;
int i,l;
int num=0;
char str[20];
word w;
l=s.length();
w.con="";
w.type='n';
for(i=0;i<l;i++){
if(s[i]>='0'&&s[i]<='9')
num=(s[i]-'0')+num*10;
else if(s[i]=='.'){
//其他字符
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='>'||c=='<'||c=='='||c=='('||c==')'||c==';'||c=='#'||c==' ')
2
实验目的
基本掌握计算机语言的词法分析程序的开发方法以及掌握计算机语言的语法分析程序设计与 属性文法应用的实现方法。通过自己动手实现上课讲述的编译的相关程序,加深对所学知识的理 解,进而培养“计算思维能力”——模型化、抽象思维能力、逻辑思维能力以及算法设计与分析能 力,程序设计与实现能力和计算机系统的认知、分析、设计和应用能力

编译原理教程实验报告

编译原理教程实验报告

一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。

二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。

2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。

3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。

4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。

5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。

6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。

四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。

2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。

3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。

4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。

5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。

6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。

五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。

编译原理中实验报告

编译原理中实验报告

实验名称:编译原理实验实验时间:2023年X月X日实验地点:实验室实验指导老师:XXX一、实验目的1. 理解编译原理的基本概念和流程。

2. 掌握词法分析和语法分析的基本方法。

3. 学习编译器生成中间代码和目标代码的过程。

4. 培养编程能力和问题解决能力。

二、实验内容本次实验主要包括以下内容:1. 词法分析:编写一个简单的词法分析器,将源代码输入转换为抽象语法树(AST)。

2. 语法分析:实现一个简单的递归下降解析器,对词法分析器输出的AST进行语法分析。

3. 中间代码生成:根据AST生成三地址代码(Three-Address Code)。

4. 代码优化:对生成的三地址代码进行优化。

5. 目标代码生成:将优化后的三地址代码转换为机器代码。

三、实验步骤1. 设计词法分析器首先,我们需要设计一个能够识别源代码中各种单词的词法分析器。

在本实验中,我们定义了以下几种单词:- 关键字:如if、else、while、int、float等。

- 标识符:由字母、数字和下划线组成,不能以数字开头。

- 常量:包括整型常量和浮点型常量。

- 运算符:如+、-、、/、==、<=等。

- 分隔符:如(、)、;、,等。

根据以上定义,我们可以编写一个词法分析器,它将输入的源代码字符串逐个字符地读取,并根据定义的规则识别出相应的单词。

2. 语法分析词法分析器生成的AST是一个树形结构,其中每个节点代表源代码中的一个单词或符号。

为了进一步分析AST的结构,我们需要实现一个递归下降解析器,它能够根据语法规则对AST进行解析。

在本实验中,我们以一个简单的算术表达式为例,实现了一个递归下降解析器。

解析器从AST的根节点开始,按照语法规则递归地解析每个子节点,直到整个表达式被解析完毕。

3. 中间代码生成在完成语法分析后,我们需要将AST转换为中间代码。

在本实验中,我们选择了三地址代码作为中间代码的形式。

三地址代码是一种表示赋值、条件判断和循环等操作的方式,它使用三个操作数和两个操作符来表示一个操作。

编译原理熟悉实验报告

编译原理熟悉实验报告

一、实验目的1. 理解编译原理的基本概念和流程;2. 掌握编译器的各个阶段及其实现方法;3. 熟悉编译器各个阶段中使用的算法和数据结构;4. 培养编程能力和问题解决能力。

二、实验内容1. 词法分析;2. 语法分析;3. 语义分析;4. 代码生成;5. 符号表;6. 中间代码生成。

三、实验步骤1. 词法分析(1)设计词法分析器:首先需要确定源程序中的词法单元,如标识符、关键字、运算符等。

然后,编写代码实现词法分析器,对源程序进行扫描,将词法单元转换成词法符号。

(2)实现词法分析器:使用C语言或Java等编程语言实现词法分析器,完成词法单元的识别和转换。

2. 语法分析(1)设计语法分析器:根据源程序的语言规范,设计语法分析器,实现语法规则的定义和匹配。

(2)实现语法分析器:使用递归下降分析法、LL(1)分析法、LR(1)分析法等实现语法分析器,对词法分析器输出的词法符号序列进行语法分析。

3. 语义分析(1)设计语义分析器:根据源程序的语言规范,设计语义分析器,实现语义规则的检查和类型检查。

(2)实现语义分析器:使用C语言或Java等编程语言实现语义分析器,完成语义规则的检查和类型检查。

4. 代码生成(1)设计代码生成器:根据源程序的语言规范,设计代码生成器,将抽象语法树转换成目标代码。

(2)实现代码生成器:使用C语言或Java等编程语言实现代码生成器,完成抽象语法树到目标代码的转换。

5. 符号表(1)设计符号表:在编译过程中,需要记录变量、函数等信息,设计符号表实现这些信息的存储和管理。

(2)实现符号表:使用C语言或Java等编程语言实现符号表,完成变量、函数等信息的存储和管理。

6. 中间代码生成(1)设计中间代码生成器:根据源程序的语言规范,设计中间代码生成器,将抽象语法树转换成中间代码。

(2)实现中间代码生成器:使用C语言或Java等编程语言实现中间代码生成器,完成抽象语法树到中间代码的转换。

四、实验结果与分析1. 词法分析器能够正确识别源程序中的词法单元,并将它们转换成词法符号。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Version 2.00; Feb. 22, 2008编译原理实验议程管理系统Agenda目录1实验描述1 1.1实验目的 (1)1.2实验环境 (1)1.2.1编程语言 (1)1.2.2开发工具 (1)1.2.3编码规范 (1)1.3实验内容 (1)1.4功能需求 (2)1.4.1用户注册 (2)1.4.2添加会议 (2)1.4.3查询会议 (2)1.4.4删除会议 (2)1.4.5清除会议 (3)1.4.6其他 (3)1.5接口约定 (3)1.6提交结果 (4)1.6.1提交方式 (4)1.6.2组织实验结果 (4)1.7实验交流 (4)2实验评价6 2.1主要评价依据 (6)2.1.1编程风格 (6)2.1.2面向对象设计 (6)2.1.3其他 (6)2.2满足最低要求 (7)2.3如何获得高分 (7)1实验描述在开始实验之前,请务必花足够时间阅读完本文档关于实验的描述与约定!1.1实验目的在初步掌握Java语言和面向对象程序设计方法后,本实验帮助学生巩固对封装、信息隐藏、数据抽象、异常处理等机制的理解与运用,并进一步掌握继承、运行时多态性、程序包、多层体系结构、设计模式等机制,从而顺利过渡到后续的编译原理实验。

1.2实验环境本实验基于当前主流的面向对象开发平台,编码规范遵循主流的参考规范。

1.2.1 编程语言Java语言,JDK 1.5版本。

1.2.2 开发工具学生可自由选择Eclipse、JBuilder等IDE环境,也可直接采用UltraEdit、EditPlus等编辑器在命令行工作。

但提交的实验结果必须独立于特定的IDE,可直接运行在JDK上。

1.2.3 编码规范你需要采用面向对象风格来设计实验中的所有类,并遵循一种良好的程序设计习惯。

例如,如果你将一个程序的很多功能全部放在一个长长的main()方法中实现,这样的设计与编码风格会被扣分。

学生在实验过程中应注意培养规范的编码风格。

本实验要求所有源代码严格遵循Sun公司关于Java程序设计语言的编码规范,参见:/docs/codeconv/。

完成后的代码应使用JDK附带的文档工具javadoc根据源程序中的文档化注释生成相应的文档。

1.3实验内容采用面向对象方法和Java语言开发一个基于命令行交互方式的议程(agenda)管理系统。

已注册到系统的用户(user)可添加(add)、删除(delete)、查询(query)系统中记录的会议(meeting)安排;系统还提供新用户注册(register)、清除(clear)某一用户所有会议安排等管理功能。

1.4功能需求本实验要求完成的议程管理系统至少应实现如下功能。

1.4.1 用户注册注册新用户时,应为该用户设置一个唯一的用户名以及一个密码。

如果注册时提供的用户名已由其他用户使用,应反馈一个适当的出错信息;成功注册后,亦应反馈一个成功注册的信息。

1.4.2 添加会议已注册的用户可以添加一个新会议到其议程安排中。

规定会议仅允许在两个已注册的用户间举行,不可创建无另一已注册用户的会议。

添加会议时提供的信息应包括:会议的起始时间(start time)和终止时间(end time)、描述本次会议的标签(label)、以及预约的另一用户名字(scheduled user)。

成功添加会议后,它应既出现在发起该会议的用户的议程中,也应出现在该会议所预约的另一用户的议程中。

注意,用户不允许分身参加多个会议,即如果用户自己或被预约的用户已有一个会议安排与新会议在时间上相互重叠(overlap),该新会议将无法成功添加到议程管理系统中。

用户在添加会议后,应获得适当的反馈信息,以得知是成功地添加了新会议,还是在添加过程出现了某些错误。

1.4.3 查询会议已注册的用户可以查询自己的议程中某一时间段(time interval)的所有会议安排。

查询会议时提供的参数应包括所关注时间段的起始时间和终止时间;查询结果返回该用户议程中在指定时间范围内找到的所有会议安排的列表,在列表中给出每一会议的起始时间、终止时间、标签、以及被预约的另一用户的名字。

注意,查询会议的结果既应包括用户作为发起人的那些会议,也应包括用户作为被预约人的那些会议。

1.4.4 删除会议已注册的用户可以删除自己登记的某一会议安排。

删除会议时,提供的参数除执行删除功能的用户的名字及其密码外,还包括一个能惟一地标识待删除的会议的参数(提示:可以简单地以会议标签作为一个会议的惟一标识)。

1.4.5 清除会议已注册的用户可以清除自己创建的所有会议安排。

1.4.6 其他本实验不要求实现程序中对象的持久性(object persistence)。

1.5接口约定本实验要求编写一个基于命令行交互方式的应用程序来访问议程管理系统中的信息。

系统启动后,显示输入提示符“$”(类似MS-DOS的提示符“>”),然后与终端用户以命令行方式进行交互。

设所有命令的名字是大小写无关的,但命令的参数却是大小写敏感的。

约定系统支持的交互命令格式如下:$ register [userName] [password]该命令用于注册一个新用户。

其中,参数userName是用户提供的注册名字,password是用户自己选择的密码。

$ add [userName] [password] [other] [start] [end] [title]该命令用于添加一个新的会议安排。

其中,参数userName是一个已注册的用户名字,password 是该用户的密码,other是新添加会议所预约的另一已注册用户的名字,start是会议的起始时间,end是会议的终止时间,title是新添加会议的标签。

$ query [userName] [password] [start] [end]该命令用于查询某一用户在某一时间段内的会议安排。

其中,参数userName是一个已注册的用户名字,password是该用户的密码,start和end分别是查询时间段的起始时间和终止时间,该时间段内查获的会议安排将被返回。

$ delete [userName] [password] [meetingId]该命令用于删除某一用户的指定会议安排。

其中,参数userName是一个已注册的用户名字,password是该用户的密码,meetingId指定将被从议程中删除的会议的标识。

$ clear [userName] [password]该命令用于清除某一用户的所有会议安排。

其中,参数userName是一个已注册的用户名字,password是该用户的密码。

$ batch [fileName]该命令用于批处理存储在文本文件fileName中的register、add、query、delete、clear等命令,其中每一条命令(包括其参数)单独占一行。

该命令相当于MD-DOS中的脚本文件(即批命令文件.bat或.cmd)。

借助该命令,你可以方便地运行多个不同的测试用例。

$ quit该命令用于退出议程管理系统。

1.6提交结果如果不按指定方式组织你的实验结果,会影响到你的实验成绩!1.6.1 提交方式注意你的实验结果不应只包含源程序代码,还应包括一个面向对象程序的设计文档(建议命名为design.doc或design.pdf)、编译与运行程序的脚本(.bat文件)、各种测试用例(尽量支持回归测试,Regression Testing)等。

此外,至少还要包括一个纯文本的自述文件readme.txt,其中描述你自己的姓名、学号、email、电话等基本信息,并将你在本实验中的收获体会也写在自述文件中。

你的实验结果全部存放在一个名为“学号+姓名”(中间不要任何空格)的文件夹中,并在指定时间汇总到班长或学习委员处,再由班长或学习委员统一提交给任课教师。

1.6.2 组织实验结果每一份实验报告提交结果应按如下方式组织:(1) 在子目录src中存放源代码,包括:z议程管理系统主程序的源代码AgendaService.java。

z程序用到的其他源码,取决于你的设计,均存放于程序包agenda中,其下可设计其他的子程序包。

(2) 在子目录bin中存放由源代码编译出来的可执行程序,即Java字节码。

(3) 在子目录doc中存放根据上述源代码生成的javadoc文档。

(4) 在工作目录的根目录中直接存放编译、运行与调试有关文件,包括:z编译所有源代码的脚本文件(批命令)build.bat。

z运行议程管理系统的脚本文件agenda.bat。

z其他用于调试、测试程序的脚本、配置文件、测试用例等;测试用例众多时,可安排在单独的子目录中。

(5) 在工作目录的根目录中直接存放其他文档,包括:z描述你的面向对象设计结果的Word文档design.doc,其中包括UML类图及其说明。

z描述程序运行测试用例的截图与解释的Word文档test.doc。

z关于实验完成人基本信息、提交结果描述、实验心得等的补充说明文档readme.txt。

1.7实验交流如果在本实验的课堂交流时你被随机地抽点到,建议你按以下次序展示你的实验结果:z介绍自己对问题的理解以及程序的设计,要求使用UML展示你的设计结果!z展示你的文档化注释生成的文档(由javadoc生成的HTML文档)以及源程序清单。

z运行多个测试用例演示程序的运行效果(屏幕截图或屏幕录像)。

z接受老师和其他同学的提问。

2实验评价任课教师将从文档、源程序、执行结果等多个角度评价你的实验结果,因而它们也是你完成该实验需要重点注意的地方。

2.1主要评价依据2.1.1 编程风格z源程序中标识符命名、程序版面、程序注释等影响程序可理解性的要素,以及是否能熟练地运用Java语言的文档化注释。

z本实验要求至少遵循Sun公司制订的Java编码规范,完成后的代码必须使用JDK附带的文档工具javadoc根据源程序中的文档化注释生成相应的文档(可根据自己的英文水平自由选择使用中文或英文书写文档化注释)。

2.1.2 面向对象设计z程序结构的设计是否合理:从大的方面看,程序体系结构的层次划分清晰;从小的方面看,程序中对类或方法的抽象符合面向对象与结构化程序设计思想,程序的接口(包括对象接口和方法接口)的设计应合理。

z程序对未来变化的适应性如何,譬如是否容易修改或不必修改就应付可能发生的变化(譬如在交互方式中增加新的命令unregister、help等),是否方便在不同的环境下复用程序或程序中的构件。

z源程序中对异常的处理是否充分,可执行程序的健壮性如何(在异常情况下工作的能力)。

z为应付未来的大型程序设计任务,在实验中是否能正确地运用package机制组织你的程序。

2.1.3 其他z为尽可能提高程序的正确性,测试用例的选择是否完善、有无其他措施有助于提高程序的正确性。

相关文档
最新文档