编译原理实验报告(C语言)

合集下载

编译原理 实验报告

编译原理 实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理实验报告(C语言)

编译原理实验报告(C语言)

编译原理实验报告实验项目1:词法分析程序实验一、实验的目的与任务:编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。

设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现方法,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。

编译原理是一门理论性和实践性都比较强的课程。

进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。

同时培养学生实际动手能力。

编译实验由三个独立实验组成,按照由浅入深进行排列,希望通过本实验使学生更深学习并理解编译的主要过程和相关方法。

词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。

基本符号是与输入的语言定义的词法所规定的终结符。

本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。

并依次输出各个单词的内部编码及单词符号自身值。

(遇到错误时可显示“Error”,然后跳过错误部分继续进行)二、题目分析1.这里采用C语言编写的源程序作为词法分析程序的输入数据,输入数据保存在“in.txt”记事本中,将分析结果存在“out.txt”记事本中。

词法分析器的源代码使用C语言编写。

2.下面就词法分析程序中的主要变量进行说明:主函数main():打开要分析的C语言源程序,若不能正确打开,则报错。

先从源程序中读入一个字符ch,然后进行如下处理:1、cp消耗掉空格,制表符,换行符后,cp数组复位,开始检测cp;2、数字检测,对照符号表输出,若匹配成功,则返回序号;3、字符串检测, 对照符号表输出,若匹配成功,则返回序号;4、基本保留字检测,对照符号表输出,若匹配成功,则返回序号;5、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是否跟着是注释语句。

编译原理实验报告(C语言)

编译原理实验报告(C语言)

else if(strcmp(word,"if")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',12,')'); else if(strcmp(word,"else")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',13,')'); else if(strcmp(word,"switch")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',14,')'); else if(strcmp(word,"case")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',15,')'); else if(strcmp(word,"for")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',16,')'); else if(strcmp(word,"do")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',17,')'); else if(strcmp(word,"while")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',18,')'); else if(strcmp(word,"goto")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',19,')'); else if(strcmp(word,"continue")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',20,')'); else if(strcmp(word,"break")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',21,')');

编译原理实验报告

编译原理实验报告

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

⼆、实验要求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语言编写)

编译原理实验报告实验名称:预测分析法姓名:专业班级:计科学号:指导老师:日期:2011年6月1日目的要求1.构造文法的语法分析程序,要求采用预测分析法对输入的字符串进行语法分析。

2.加深对预测分析LL(1)分析法的理解和掌握。

实验内容对文法G进行语法分析,文法G如下所示:*0. S→a */*1. S→^*2. S→(T)*3. T→SW **4. W→,SW*5. W→ε;并对任给的一个输入串进行语法分析检查。

程序要求能对输入串进行预测分析,能判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。

程序输入/输出示例:输入:一个以 # 结束的符号串:例如:(a,a)#输出:步数分析栈输入串所用规则(1) #S (a,a))# 2源程序://LL(1)预测分析控制程序#include <stdio.h>#include <stdlib.h>#include <string.h>char str[100]; //存储待分析的句子const char T[ ] = "a^(),#"; //终结符,分析表的列符const char NT[ ] = "STW"; //非终结符,分析表的行符/*指向产生式右部符号串*/const char *p[] = {/*0. S→a */ "a",/*1. S→^ */ "^",/*2. S→(T) */ "(T)",/*3. T→SW */ "SW",/*4. W→,SW */ ",SW",/*5. W→ε; */ ""};//设M[i][j]=x,通过p[M[i][j]]=p[x]获取右部符号串。

const int M[][6] = {/* a ^ ( ) , # *//*S*/ { 0, 1, 2, -1, -1, -1 },/*T*/ { 3, 3, 3, -1, -1, -1 },/*W*/ { -1, -1,-1, 5, 4, -1 }};void init()//输入待分析的句子{printf("请输入待分析的句子(以$结束):\n");scanf("%s",str);}int lin(char c);//非终结符转换为行号int col(char c);//终结转换为列号bool isNT(char c);//isNT判断是否是非终结符bool isT(char c);//isT判断是否是终结符。

编译原理实验报告

编译原理实验报告

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

二、实验环境本次实验使用的编程语言为 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("(非法符号)");。

编译原理实验报告

