北京科技大学编译原理实验报告

合集下载

编译原理 实验报告

编译原理 实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的和要求本次实验旨在对PL_0语言进行功能扩充,添加新的语法特性,进一步提高编译器的功能和实用性。

具体要求如下:1.扩展PL_0语言的语法规则,添加新的语法特性;2.实现对新语法的词法分析和语法分析功能;3.对扩展语法规则进行语义分析,并生成中间代码;4.验证扩展功能的正确性。

二、实验内容1.扩展语法规则本次实验选择扩展PL_0语言的语句部分,添加新的控制语句,switch语句。

其语法规则如下:<switch_stmt> -> SWITCH <expression> CASE <case_list><default_stmt> ENDSWITCH<case_list> -> <case_stmt> , <case_stmt> <case_list><case_stmt> -> CASE <constant> : <statement><default_stmt> -> DEFAULT : <statement> ,ε2.词法分析和语法分析根据扩展的语法规则,需要对新的关键字和符号进行词法分析,识别出符号类型和记号类型。

然后进行语法分析,建立语法树。

3.语义分析在语义分析阶段,首先对switch语句的表达式进行求值,判断其类型是否为整型。

然后对case语句和default语句中的常量进行求值,判断是否与表达式的值相等。

最后将语句部分生成中间代码。

4.中间代码生成根据语法树和语义分析的结果,生成对应的中间代码。

例如,生成switch语句的跳转表,根据表达式的值选择相应的跳转目标。

5.验证功能的正确性设计一些测试用例,验证新语法的正确性和扩展功能的实用性。

三、实验步骤与结果1.扩展语法规则,更新PL_0语法分析器的词法规则和语法规则。

编译原理实验报告

编译原理实验报告

编译原理实验报告实验⼀词法分析⼀、实验⽬的设计、编制并调试⼀个词法分析程序,加深对词法分析原理的理解。

⼆、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是⼩写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空⽩、制表符和换⾏符组成。

空格⼀般⽤来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码单词符号种别码单词符号种别码bgin 1 :17If 2 := 18Then 3 < 20wile 4 <> 21do 5 <= 22end 6 > 23lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26—14 ( 27* 15 ) 28/ 16 # 02.3 词法分析程序的功能:输⼊:所给⽂法的源程序字符串。

输出:⼆元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词⾃⾝字符串;(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表⽰的源程序中识别出具有独⽴意义的单词符号,其基本思想是根据扫描到单词符号的第⼀个字符的种类,拼出相应的单词符号。

3.1 主程序⽰意图:主程序⽰意图如图3-1所⽰。

其中初始包括以下两个⽅⾯:⑴关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在⼀张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。

编译原理实验报告

编译原理实验报告

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

二、实验环境本次实验使用的编程语言为 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++,开发环境为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. 最后,根据抽象语法树生成目标代码。

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

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

编译原理实验报告(手打)

编译原理实验报告(手打)

《编译原理》实验报告班级:计C104姓名:李云霄学号:108490实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。

二、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。

输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。

输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。

三、实现方法与环境1、首先设计识别各类单词的状态转换图。

描述无符号常数的确定、最小化状态转换图如图1所示。

其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。

图1 文法G[<无符号数>]的状态转换图其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。

在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。

四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JAVA语言)直接编写词法分析程序。

编译原理实验报告1

编译原理实验报告1

编译原理实验报告某某:班级:学号:自评:中实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。

二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。

例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。

输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。

输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。

例如,所输出的每一单词均按形如(CLASS,V ALUE)的二元式编码。

对于变量和常数,CLASS字段为相应的类别码;V ALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。

对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,V ALUE字段则为“空”。

另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。

三、实现方法与环境词法分析是编译程序的第一个处理阶段,本次试验用手工的方式(C语言)构造词法分析程序。

根据文法和状态转换图直接编写词法分析程序。

四、基本实验题目1)题目1:试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。

语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。

参考实现方法简述如下。

单词的分类:构造上述语言中的各类单词符号及其分类码表。

表I 语言中的各类单词符号及其分类码表+ 15 PL- 16 MI* 17 MU/ 18 DI处理过程:在一个程序设计语言中,一般都含有若干类单词符号,为此首先为每类单词建立一X状态转换图,然后将这些状态转换图合并成一X统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。

编译原理实验报告

编译原理实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的本次实验的目的是了解编译原理的基本知识,并运用所学知识实现一个简单的词法分析器。

二、实验内容1.设计一个词法分析器,能够识别并输出源程序中的关键字、标识符、常数和运算符等。

2.设计并实现一个词法分析器的算法。

3.对编写的词法分析器进行测试。

三、实验过程1.设计词法分析器的算法在设计词法分析器的时候,需要先了解源程序的基本构成,了解关键字、标识符、常数和运算符等的特点,以及它们在源程序中的表示形式。

