编译原理词法分析程序实现实验报告
编译原理实验报告
编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理实验报告
编译原理实验报告班级姓名:学号:自我评定:实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。
例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。
输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。
输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。
例如,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。
对于变量和常数,CLASS字段为相应的类别码;VALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。
对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。
另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。
三、实现方法与环境词法分析是编译程序的第一个处理阶段,可以通过两种途径来构造词法分析程序。
其一是根据对语言中各类单词的某种描述或定义(如BNF),用手工的方式(例如可用C语言)构造词法分析程序。
一般地,可以根据文法或状态转换图构造相应的状态矩阵,该状态矩阵同控制程序便组成了编译器的词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。
构造词法分析程序的另外一种途径是所谓的词法分析程序的自动生成,即首先用正规式对语言中的各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程序所应进行的语义处理工作,然后由一个所谓词法分析程序的构造程序对上述信息进行加工。
编译原理实验报告
编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。
本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。
二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。
此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。
三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。
在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。
首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。
然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。
在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。
对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。
(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。
在本次实验中,我们使用了递归下降的语法分析方法。
首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。
在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。
为了处理语法错误,在分析过程中添加了错误检测和处理机制。
当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。
(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。
在本次实验中,我们使用了三地址码作为中间代码的表示形式。
在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。
对于符合语义规则的语法结构,生成相应的三地址码指令。
四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。
编译原理词法分析实验报告
编译原理词法分析实验报告实验一词法分析一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
二、实验内容(1)功能描述:该程序是实现一个词法分析器,词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是将单词分为五种的方法。
识别关键字:main、if、int、for、while、do、return、break、continue;单词种别码为1。
标识符:单词种别码为2。
常数:为无符号整形数;单词种别码为3。
运算符:包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符:包括:,、;、{、}、(、);单词种别码为5。
(2)程序结构描述:输入:从控制台输入一段源程序代码,对输入的代码进行词法分析,处理:分离出关键字、标识符、数值、运算符和界符。
输出:在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。
其中,编码是自定义的,一种类型对应一个编码。
词法分析结果显示在控制台上。
(3)程序设计思路1、定义编码表,用ArrayList集合存放单词,如:关键字、运算符、分界符。
这三种单词是固定的,标示符和数字这两种单词不存放在集合中。
编码表是固定的,只需要初始化一次就够了,所以将集合定义为static类型,使其在类加载时,进行一次初始化。
2、static char allstr[] = new char[100000];该数组用于存储用户从控制台输入的所有字符。
3、//从键盘获取一个一个的字符public char Getchar() {try {ch = (char) System.in.read();} catch (Exception e) {e.printStackTrace();}return ch;}4、用while循环遍历allstr数组中存放的字符,判断分离出关键字、标示符、数字、运算符、标示符。
编译原理的实验报告
一、实验目的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)定义语义规则,包括类型检查、作用域检查等。
实验报告编译实验
一、实验目的1. 理解编译原理的基本概念和过程。
2. 掌握编译器的基本组成和编译流程。
3. 学会使用编译器对源代码进行编译,并分析编译结果。
二、实验环境1. 操作系统:Windows 102. 编译器:GCC (GNU Compiler Collection)3. 开发工具:Visual Studio Code三、实验内容1. 编译器的基本组成和编译流程2. 编译器的使用3. 编译结果分析四、实验步骤1. 编译器的基本组成和编译流程(1)词法分析:将源代码分解成一个个的单词,如标识符、关键字、运算符等。
(2)语法分析:将单词序列转换成语法树,验证源代码是否符合语法规则。
(3)语义分析:检查语法树,确保源代码在语义上是正确的。
(4)中间代码生成:将语法树转换成中间代码,如三地址代码。
(5)代码优化:对中间代码进行优化,提高程序运行效率。
(6)目标代码生成:将优化后的中间代码转换成目标代码,如汇编代码。
(7)代码生成:将目标代码转换成可执行文件。
2. 编译器的使用(1)编写源代码:使用Visual Studio Code编写C语言源代码。
(2)编译源代码:在命令行中输入gcc -o 程序名源文件名.c,编译源代码。
(3)运行程序:在命令行中输入程序名,运行编译后的程序。
3. 编译结果分析(1)词法分析:编译器将源代码中的单词进行分解,如以下代码:```cint main() {int a = 1;return a;}```编译器将分解为以下单词:- int- main- (- )- {- int- a- =- 1- ;- return- a- ;- }- }(2)语法分析:编译器将单词序列转换成语法树,验证源代码是否符合语法规则。
(3)语义分析:编译器检查语法树,确保源代码在语义上是正确的。
(4)中间代码生成:编译器将语法树转换成中间代码,如以下三地址代码:```t1 = 1a = t1t2 = areturn t2```(5)代码优化:编译器对中间代码进行优化,如以下优化后的三地址代码:```a = 1return a```(6)目标代码生成:编译器将优化后的中间代码转换成汇编代码。
(完整word版)编译原理词法分析程序实现实验报告
(完整word版)编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:GOTO 1:(完整word版)编译原理词法分析程序实现实验报告GOTO 2:三、源程序代码部分#include <stdio.h>#include<stdlib.h>#include <math.h>#define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111int count=0;int Class;void StoreType();int Type[100];char Store[20]={'\0'};void ShowStrFile();//已经将要识别的字符串存在文件a中void Output(int a,char *p1,char *p2);//字符的输出过程int Sign(char *p);//'+''-''*''/'整体识别过程int UnsignedNum(char *p);//是否适合合法的正整数0~9int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.' void DistinguishSign(char *p);//'+''-''*''/'具体识别过程void TypyDistinguish();//字符的识别过程void ShowType();//将类别码存储在Type[100]中,为语法分析做准备void ShowStrFile()//已经将要识别的字符串存在文件a中{FILE *fp_s;char ch;if((fp_s=fopen("a.txt","r"))==NULL){printf("The FILE cannot open!");exit(0);}elsech=fgetc(fp_s);while(ch!=EOF){putchar(ch);ch=fgetc(fp_s);}printf("\n");}void StoreStr()//将文件中的字符串存储到数组Store[i] {FILE *fp=fopen("a.txt","r");char str;int i=0;while(!feof(fp)){fscanf(fp,"%c",&str);if(str=='?'){Store[i]='\0';break;}Store[i]=str;i++;}Store[i]='\0';}void ShowStore(){int i;for (i=0;Store[i]!='\0';i++)printf("%c",Store[i]);printf("\n");}void Output(int a,char *p1,char *p2){printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");while(p1<=p2){printf("%c",*p1);p1++;}printf("\n");}int Sign(char *p){char ch=*p;if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return 1;elsereturn 0;}int UnsignedNum(char *p){char ch=*p;if('0'<=ch&&ch<='9')return 1;elsereturn 0;}int LegalCharacter(char *p){char ch=*p;if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.')。
编译原理词法分析报告
实验一:词法分析一、实验目的:1、通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
2、编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本关键字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验预习提示1、词法分析器的功能和输出格式词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是一类符号一种别码的方式。
2、单词的BNF表示<标识符>-> <字母><字母数字串><字母数字串>-><字母><字母数字串>|<数字><字母数字串>|<下划线><字母数字串>|ε<无符号整数>-> <数字><数字串><数字串>-> <数字><数字串> |ε<加法运算符>-> +<减法运算符>->-<大于关系运算符>->><大于等于关系运算符>-> >=3、“超前搜索”方法词法分析时,常常会用到超前搜索方法。
如当前待分析字符串为“a>+”,当前字符为’>’,此时,分析器到底是将其分析为大于关系运算符还是大于等于关系运算符呢?显然,只有知道下一个字符是什么才能下结论。
于是分析器读入下一个字符’+’,这时可知应将’>’解释为大于运算符。
但此时,超前读了一个字符’+’,所以要回退一个字符,词法分析器才能正常运行。
在分析标识符,无符号整数等时也有类似情况。
编译原理实验报告
编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。
本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。
二、实验环境本次实验使用了Java编程语言及相关工具。
在开始实验前,我们需要安装Java JDK并配置好运行环境。
三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。
我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。
2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。
我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。
3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。
我们主要进行类型检查、语法错误检查等。
如果源代码存在语义错误,编译器应该能够提供相应的错误提示。
4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。
在本次实验中,我们将目标代码生成为Java字节码。
5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。
通过多个测试用例的执行,我们可以验证编译器的正确性和性能。
四、实验心得通过完成这个编译器的实验,我收获了很多。
首先,我对编译原理的知识有了更深入的理解。
在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。
其次,我提高了编程能力。
实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。
通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。
最后,我锻炼了解决问题的能力。
在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。
词法分析器实验报告_5
一、实验目的1.1总体目的1.1.1 掌握词法分析的基本原理;1.1.2.理解词法分析在编译程序过程中的作用;1.1.3.熟悉关键字表等相关的数据结构与单词的分类方法.1.1.4.加深对编译原理的理解,掌握词法分析器的实现方法和技术,同时,将JA V A 的理论知识结合实际,锻炼编程技术,强调良好的程序设计风格。
1.2程序目的利用JAVA语言针对C语言编制一个一遍扫描的编译程序。
从文件中识别出各个单词, 识别出所取的单词的类型, 并且对代码中的词法错误进行提示。
二、实验内容根据编译原理中的词法分析原理, 利用Java语言针对C语言编写一个词法分析程序: 输入: 打开一个C语言程序的源代码文件, 将其读入程序输入框。
处理: 对输入框中的代码进行词法分析,分离出关键字、标识符、数值、运算符和界符。
输出:在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。
其中, 编码是自定义的,一种类型对应一组编码。
词法分析结果显示在词法分析错误信息栏, 提示错误个数、错误所在行号, 并对某些词法错误原因进行说明。
三、实验需求针对C语言程序代码进行词法分析器, 从指定文件中读入预分析的源程序, 从左至右扫描源程序的字符串, 按照词法规则(正则文法规则)识别出一个个正确的单词, 并转换成该单词相应的二元式(种别码、属性值)以便之后进行语法分析使用。
同时, 按照给定的规则, 识别出单词符号作为输出, 发现其中的语法错误, 不同类别的字符通过相应的函数模块来分析识别, 使程序能够正确识别文法所规定的任何组织形式的字符组合, 将所有的分析状态显示在词法分析器中。
最后在错误分析栏中显示该文件中C语言代码的词法错误个数、错误所在行, 并对错误原因进行说明。
四、主要数据结构介绍4.1关键字编码4.2标识符统一编码1004.3数值统一编码2004.4界符编码4.5运算符编码4.6全局变量含义int row: 语法错误出现的所在列数int line: 语法错误出现的所在行数int err: 语法错误的个数int begin: 当前程序扫描在字符串中的开始位置int end: 当前程序扫描在字符串中的结束位置4.7局部变量定义int i: 选择第i 个字符进行检测 int state: 单词类型判断标志 int N: 文件长度char c: 当前遍历的字符 string str: 输入字符串 int flag: 退出标志五、主要模块算法介绍5.1总体流程介绍说明: state 为输入字符状态标志, 根据输入字符不同类型选择不同处理。
编译原理词法分析器实验报告
编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。
词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。
本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。
2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。
具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。
3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。
这些规则描述了编程语言中各种词法单元的模式。
例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。
4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。
在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。
4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。
测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。
4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。
如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。
5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。
该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。
在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。
编译原理教程实验报告
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容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. 熟悉C语言在词法分析中的应用。
4. 提高编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C3. 开发环境:Visual Studio 2019三、实验内容1. 设计词法分析器,实现对源代码的词法分析。
2. 将源代码分解为单词序列。
3. 输出单词序列及对应的词法类型。
四、实验步骤1. 分析源代码中的词法单位,确定词法类型。
2. 设计词法分析器的状态转换表。
3. 编写词法分析器代码。
4. 测试词法分析器,验证其正确性。
五、实验过程1. 分析源代码中的词法单位在C语言中,词法单位包括标识符、关键字、运算符、分隔符、常量等。
本实验以C语言为例,分析源代码中的词法单位,确定词法类型。
2. 设计词法分析器的状态转换表根据词法单位,设计词法分析器的状态转换表。
状态转换表包括当前状态、输入字符、下一状态、输出词法类型和对应动作。
3. 编写词法分析器代码根据状态转换表,编写词法分析器代码。
以下为词法分析器的主要功能模块:(1)初始化:设置初始状态、词法类型和单词长度。
(2)读取字符:从源代码中读取字符,并判断字符类型。
(3)状态转换:根据状态转换表,更新当前状态、输出词法类型和单词长度。
(4)输出结果:将单词序列及对应的词法类型输出到屏幕。
4. 测试词法分析器编写测试用例,验证词法分析器的正确性。
测试用例包括以下几种情况:(1)包含各种词法单位的源代码。
(2)包含注释的源代码。
(3)包含错误标识符的源代码。
六、实验结果与分析1. 实验结果通过测试,词法分析器能够正确识别源代码中的各种词法单位,并将单词序列及对应的词法类型输出到屏幕。
以下为部分测试结果:```int a = 10; // 输出:int, 标识符if (a > 0) // 输出:if, 关键字{// 输出:{, 分隔符// ...// 输出:}, 分隔符}// 输出://, 注释开始注释内容// 输出://, 注释结束```2. 实验分析(1)实验过程中,通过对词法分析原理的学习,加深了对编译原理的理解。
编译原理熟悉实验报告
一、实验目的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. 词法分析器能够正确识别源程序中的词法单元,并将它们转换成词法符号。
编译原理实验报告 词法分析
编译原理实验一·词法分析一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
二、实验内容及要求对某特定语言A ,构造其词法规则。
该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。
功能要求如下所示:·按单词符号出现的顺序,返回二元组序列,并输出。
·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。
·如果出现词法错误,报出:错误类型,位置(行,列)。
·处理段注释(/* */),行注释(//)。
·有段注释时仍可以正确指出词法错误位置(行,列)。
三、实验过程1、词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。
A→(ID | NUM | RES | DEL | OPR) *ID→letter(letter | didit)*NUM→digit digit*letter→a | …| z | A | …| Zdigit→0 | …| 9RES→program | begin | end | var | int | and | or | not | if | then | else | while | doDEL→( | ) | . | ; | ,OPR→+ | * | := | > | < | = | >= | <= | <>如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
空格由空白、制表符和换行符组成。
2、单词种别定义;3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、运行环境介绍;本次实验采用win-tc进行代码的编写和编译及运行程序的运行环境为windows5、关键算法的流程图及文字解释;程序中用到的函数列表:变量ch储存当前最新读进的字符的地址strToken存放当前字符串voidmain() //主函数struct binary *lexicalAnalyze(); //词法分析的主函数,返回一个二元组的指针void GetBC(); //检查ch指向的字符是否为空格、制表或回车符,如果是则调用GetChar()直至不是上述字符void GetChar(); //ch前移一个地址单元int ConCat(); //将ch指向的字符连接到strToken之后int isLetter(); //判断ch指向的字符是否字母int isDigit(); //判断ch指向的字符是否数字int insertId(); //向标识符表中插入当前strToken的字符串int insertConst(); //将strToken的常数插入常数表中int Reserved(); //检测当前strToken中的字符串是否保留字,若是,则返回编码,否则返回0int isId(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回其编号,否则返回0int isConst(); //检测当前strToken中的字符串是否在常数表中已存在,若是,则返回其编号,否则返回0void errProc(int errType); //出错处理过程,errType是错误类型,将错误信息加入错误表中main()函数的流程图如下:lexicalAnalyze()函数的流程图如下所示:Reserved()、isId()和isConst()函数均采用了对链表的遍历算法,errProc()函数通过识别不同的错误编号,向错误链表中添加相应的错误信息。
(完整)编译原理实验报告(词法分析器 语法分析器)
编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的: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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,,,*,/, ( , ) 构成的算术表达式,如1.5E+2,100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:输入字符p指向第一个字符符号识别*p=+||-||*||/YYNN*p=0~9*p=E*p=0~9||"."N无效符号Y*p=“.”GOTO 2GOTO 1GOTO 1:NY无符号数GOTO 1*p=0~9*p='/0'YNP++NNP++*p=E*p='+'||'-'YYP++P++continueYY*p=0~9*p=0~9NN无符号数无符号数P++P++continuecontinueGOTO 2:GOTO 2*p=EcontinueY无符号数P++continue三、源程序代码部分#include <stdio.h>#include<stdlib.h>#include <math.h>#define MAX 100#define UNSIGNEDNUMBER 1 #define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6 #define RIGHTBRACKET 7 #define INEFFICACIOUSLABEL 8 #define FINISH 111int count=0;int Class;void StoreType();int Type[100];char Store[20]={'\0'}; void ShowStrFile();//已经将要识别的字符串存在文件a中 void Output(int a,char *p1,char *p2);//字符的输出过程 int Sign(char *p);//'+''-''*''/'整体识别过程int UnsignedNum(char *p);//是否适合合法的正整数0~9 int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.'void DistinguishSign(char *p);//'+''-''*''/'具体识别过程 void TypyDistinguish();//字符的识别过程void ShowType();//将类别码存储在Type[100]中,为语法分析做准备void ShowStrFile()//已经将要识别的字符串存在文件a中 {FILE *fp_s;char ch;if((fp_s=fopen("a.txt","r"))==NULL){printf("The FILE cannot open!");exit(0);}elsech=fgetc(fp_s);while(ch!=EOF){putchar(ch);ch=fgetc(fp_s);}printf("\n");}void StoreStr()//将文件中的字符串存储到数组Store[i] { FILE *fp=fopen("a.txt","r");char str;int i=0;while(!feof(fp)){fscanf(fp,"%c",&str);if(str=='?'){Store[i]='\0';break;}Store[i]=str;i++;}Store[i]='\0';}void ShowStore(){int i;for (i=0;Store[i]!='\0';i++)printf("%c",Store[i]);printf("\n");}void Output(int a,char *p1,char *p2){printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");while(p1<=p2){printf("%c",*p1);p1++;}printf("\n");}int Sign(char *p){char ch=*p;if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return 1;elsereturn 0;}int UnsignedNum(char *p) {char ch=*p;if('0'<=ch&&ch<='9')return 1;elsereturn 0;}int LegalCharacter(char *p) {char ch=*p;if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.') return 1;else return 0;}void DistinguishSign(char *p) { int Class;char ch=*p;switch(ch){case '+':Output(PLUS,p,p);Type[count++]=PLUS;break;case '-':Output(SUBTRACT,p,p);Type[count++]=SUBTRACT;break; case '*':Output(MULTIPLY,p,p);Type[count++]=MULTIPLY;break; case '/':Output(DIVIDE,p,p);Type[count++]=DIVIDE;break; case '(':Output(LEFTBRACKET,p,p);Type[count++]=LEFTBRACKET;break; case ')':Output(RIGHTBRACKET,p,p);Type[count++]=RIGHTBRACKET;break; default:break;}}void TypyDistinguish(){printf("词法开始,分析结果如下:\n");char *p;p=&Store[0];while(*p!='\0'){if(Sign(p)){DistinguishSign(p++);continue;}else if(UnsignedNum(p)||*p=='.'){char *p1=p;if(UnsignedNum(p)){while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~"); break; Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else if(*p=='.'){p++;while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~ /n");break;Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~因为他的后面既不是0~9也不是“+”或者“-…");break;//1.5E*2这样的字符串不是无符号数Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}}if(*p=='.'){p++;if(UnsignedNum(p)){p++;while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~"); break; Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}}else if(*p=='E'){Output(INEFFICACIOUSLABEL,p,p); break;Type[count++]=INEFFICACIOUSLABEL;printf("输入的这个符号是不合法的~");p++;continue;}}printf("\n\n词法分析完毕~");}void ShowType()//将类别码存储在Type[100]中,为语法分析做准备{printf("\n用类别码表示输入的字符如下:\n");int i;printf("\n");for(i=0;Type[i]!=FINISH;i++){printf("%d",Type[i]);}printf("\n\n");}void main(){//词法分析部分StoreStr();ShowStore();TypyDistinguish();Type[count]=FINISH;ShowType();}四、实验结果正确的结果:错误的结果:输入的字符串中有1.5E*2因为实验是以文件的形式进行读取的所以,在读取不合法的过程中只是将存在project 中的a.txt 中的内容改变改为1.5E*2+100*555实验结果如下:结果分析:对于正确的结果,我以二元式的形式输出,包括他的值和他的类别码,其中将类别码存放在另外的一个数组中,为了在实验二中的语法识别打下基础。