编译原理实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理语法分析实验报告

编译原理语法分析实验报告

语法分析实验报告实验目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二、实验要求利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

2.1 待分析的简单语言的语法用扩充的BNF表示如下:1)<程序>::=begin<语句串>end2)<语句串>::=<语句>{;<语句>}3)<语句>::=<赋值语句>4)<赋值语句>::=ID:=<表达式>5)<表达式>::=<项>{+<项> | -<项>}6)<项>::=<因子>{*<因子> | /<因子>7)<因子>::=ID | NUM | (<表达式>)2.2 实验要求说明输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:输入 begin a:=9; x:=2*3; b:=a+x end #输出语法分析成功输入 x:=a+b*c end #输出语法分析2.3 语法分析程序的酸法思想1)主程序示意图如图2-1所示。

图2-1 语法分析主程序示意图2)递归下降分析程序示意图如图2-2所示。

3)语句串分析过程示意图如图2-3所示。

图2-2 递归下降分析程序示意图图2-3 语句串分析示意图4)statement语句分析程序流程如图2-4、2-5、2-6、2-7所示。

图2-4 statement语句分析函数示意图图2-5 expression表达式分析函数示意图图 2-6 term分析函数示意图图2-7 factor 分析过程示意图三、语法分析程序的C 语言程序源代码#include <stdio.h>#include <stdlib.h>#include <string.h>char prog[100],ch,token[8];int p=0,syn,n,i;char *keyword[6]={"begin","then","if","while","do","end"};void scaner();void Irparse();void statement();void expression_r();void term();void factor();void main(){int select=-1;p=0;printf("please input sentence, end of '#' !\n");do{ch=getchar();prog[p++]=ch;}while(ch!='#');p=0;printf("请输入1 或 2 \n 1.词法分析\n 2.语法分析\n");scanf("%d",&select);if(select==1){do{scaner();switch(syn){case -1:printf("词法分析出错\n");break;default :printf("<%d,%s>\n",syn,token);break; }}while(syn!=0);printf("词法分析成功\n");}else if(select==2){scaner();if(syn==1){Irparse();}//beginelse{printf("语法分析出错! 请检查begin关键字\n");return;} if(syn==6)//end{scaner();if(syn==0){printf("恭喜语法分析成功\n");}else{printf("语法分析出错! 请检查是否缺少'#'\n");} }else{printf("语法分析出错! 请检查是否缺少'end'\n");}}getchar();}void scaner(){for(n=0;n<8;n++){token[n]='\0';}n=0;ch=prog[p++];while(ch==' '){ch=prog[p++];}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){do{token[n++]=ch;ch=prog[p++];}while((ch>='a'&&ch<='z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch <='9'));syn=10;for(n=0;n<6;n++){if(strcmp(token,keyword[n])==0){syn=n+1;}}p--;//return;}else if(ch>='0'&&ch<='9'){p--;do{token[n++]=prog[p++];ch=prog[p];}while(ch>='0'&&ch<='9');syn=11;return;}else{//ch=prog[p++];switch(ch){case '+':syn=13;token[0]=ch;break;case '-':syn=14;token[0]=ch;break;case '*':syn=15;token[0]=ch;break;case '/':syn=16;token[0]=ch;break;case ':':syn=17;token[0]=ch;ch=prog[p++];if(ch=='='){token[1]=ch;syn++;}else p--;break;case '<':syn=20;token[0]=ch;ch=prog[p++];if(ch=='>'){token[1]=ch;syn++;}else if(ch=='='){token[1]=ch;syn=syn+2;} else p--;break;case '>':syn=23;token[0]=ch;ch=prog[p++];if(ch=='='){token[1]=ch;syn++;}else p--;break;case '=':syn=25;token[0]=ch;break;case ';':syn=26;token[0]=ch;break;case '(':syn=27;token[0]=ch;break;case ')':syn=28;token[0]=ch;break;case '#':syn=0;token[0]=ch;break;default: printf("词法分析出错! 请检查是否输入非法字符\n");syn=-1;break;}//return;}}void Irparse(){scaner();statement();while(syn==26)//;{scaner();statement();}}void statement(){if(syn==10){scaner();if(syn==18){scaner();expression_r();}else{printf("语法分析出错! 请检查表达式是否正确\n");return;}}else{printf("语法分析出错! 请检查语句是否正确\n");return; }}void expression_r(){term();while(syn==13||syn==14)//+ -{scaner();term();}}void term(){factor();while(syn==15||syn==16)//* /{scaner();factor();}}void factor(){if(syn==10||syn==11){scaner();}else if(syn==27){scaner();expression_r();if(syn==28){scaner();}else {printf("语法分析出错! 请检查是否缺少')'\n");return;}}else {printf("语法分析出错! 请检查是否输入非法字符\n");return;}}四、程序测试结果1)开始调试的界面2)对源程序begin a:=9; x:=2*3; b:=a+x end #的源文件,经过语法分析后如下图4-1所示:图 4-1 正确结果输出3)对源程序x:=a+b*c end #的源文件,经过语法分析后如下图4-2所示:图 4-2 错误结果输出五、总结通过对语法分析程序的设计和编写,使自己获得了很大的收获,并且使自己对语法分析程序的功能有了更进一步认识。