然后,根据这些特点,设计一个适合的算法来进行词法分析。

2.实现词法分析器根据设计好的算法,在编程语言中实现词法分析器。

在实现过程中,需要根据不同的词法单元,设计相应的正则表达式来进行匹配和识别。

3.测试词法分析器编写几个简单的测试用例,对词法分析器进行测试。

检查输出结果是否正确,并根据实际情况对词法分析器进行调试和优化。

四、实验结果经过测试,词法分析器能够正确识别并输出源程序中的关键字、标识符、常数和运算符等。

测试用例的输出结果与预期结果一致。

五、实验总结通过本次实验,我学习了编译原理的基本知识,掌握了词法分析器的设计和实现方法。

在实验过程中,我遇到了一些困难和问题,但通过仔细思考和查阅文献资料,最终成功地完成了实验任务。

这次实验不仅帮助我巩固了所学知识,还提高了我的编程能力和解决问题的能力。

通过实践,我深刻体会到了编译原理在软件开发中的重要性和作用,并对将来的学习和工作有了更好的规划和方向。

通过本次实验,我对编译原理的相关知识有了更深入的理解和掌握,对词法分析器的设计和实现方法有了更加清晰的认识。

同时,我还学会了如何进行实验报告的撰写,提高了我的文档写作能力。

通过本次实验,我不仅实现了实验的目标,还提高了自己的综合素质和能力。

编译原理实验报告小结

编译原理实验报告小结

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理实验报告

编译原理实验报告

实验一词法分析一、实验目的通过设计、编写和调试词法分析程序,了解词法分析程序的作用,组成结构,不同种类单词的识别方法,掌握由单词的词法规则出发,画出识别单词的状态转换图,然后在用程序实现词法分析程序设计方法。

二、词法规则1、注释用{和}括起来。