编译原理实验报告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统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。

编译原理预测分析法C语言的实验报告

编译原理预测分析法C语言的实验报告

题目:编写识别由下列文法所定义的表达式的预测分析程序。

E→E+T | E-T | TT→T*F | T/F |FF→(E) | i输入:每行含一个表达式的文本文件。

输出:分析成功或不成功信息。

(题目来源:编译原理实验(三)--预测(LL(1))分析法的实现)解答:(1)分析a) ∵E=>E+T=>E+T*F=>E+T*(E)即有E=>E+T*(E)存在左递归。

用直接改写法消除左递归,得到如下:E →TE’ E’ →+TE’ | −TE’|εT →FT’ T’ →*FT’ | /FT’|εF → (E) | i对于以上改进的方法。

可得:对于E’:FIRST( E’ )=FIRST(+TE’)∪FIRST(-TE’)∪{ε}={+,−,ε}对于T’:FIRST( T’ )=FIRST(*FT’)∪FIRST(/FT’)∪{ε}={*,∕,ε} 而且:FIRST( E ) = FIRST( T ) = FIRST( F )=FIRST((E))∪FIRST(i)={(,i }由此我们容易得出各非终结符的FOLLOW集合如下:FOLLOW( E )= { ),#}FOLLOW(E’)= FOLLOW(E)={ ),#}FOLLOW( T )= FIRST(E’)\ε∪FOLLOW(E’)={+,−,),#}FOLLOW( T’ ) = FOLLOW( T ) ={+,−,),#}FOLLOW( F )=FIRST(T’)\ε∪FOLLOW(T’)={*,∕,+,−,),#}由以上FOLLOW集可以我们可以得出SELECT集如下:对E SELECT(E→TE’)=FIRST(TE’)=FIRST(T)={ (,i }对E’ SELECT(E’ →+TE’)={ + }SELECT(E’ →−TE’)={ − }SELECT(E’ →ε)={ε,),#}对T SELECT(T→FT’)={(,i}对T’ SELECT(T’ →*FT’)={ * }SELECT(T’ →∕FT’)={ ∕ }SELECT(T’ →ε)={ε,+,−,),#}对F SELECT(F→(E) )={ ( }SELECT(F→i)={ i }∴SELECT(E’ →+TE’)∩SELECT(E’ →−TE’)∩SELECT(E’ →ε)=ΦSELECT(T’ →*FT’)∩SELECT(T’ →∕FT’)∩SELECT(T’ →ε)=ΦSELECT(F→(E) )∩SELECT(F→i)= Φ由上可知,有相同左部产生式的SELECT集合的交集为空,所以文法是LL(1)文法。

编译原理实验报告

编译原理实验报告

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

二、实验内容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.七、运行效果八、实验总结通过这次编译器词法分析程序的编写,我更好地了解了词法分析的作用及工作原理,讲课本中的知识融入到程序编写过程中,理论结合了实际。

编译原理语法分析实验报告

编译原理语法分析实验报告

编译原理语法分析实验报告编译原理实验报告二、语法分析(一) 实验题目编写程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。

(二) 实验内容和要求1. 要求程序至少能分析的语言的内容有:1) 变量说明语句2) 赋值语句3) 条件转移语句4) 表达式(算术表达式和逻辑表达式)5) 循环语句6) 过程调用语句2. 此外要处理:包括依据文法对句子进行分析;出错处理;输出结果的构造。

3. 输入输出的格式:输入:单词文件(词法分析的结果)输出:语法成分列表或语法树(都用文件表示),错误文件(对于不合文法的句子)。

4. 实现方法:可以采用递归下降分析法,LL(1)分析法,算符优先法或LR分析法的任何一种,也可以针对不同的句子采用不同的分析方法。

(三) 实验分析与设计过程1. 待分析的C语言子集的语法:该语法为一个缩减了的C语言文法,估计是整个C语言所有文法的60%(各种关键字的定义都和词法分析中的一样),具体的文法如下:语法:100: program -> declaration_list101: declaration_list -> declaration_list declaration | declaration 102: declaration -> var_declaration|fun_declaration103: var_declaration -> type_specifier ID;|type_specifier ID[NUM]; 104: type_specifier -> int|void|float|char|long|double|105: fun_declaration -> type_specifier ID (params)|compound_stmt 106: params -> params_list|void107: param_list ->param_list,param|param108: param -> type-spectifier ID|type_specifier ID[]109: compound_stmt -> {local_declarations statement_list}110: local_declarations -> local_declarations var_declaration|empty 111: statement_list -> statement_list statement|empty11编译原理实验报告112: statement -> epresion_stmt|compound_stmt|selection_stmt|iteration_stmt|return_stmt113: expression_stmt -> expression;|;114: selection_stmt -> if{expression)statement|if(expression)statement else statement115: iteration_stmt -> while{expression)statement116: return_stmt -> return;|return expression;117: expression -> var = expression|simple-expression118: var -> ID |ID[expression]119: simple_expression ->additive_expression relop additive_expression|additive_expression 120: relop -> <=|<|>|>=|= =|!=121: additive_expression -> additive_expression addop term | term 122: addop -> + | -123: term -> term mulop factor | factor124: mulop -> *|/125: factor -> (expression)|var|call|NUM126: call -> ID(args)127: args -> arg_list|empty128: arg_list -> arg_list,expression|expression该文法满足了实验的要求,而且多了很多的内容,相当于一个小型的文法说明:把文法标号从100到128是为了程序中便于找到原来的文法。

编译原理教程实验报告

编译原理教程实验报告

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

二、实验内容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转换为中间代码。

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

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

编译原理实验报告