注释体中不能有{。

注释可以出现在任何记号的后面。

2、记号间的空格可有可无,但关键字前后必须有空格、换行、程序的开头或者结尾的原点。

3、标识符的记号id 与以字母开头的字母数字串相匹配:Letter->[a-zA-Z]Digit->[0-9]Id->letter (letter | digit)*4、记号num与无符号整数相匹配:Digits->digit digit*Optional_fraction -> . Digits | ɛOptional_exponent->(E(+ | - | ɛ ) digits) | ɛNum ->digits optional_fraction optional_exponent5、关键字要被保留且在文法中以黑体出现6、关系运算符(relop)指:=、<、<>、<=、>=、>7、Addop: + 、 - 、or8、Mulop:*、/ 、div、mod、and9、Assignop: :=三、词法分析程序详细设计及判别状态图1、无符号数(可带小数和指数)的状态转换图:2、标识符/关键字的状态转换图:字母或数程序详细设计:四、开发环境本程序在Microsoft Visual C++ 6.0环境中编写,无特殊编译要求。

五、函数清单void LexcialAnalysis(FILE *fp);//词法分析主函数int JudgeFirstLetter(char ch);//判断单词的第一个字符int IsDigit(char ch);//判断是否为数字int IsLetter(char ch);//判断是否为字母int IsSpecialPunc(char ch);//判断是否为特殊标点void RecogDigit(char StrLine[]);//用状态图识别无符号数字void RecogIdentifier(char strLine[]);//用状态图识别标识符void RecogPunc(char strLine[]);//识别特殊标点int IsKeyWord(string str);//判断标识符是否为关键字void error();//出错处理六、测试程序program example(input, output);{comments goes here!}var x, y: integer;function gcd(a, b: integer): integer;beginif b =1.2e3 then gcd := aelse gcd := gcd(b, a mod b)end;beginread(x, y);write(gcd(x, y));end.七、运行效果八、实验总结通过这次编译器词法分析程序的编写,我更好地了解了词法分析的作用及工作原理,讲课本中的知识融入到程序编写过程中,理论结合了实际。

编译原理课设实验报告

编译原理课设实验报告

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

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

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

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

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

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

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

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

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

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

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

编译原理教程实验报告

编译原理教程实验报告

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

二、实验内容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,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字。

标示符。

无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符.字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include 〈stdio.h〉#include <math.h>#include <string。

h>int i,j,k;char c,s,a[20],token[20]={’0’};int letter(char s){if((s〉=97)&&(s〈=122)) return(1);else return(0);}int digit(char s){if((s〉=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else”)==0) return(3);else if(strcmp(token,"switch”)==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf(”please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!=’#’);i=1;j=0;get();while(s!=’#'){ memset(token,0,20);switch(s){case 'a':case ’b':case ’c':case ’d':case ’e’:case ’f’:case 'g’:case ’h':case 'i':case ’j':case 'k’:case ’l':case 'm’:case 'n':case ’o':case ’p':case ’q’:case 'r’:case 's’:case 't’:case ’u’:case ’v’:case ’w’:case ’x':case ’y':case ’z’:while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)”,6,token);else printf("(%d,—)",k);break;case ’0':case ’1’:case ’2':case ’3':case '4’:case '5’:case ’6':case ’7’:case ’8’:case '9’:while(digit(s)){token[j]=s;j=j+1;get();}retract();printf(”%d,%s",7,token);break;case '+':printf(”(’+',NULL)”);break;case ’-':printf("(’-',null)");break;case ’*':printf(”('*’,null)");break;case '<':get();if(s=='=’) printf(”(relop,LE)”);else{retract();printf("(relop,LT)");}break;case ’=':get();if(s=='=’)printf("(relop,EQ)");else{retract();printf(”('=',null)”);}break;case ’;':printf(”(;,null)");break;case ' ’:break;default:printf("!\n”);}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术.三、实验原理:1、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。

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

编译原理实验报告学院: 计算机与通信工程学院专业: 计算机科学与技术班级:学号:姓名:实验成绩:词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图:3.2词法分析程序流程图:四、词法分析程序的C++语言程序源代码:#include"stdio.h" #include"stdlib.h" #include"string.h"#define _KEY_WORD_END "waiting for your expanding" typedef struct开始 变量初始化是否文件结束?返回拼数Syn=11返回拼字符串是否是关键字?Syn 为对应关键字的单词种别码Syn=10给不同的符号相同的 Syn 值报错是否数字字母是否运算符, 界符等其他{int typenum;char * word;}WORD;char input[255];char token[255]="";int p_input;int p_token;char ch;char * rwtab[]={"begin","if","then","while","do","end",_KEY_WORD_END}; WORD * scaner();int main(){int over=1;WORD* oneword=new WORD;printf(" 输入源程序(以#结束):");scanf("%[^#]s",input);p_input=0;printf("Your words:\n%s\n",input);while(over<1000&&over!=-1){oneword=scaner();if(oneword->typenum<1000)printf("(%d,%s)\n",oneword->typenum,oneword->word);over=oneword->typenum;}printf("\npress # to exit:");scanf("%[^#]s",input);return 0;}char m_getch(){ch=input[p_input];p_input=p_input+1;return(ch);}void getbc(){while(ch==' '||ch==10){ch=input[p_input];p_input=p_input+1;}}void concat(){token[p_token]=ch;p_token=p_token+1;token[p_token]='\0';}int letter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;elsereturn 0;}int digit(){if(ch>='0'&&ch<='9')return 1;elsereturn 0;}int reserve(){int i=0;while(strcmp(rwtab[i],_KEY_WORD_END)){if(!strcmp(rwtab[i],token)){return i+1;}i=i+1;}return 10;}void retract(){p_input=p_input-1;}char * dtp(){return NULL;}WORD *scaner(){WORD *myword=new WORD;myword->typenum=10;myword->word=" ";p_token=0;m_getch();getbc();if(letter()){while(letter()||digit()){concat();m_getch();}retract();myword->typenum=reserve();myword->word=token;return(myword);}else if(digit()){while(digit()){concat();m_getch();}retract();myword->typenum=20;myword->word=token;return(myword);}else switch(ch){case'=': m_getch();if(ch=='='){myword->typenum=39;myword->word="==";return(myword);}retract();myword->typenum=21;myword->word="=";break;case'+': myword->typenum=22;myword->word="+";return(myword);break;case'-': myword->typenum=23;myword->word="-";return(myword);break;case'*': myword->typenum=24;myword->word="*";return(myword);break;case'/': myword->typenum=25;myword->word="/";return(myword);break;case'(': myword->typenum=26;myword->word="(";return(myword);break;case')': myword->typenum=27;myword->word=")";return(myword);break;case'[': myword->typenum=28;myword->word="[";return(myword);break;case']': myword->typenum=29;myword->word="]";return(myword);break;case'{': myword->typenum=30;myword->word="{";return(myword);break;case'}': myword->typenum=31;myword->word="}";return(myword);break;case',': myword->typenum=32;myword->word=",";break;case':': myword->typenum=33;myword->word=":";return(myword);break;case';': myword->typenum=34;myword->word=";";return(myword);break;case'>': m_getch();if(ch=='='){myword->typenum=37;myword->word=">=";return(myword);}retract();myword->typenum=35;myword->word=">";return(myword);break;case'<': m_getch();if(ch=='='){myword->typenum=38;myword->word="<=";return(myword);}retract();myword->typenum=36;myword->word="<";return(myword);break;case'!': m_getch();if(ch=='='){myword->typenum=40;myword->word="!=";return(myword);}retract();myword->typenum=-1;myword->word="ERROR";break;case'\0': myword->typenum=1000;myword->word="OVER";return(myword);break;default: myword->typenum=-1;myword->word="ERROR";return(myword);}}五、结果分析:输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后如图所示:六、总结:词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

相关文档
最新文档