编译原理实验报告
实验四: 设计一个表示01符号串集合的自动机,其中符号串至少包含1个0且长度必须大于等于2。并通过该自动机判断任意输入的符号串是否合法符号串。
实验五: 设计一个算法,求出任一上下文无关文法中所有导空符号,并输出。
实验六: 检查某段C源程序中,标识符的使用是否正确,即是否先声明后使用,或重复声明。假设数据类型只有int,float,double,char。
break;
}
if(temp[n*13+n2]=='k'&&zt[m]==0) //那些不能推出 空,但是因为要加入 其他非终结符的first集 而可能含有 空
n2++;
else if(n3>=n1) //for循环结束是因为n3而不是break ,即无相同字符
while(temp[n*13+n2]!='\0') //把z[n]对应的first加入temp[m*13+n1]这个first中,每个字符依次加在最后
{
for(n3=0;n3<n1;n3++) //循环判定是否有相同的字符
{
if(temp[m*13+n3]==temp[n*13+n2])
}
n++;
}
break; //break位于if(gs[n]==z2[m]),对于gs[n]已找到z2[m]完成任务跳出for循环
}
}
n2=m; //存放该for循环中m的值
n++;
}
//进一步处理集除去非终结符
m=0;n=0;n1=0;n2=0;
else n2++;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理实验报告 实验项目 1:词法分析程序实验
一、实验的目的与任务:
编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。设置该课程的目的在于系统地向 学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现方法,使学生通过学习既掌 握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。编译原 理是一门理论性和实践性都比较强的课程。进行上机实验的目的是使学生通过完成上机实验题目加深对课 堂教学内容的理解。同时培养学生实际动手能力。 编译实验由三个独立实验组成,按照由浅入深进行排列,希望通过本实验使学生更深学习并理解编译 的主要过程和相关方法。 词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等 分隔符号。基本符号是与输入的语言定义的词法所规定的终结符。 本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本 保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。 (遇 到错误时可显示“Error” ,然后跳过错误部分继续进行)
分隔符 ; : , { } [ ] ( ) 41 42 43 44 45 46 47 48 49
4.程序源代码(C 语言)
#include <stdio.h> #define MAX 500 main() { FILE *in,*out; char word[MAX]; char cp; int i; if((in=fopen("in.txt","r"))==NULL) { printf("不能打开文档 in.txt,请检查根目录下是否存在该文档\n"); exit(0); } else { printf("成功打开文档 in.txt\n"); } if((out=fopen("out.txt","w"))==NULL) { printf("不能打开文档 out.txt,请检查根目录下是否存在该文档\n"); exit(0); /*存储标识符*/ /*标识符的最大长度*/
extern register static
9 10 11
continue break default
20 229
运算符 ‘+' ‘-’ ‘*’ ‘/' ‘<' ‘<=’ ‘>’ ‘>=’ ‘=’ ‘!=' 其他运算符 31 32 33 34 35 36 37 38 39 40 27
二、题目分析
1.这里采用 C 语言编写的源程序作为词法分析程序的输入数据,输入数据保存在“in.txt”记事本中,将分 析结果存在“out.txt”记事本中。词法分析器的源代码使用 C 语言编写。 2. 下面就词法分析程序中的主要变量进行说明: 主函数 main(): 打开要分析的 C 语言源程序,若不能正确打开,则报错。 先从源程序中读入一个字符 ch,然后进行如下处理: 1、cp 消耗掉空格,制表符,换行符后,cp 数组复位,开始检测 cp; 2、数字检测,对照符号表输出,若匹配成功,则返回序号; 3、字符串检测, 对照符号表输出,若匹配成功,则返回序号; 4、基本保留字检测,对照符号表输出,若匹配成功,则返回序号; 5、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是 否跟着是注释语句。是则跳过,不是则输出运算符。 6、分隔符(界符)检测,对照符号表输出,若匹配成功,则返回序号; 7、排错处理; 结束。 3.以下给定一个 C 语言的符号表的设计和结构: C 语言基本保留 字表 main void int float double char struct const 1 2 3 4 5 6 7 8 if else switch case for do while goto 12 13 14 15 16 17 18 19 sizeof return 23 24
word[i]='\0'; fprintf(out,"%s%c%s%c%s\n","error: ",'"',word,'"',"不是合法的标识符"); } continue; } /*字符串检测*/ if((cp>='a'&&cp<='z')||(cp>='A'&&cp<='Z')||cp=='_') { while((cp>='a'&&cp<='z')||(cp>='0'&&cp<='9')||(cp>='A'&&cp<='Z')||cp=='_') { word[i++]=cp; cp=fgetc(in); }
/*存储当前读入字符*/
} else { printf("成功打开文档 out.txt\n"); } cp=fgetc(in); while(cp!=EOF) { /*消耗掉空格,制表符,换行符*/ while(cp==' '||cp=='\t'||cp=='\n') { cp=fgetc(in); } /*cp 数组复位*/ i=0; /*数字检测*/ if(cp>='0'&&cp<='9') { word[i++]=cp; cp=fgetc(in); while(cp>='0'&&cp<='9') { word[i++]=cp; cp=fgetc(in); } if(cp==' '||cp=='\t'||cp=='\n'||cp=='='||cp=='+'||cp=='-'||cp=='*'||cp=='/'||cp=='>'||cp=='<'||cp=='!'||cp==';'||cp==':'||cp==','||cp=='{ '||cp=='}'||cp=='['||cp==']'||cp=='('||cp==')') { word[i]='\0'; fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',28,')'); } else { while(cp!=' '&&cp!='\t'&&cp!='\n'&&cp!='='&&cp!='+'&&cp!='-'&&cp!='*'&&cp!='/'&&cp!='>'&&cp!='<'&&cp!='!'&&cp! =';'&&cp!=':'&&cp!=','&&cp!='{'&&cp!='}'&&cp!='['&&cp!=']'&&cp!='('&&cp!=')') { word[i++]=cp; cp=fgetc(in); }
相关文档
最新文档