编译原理实验报告1

合集下载

编译原理实验报告(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++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理语法分析实验报告第一篇:编译原理语法分析实验报告实验2:语法分析1.实验题目和要求题目:语法分析程序的设计与实现。

实验内容:编写语法分析程序,实现对算术表达式的语法分析。

要求所分析算术表达式由如下的文法产生。

E→E+T|E-T|TT→T*F|T/F|F F→id|(E)|num实验要求:在对输入表达式进行分析的过程中,输出所采用的产生式。

方法1:编写递归调用程序实现自顶向下的分析。

方法2:编写LL(1)语法分析程序,要求如下。

(1)编程实现算法4.2,为给定文法自动构造预测分析表。

(2)编程实现算法4.1,构造LL(1)预测分析程序。

方法3:编写语法分析程序实现自底向上的分析,要求如下。

(1)构造识别所有活前缀的DFA。

(2)构造LR分析表。

(3)编程实现算法4.3,构造LR分析程序。

方法4:利用YACC自动生成语法分析程序,调用LEX自动生成的词法分析程序。

实现(采用方法1)1.1.步骤:1)对文法消除左递归E→TE'E'→+TE'|-TE'|εT→FT'T'→*FT'|/FT'|εF→id|(E)|num2)画出状态转换图化简得:3)源程序在程序中I表示id N表示num1.2.例子:a)例子1 输入:I+(N*N)输出:b)例子2 输入:I-NN 输出:第二篇:编译原理实验报告编译原理实验报告报告完成日期 2018.5.30一.组内分工与贡献介绍二.系统功能概述;我们使用了自动生成系统来完成我们的实验内容。

我们设计的系统在完成了实验基本要求的前提下,进行了一部分的扩展。

增加了声明变量类型、类型赋值判定和声明的变量被引用时作用域的判断。

从而使得我们的实验结果呈现的更加清晰和易懂。

三.分系统报告;一、词法分析子系统词法的正规式:标识符(|)* 十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)* 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和分隔符 +| * | / | > | < | = |(|)| <=|>=|==;对于标识符和关键字: A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε综上正规文法为: S—〉I1|I2|I3|A4|A5 I1—〉0|A1 A1—〉B1C1|ε C1—〉E1D1|ε D1—〉E1C1|εE1—〉0|1|2|3|4|5|6|7|8|9 B1—〉1|2|3|4|5|6|7|8|9 I2—〉0A2 A2—〉0|B2 B2—〉C2D2 D2—〉F2E2|ε E2—〉F2D2|εC2—〉1|2|3|4|5|6|7 F2—〉0|1|2|3|4|5|6|7 I3—〉0xA3 A3—〉B3C3 B3—〉0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f C3—〉(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)|C3|εA4—〉+ |-| * | / | > | < | = |(|)| <=|>=|==; A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε状态图流程图:词法分析程序的主要数据结构与算法考虑到报告的整洁性和整体观感,此处我们仅展示主要的程序代码和算法,具体的全部代码将在整体的压缩包中一并呈现另外我们考虑到后续实验中,如果在bison语法树生成的时候推不出目标的产生式时,我们设计了报错提示,在这个词的位置出现错误提示,将记录切割出来的词在code.txt中保存,并记录他们的位置。

编译原理课程试验报告

编译原理课程试验报告
int id;//指向符号表的元素的下标
}
2.符号表:
数组string[MAX],用于存储符号。
3.符号映射:
map<string, int> SM;
用于判断符号是否在符号表中存在,若存在返回此符号在符号表中的位置下标。
(4)错误处理
1.显示错误行数,状态0发生错误,非法的开始字符
2.显示错误行数,装态5发生错误,浮点数分析时发生错误
编译原理课程实验报告
实验1:词法分析
姓名
院系
软件学院
学号
任课教师
指导教师
实验地点
实验时间
2008-12-1
实验课表现
出勤、表现得分
实验报告
得分
实验总分
操作结果得分
一、实验目的
实验目的:
1.巩固对词法分析的基本功能和原理的认识。通过看书和实践来达到目的。
2.能够应用自动机的知识进行词法分析。通过画出状态转换图达到目的。
3.理解并处理词法分析中的异常和错误。通过编写代码处理达到目的。
二、实验内容
要求:对如下工作进行展开描述
(1)给出语言的词法规则描述
记号
属性
关键字
本身
_
标识符
IDN
指向符号表中与*相关的表项的指针
整常数
INUM
数值
浮点常数
FNUM
数值
字符常数
CH
字符
字符串常数
STR
字符串
单界符
SC
字符(+,-,*,/,=,{,},;)
指导教师评语:
日期:
IDN变量: f
SC单界符: =
FNUM浮点数: -2.01

编译原理实验一

编译原理实验一

编译原理实验一
编译原理实验一是一个非常重要的实验环节,它涉及到一些基本的编译原理知识和实践技能。

在这个实验中,我们将学习如何设计并实现一个简单的词法分析器。

在编译原理实验一中,我们将首先学习词法分析的基本概念和原理。

词法分析是编译器的第一阶段,它的主要任务是将输入的源代码分解成一个个的词法单元,如标识符、关键字、数字、运算符等。

为了完成这个任务,我们需要设计一个适用于特定编程语言的词法分析器。

接下来,我们将学习如何使用正则表达式来描述词法单元的模式。

通过定义正确的正则表达式,我们可以准确地识别出源代码中的各种词法单元。

为了实现这一功能,我们将使用一个常用的正则表达式引擎,如lex工具。

在实验过程中,我们将根据给定的编程语言规范,编写相应的正则表达式规则,并通过lex工具生成对应的词法分析器程序。

然后,我们将使用这个词法分析器程序来对一些示例源代码进行分析,确保它能正确地识别出各种词法单元。

最后,我们将对实验结果进行总结和分析。

通过实验一,我们将更深入地了解词法分析的原理和实现方法,为以后更复杂的编译原理实验和项目打下坚实的基础。

希望大家能够认真对待这个实验,积极探索和学习,并尽可能多地掌握相关知识和技能。

编译原理实验报告——词法分析器(内含源代码)

编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。

该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。

二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。

同时增强编写和调试程序的能力。

三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。

四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。

int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。

void GetChar(char *ch); //将下一个输入字符读到ch中。

void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。

void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。

int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。

void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。

计算机编译原理实验报告

计算机编译原理实验报告

编译原理实验报告实验一词法分析设计一、实验功能:1、对输入的txt文件内的内容进行词法分析:2、由文件流输入test.txt中的内容,对文件中的各类字符进行词法分析3、打印出分析后的结果;二、程序结构描述:(源代码见附录)1、分别利用k[],s1[],s2[],s3[]构造关键字表,分界符表,算术运算符表和关系运算符表。

2、bool isletter(){} 用来判断其是否为字母,是则返回true,否则返回false;bool isdigit(){} 用来判断其是否为数字,是则返回true,否则返回false;bool iscalcu(){} 用来判断是否为算术运算符,是则返回true,否则返回false;bool reserve(string a[]){} 用来判断某字符是否在上述四个表中,是则返回true,否则返回false;void concat(){} 用来连接字符串;void getn(){} 用来读取字符;void getb(){} 用来对空格进行处理;void retract(){}某些必要的退格处理;int analysis(){} 对一个单词的单词种别进行具体判断;在主函数中用switch决定输出。

三、实验结果四、实验总结词法分析器一眼看上去很复杂,但深入的去做就会发现并没有一开始想象的那么困难。

对于一个字符的种别和类型可以用bool函数来判断,对于关键字和标示符的识别(尤其是3b)则费了一番功夫,最后对于常数的小数点问题处理更是麻烦。

另外,这个实验要设定好时候退格,否则将会导致字符漏读甚至造成字符重复读取。

我认为,这个实验在程序实现上大体不算困难,但在细节的处理上则需要好好地下功夫去想,否则最后的程序很可能会出现看上去没有问题,但实际上漏洞百出的状况。

将学过的知识应用到实际中并不简单,只有自己不断尝试将知识转化成程序才能避免眼高手低,对于知识的理解也必将更加深刻。

实验二LL(1)分析法一、实验原理:1、写出LL(1)分析法的思想:当一个文法满足LL(1)条件时,我们就可以为它构造一个不带回溯的自上而下的分析程序,这个分析程序是有一组递归过程组成的,每个过程对应文法的一个非终结符。

编译原理实验报告1

编译原理实验报告1

03091337 李璐 03091339 宗婷婷一、上机题目:实现一个简单语言(CPL)的编译器(解释器)二、功能要求:接收以CPL编写的程序,对其进行词法分析、语法分析、语法制导翻译等,然后能够正确的执行程序。

三、试验目的1.加深编译原理基础知识的理解:词法分析、语法分析、语法制导翻译等2.加深相关基础知识的理解:数据结构、操作系统等3.提高编程能力4.锻炼独立思考和解决问题的能力四、题目说明1.数据类型:整型变量(常量),布尔变量(常量)取值范围{…, -2, -1, 0, 1, 2, …}, {true, false}2、运算表达式:简单的代数运算,布尔运算3、程序语句:赋值表达式,顺序语句,if-else语句,while语句五、环境配置1.安装Parser Generator、Visual C++;2.分别配置Parser Generator、Visual C++;3.使用Parser Generator创建一个工程编写l文件mylexer.l;编译mylexer.l,生成mylexer.h与mylexer.c;4.使用VC++创建Win32 Console Application工程并配置该项目;加入mylexer.h与mylexer.c,编译工程;执行标识符数字识别器;注意:每次修改l文件后,需要重新编译l文件,再重新编译VC工程六、设计思路及过程设计流程:词法分析LEX的此法分析部分主要利用有限状态机进行单词的识别,在分析该部分之前,首先应该对YACC的预定义文法进行解释。

在YACC中用%union扩充了yystype的内容,使其可以处理char型,int型,node型,其中Node即为定义的树形结点,其定义如下:typedef enum { TYPE_CONTENT, TYPE_INDEX, TYPE_OP } NodeEnum;/* 操作符 */typedef struct {int name; /* 操作符名称 */int num; /* 操作元个数 */struct NodeTag * node[1]; /* 操作元地址可扩展 */} OpNode;typedef struct NodeTag {NodeEnum type; /* 树结点类型 *//* Union 必须是最后一个成员 */union {int content; /* 内容 */int index; /* 索引 */OpNode op; /* 操作符对象 */};} Node;extern int Var[26];结点可以是三种类型(CONTENT,INDEX,OP)。

编译原理实验报告

编译原理实验报告

编译方法实验报告实验1:扫描器的设计一、实验目的熟悉并实现一个扫描器(词法分析程序)。

二、实验要求(1) 设计扫描器的有限自动机(识别器);(2) 设计翻译、生成Token的算法(翻译器);(3) 编写代码并上机调试运行通过。

·输入——源程序文件或源程序字符串;·输出——相应的Token序列;关键字表和界符表;符号表和常数表;三、实验步骤流程:初始化;打开用户源程序文件;while (文件未结束){ 读入一行到w[i],i=0;do //处理一行,每次处理一个单词{ 滤空格,直到第一个非空的w[i];i--;s=1; //处理一个单词开始while (s!=0)//拼单词并生成相应Token{act(s); //执行q sif (s>=11 && s<=14)//一个单词处理结束break;i++; //getchar()s=find(s, w[i]);}if (s==0)词法错误;}while (w[i]!=换行符);}关闭用户源程序文件;生成Token文件;输出关键字表;输出Token序列;输出符号表;输出常数表;有限自动机的状态转换图: ed d d+|- -1/+/-+① d ② . ③ d ④ e ⑤ ⑥ d ⑦ d --1/+/-l/d -1/+/--1l ⑧ --1b ⑨ b ⑩ --1--1-其中:d 为数字,l 为字母,b 为界符,-1代表其它符号(如在状态8处遇到了非字母或数字的其它符号,会变换到状态12)。

关键字表和界符表:Program; Begin: End( Var) While, Do:= Repeat+ Until- For* To/ If> Then>= Else==< <=四、 主要数据结构①状态转换矩阵:int aut[10][7]={ 2, 0, 0, 0, 8, 9, 15,2, 3, 5,11, 0, 0, 11,4, 0, 0, 0, 0, 0, 0,4, 0, 5,11, 0, 0, 11,7, 0, 0, 6, 0, 0, 0,7, 0, 0, 0, 0, 0, 0,7, 0, 0,11, 0, 0, 11,8, 0, 0, 0, 8, 0, 12,0, 0, 0, 0, 0, 10, 14,0, 0, 0, 0, 0, 0, 13};12 11 13 14 15②关键字表:char keywords[30][12]={“program”,”begin”,”end”,”var”,”while”,”do”,”repeat”,”until”,”for”,”to”,”if”,”then”,”else”,“;”, ”:”, ”(“, ”)”, ”,”, ”:=”, ”+”, ”-“, ”*”, ”/”,”>”, ”>=”, ”==”, “<”, “<=”};③符号表:char ID[50][12]; //表中存有源程序中的标识符④常数表:float C[20];⑤其它变量:struct token{ int code;int value}; //Token结构struct token tok[100]; //Token数组int s; //当前状态int n,p,m,e,t; //尾数值,指数值,小数位数,指数符号,类型float num; //常数值char w[50]; //源程序缓冲区int i; //源程序指针,当前字符为w[i]char strTOKEN[12]; //当前已经识别出的单词五、实验核心代码int main(int argc, char* argv[]){FILE *fp;int s; //当前状态 *有限自动机中的状态fp=fopen("exa.txt","r");while (!feof(fp)){fgets(w,50,fp);i=0;//*处理一行do{printf("%c ",w[i]); //测试显示每个token的首字母//*处理一个tokenwhile (w[i]==' ') //滤空格i++;if (w[i]>='a' && w[i]<='z') //判定单词类别*是字母(关键字或标识符){ptr=col2; num_map=2;}else if (w[i]>='0' && w[i]<='9') //*是数字(常量的开头){ptr=col1; num_map=4;}else if (strchr(col3[0].str,w[i])==NULL) //*其他字符算为非法字符{printf("非法字符%c\n",w[i]);i++;continue;}else //界符{ptr=col3; num_map=1;}i--; //*向后退一个字符s=1; //开始处理一个单词while (s!=0){act(s);if (s>=11 && s<=14) //*判断是否是终止状态 *是终止状态,则形成一个tokenbreak;i++; //getchar() *读取下一个字符s=find(s,w[i]); //状态转换}if (s==0){strTOKEN[i_str]='\0';printf("词法错误:%s\n",strTOKEN);}}while (w[i]!=10);}printf("关键字表:"); //输出结果for (i=0;i<30;i++)printf("%s ",keywords[i]);printf("\n");printf("Token序列:");for (i=0;i<num_token;i++)printf("(%d,%d)",tok[i].code,tok[i].value);printf("\n");printf("符号表:");for (i=0;i<num_ID;i++)printf("%s ",ID[i]);printf("\n");printf("常数表:");for (i=0;i<num_C;i++)printf("%d ",C[i]);printf("\n");fclose(fp);printf("Hello World!\n");return 0;}//*状态转换后,达到新的状态之后,记录的变化void act(int s){int code;switch (s){case 1:n=0;m=0;p=0;t=0;e=1;num=0;i_str=0;strTOKEN[i_str]='\0'; //其它变量初始化break;case 2:n=10*n+w[i]-48;break;case 3:t=1;break;case 4:n=10*n+w[i]-48; m++;break;case 5:t=1;break;case 6:if (w[i]=='-') e=-1;break;case 7:p=10*p+w[i]-48;break;case 8:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 9:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 10:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 11:num=n*pow(10,e*p-m); //计算常数值tok[i_token].code=2; tok[i_token++].value=InsertConst(num); //生成常数Tokennum_token++;break;case 12:strTOKEN[i_str]='\0';code=Reserve(strTOKEN); //查关键字表if (code){ tok[i_token].code=code; tok[i_token++].value=0; } //生成关键字Token else{ tok[i_token].code=1;tok[i_token++].value=InsertID(strTOKEN); } //生成标识符Token num_token++;break;case 13:strTOKEN[i_str]='\0';code=Reserve(strTOKEN); //查界符表if (code){ tok[i_token].code=code; tok[i_token++].value=0; } //生成界符Token else{strTOKEN[strlen(strTOKEN)-1]='\0'; //单界符i--;code=Reserve(strTOKEN); //查界符表tok[i_token].code=code; tok[i_token++].value=0; //生成界符Token }num_token++;break;case 14:strTOKEN[i_str]='\0';code=Reserve(strTOKEN); //查界符表tok[i_token].code=code; tok[i_token++].value=0; //生成界符Token num_token++;break;}}//*状态转换int find(int s,char ch){int i,col=7;struct map *p;p=ptr;for (i=0;i<num_map;i++)if (strchr((p+i)->str,ch)){col=(p+i)->col;break;}return aut[s][col];}//*向常量表中插入常量int InsertConst(double num){int i;for (i=0;i<num_C;i++)if (num==C[i])return i;C[i]= (int)num;num_C++;return i;}int Reserve(char *str){int i;for (i=0;i<num_key;i++)if (!strcmp(keywords[i],str))return (i+3);return 0;}//*向符号表中插入新的符号int InsertID(char *str){int i;for (i=0;i<num_ID;i++)if (!strcmp(ID[i],str)) //*符号已经存在,则返回地址return i;strcpy(ID[i],str);num_ID++;return i;}六、实验结果实验思考题:1.扫描器的任务是什么?答:词法分析程序又称扫描器,任务有:(1) 识别单词——从用户的源程序中把单词分离出来;(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.七、运行效果八、实验总结通过这次编译器词法分析程序的编写,我更好地了解了词法分析的作用及工作原理,讲课本中的知识融入到程序编写过程中,理论结合了实际。

编译原理实验报告

编译原理实验报告

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

编译原理实验报告

编译原理实验报告

中南林业科技大学实验报告课程名称:编译原理专业班级:2011级计算机科学与技术1班姓名:朱斌俊学号:2014 年6 月30 日实验一词法分析器的设计一、实验目的设计词法分析器二、设计方法:1.写出该语言的词法规则。

2.把词法规则转换为相应的状态转换图。

3.把各转换图的初态连在一起,构成识别该语言的自动机4.设计扫描器5.把扫描器作为语法分析的一个过程,当语法分析需要一个单词时,就调用扫描器。

6.扫描器从初态出发,当识别一个单词后便进入终态,送出二元式。

三、实验结果输入:输出:四、实验代码#include<iostream> #include<fstream> #include<map>#include<string>#include<vector> using namespace std; #define IPTF cin#define OPTF cout //input flowstruct WordType{string str;int type;WordType(string s,int t){str=s,type=t;}};bool operator <(string s1,string s2){return pare(s2)<0;} //小于重载class TL{public:map<string,int>mp;vector<WordType>res; //翻译结果string strCache;int cacheLen;//已经读取的数据TL();bool init();bool printFile();bool translate();char getChar(); //获取字符char peek(); //探测string getWord();// bool translateWordByMap(string str); //使用map翻译private:bool isLetter(char ch){return (ch>='a'&&ch<='z') || (ch>='A'&&ch<='Z');} bool isNum(char ch){return (ch>='0'&&ch<='9');}};TL::TL(){}bool TL::init(){mp.clear();ifstream mpf("mapFile.txt",ios::in);if(!mpf){cerr<<"open error!"<<endl;return 0;}int type;string str;while(mpf>>type){while(mpf>>str && pare("#end")!=0){mp[str]=type;}}//end mpf typefstream ipf; //输入文件流ipf.open("inputFile.txt",ios::in);cacheLen=0;if(!ipf){cout<<"cannot find the inputFile.txt,you can input the file by console!"<<endl;//输入处理函数输出到inputFile.txt}freopen("inputFile.txt","r",stdin); /////////////////////return 1;}bool TL::printFile(){ofstream otf("outputFile.txt",ios::out);if(!otf){cerr<<"outputFile open error!"<<endl;return 0;}vector<WordType>::iterator it;for(it=res.begin();it!=res.end();it++){otf<<"(" <<it->type <<"," <<it->str<<")" <<endl;cout<<"(" <<it->type <<",\"" <<it->str<<"\")" <<endl;}cout<<"print file suceessful"<<endl;return 1;}char TL::getChar() //从缓冲区中取出一个char{if(pare("")==0 || strCache.length()==cacheLen){if(! (IPTF>>strCache)) //读取失败return 0;strCache+=' '; //加入一个空格分隔符cacheLen=0;}return (char)strCache[cacheLen++];}char TL::peek(){if(pare("")==0 || strCache.length()==cacheLen){if(! (IPTF>>strCache)) //读取失败return 0;strCache+=' '; //加入一个空格分隔符cacheLen=0;}return (char)strCache[cacheLen];}string TL::getWord(){string strw;char ch; //输入字符int type; //该单词的种类bool pointFlag=0;//小数点标记位while(1){ch=getChar();if(ch==' ' && strw.size()!=0)return strw;else if(ch==' ')ch=TL::getChar();if(ch==0)return strw;if(strw.size()==0){if(TL::isLetter(ch) || ch=='_')type=1; //关键字else if(TL::isNum(ch))type=2; //实数else if(ch=='+'|| ch=='-') //实数{if(res.size()>0 && (res[res.size()-1].type==2 || res[res.size()-1].type==3) )type=3; //前面的项为实数,则为运算符elsetype=2; //前面的项不是数字则为实数}elsetype=0;}//////////////////////////////////////开始对每个种类进行处理if(type==1) //是字母开头类{if(TL::isLetter(ch) || TL::isNum(ch) || ch=='_') //关键字的三种构成strw+=ch;else {cacheLen--;return strw;}}else if(type==2) //是数字开头类{if(strw.size()==0 && (ch=='+' || ch=='-'))strw+=ch;else if(ch=='.' && pointFlag==0){strw+=ch;pointFlag==1;}else if(TL::isNum(ch))strw+=ch;else //不是小数点也不是其他的数字{cacheLen--;return strw;}}else //ch为其他符号(包括运算符){strw+=ch;ch=getChar();if(mp[strw+ch]!=0)return strw+ch;else{cacheLen--;return strw;}}// end else}// whilereturn strw;}bool TL::translate(){string str;while(1){str=TL::getWord();if(pare("")==0)break;if(mp[str]!=0)res.push_back(WordType(str,mp[str]) );//包括类别1,,4,5 else if(TL::isLetter(str[0]) || str[0]=='_')res.push_back(WordType(str,2)); //变量2else if(TL::isNum(str[0])|| str[0]=='+' || str[0]=='-')res.push_back(WordType(str,3) ); //常数3elsecout<<"translate error where the word is '"<<str<<"'"<<endl;}return 0;}void compileWork1(TL tl){//读入缓冲区去掉注释//freopen("compileFile.txt","r",stdin);tl.translate(); //开始翻译tl.printFile(); //输出结果}int main(){TL tl;if(! (tl.init())){cout<<"初始化失败"<<endl;return 0;}compileWork1(tl);return 0;}实验二LL(1)分析法一、实验目的根据某一文法编制调试LL(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.设计翻译、生成Token的算法;3.编写代码并上机调试运行通过。

要求:输入——源程序文件;输出——(1)相应的Token序列;(2)关键字、界符表,符号表,常数表。

四、扫描器设计:自动机:关键字表和界符表单词编码program 3procedure 4④-begin 5end 6while 7do 8+ 9* 10⑧-:11:= 12⑨-= 13,14;15五、概要设计:(1)各模块概要设计1.判断当前读入的字符是字母还是数字int IsLetter(char ch) //判断ch是否为字母 { if (ch是A~Z或a~z) return 1;else return 0;}int IsDigit(char ch) //判断ch是否为数字{ if (ch是0~9) return 1;else return 0;}2.将读入的字符连接成单词或数while (IsLetter(ch)||IsDigit(ch)){ Concat(); //将ch中的字符拼接到strToken中ch=GetChar();}3.查表判断当前的独立串是关键字、标示符还是常数4.求出当前的独立串的code 和value(2)程序说明:1、关键字表、界符表和常数表中初始化后都有元素,即都不是空表。

而符号表则是空的。

它用来存放用户自己定义的变量名,按输入的被识别串中的顺序依次标识其value的值的1,2,3,……,n。

2、value=-1用来标识它是一个关键字;value=1用来标识它是一个界符常数的code值一定为2六、程序源代码及注释:#include "stdio.h"#include "string.h"#define N 15struct TokenType{ int code,value; };char*keywords[]={"program","procedure","begin","end","while","do","+","*",":",":=","=",",",";","(",")",}; //关键字表、界符表char ID[10][10]; //符号表int m;int Cons[10]; //常数表int n;void print(struct TokenTykpe token) //输出Token{ printf("( %d %d)\n",token.code,token.value);}void ProcError(){ printf("Error! You haven't defined it!");}int IsLetter(char ch) //判断ch是否为字母¸{ if (ch>='A' && ch<='Z' || ch>='a' && ch<='z')return 1; else return 0;}int IsDigit(char ch) //判断ch是否为数字{ if (ch>='0' && ch<='9') return 1;else return 0;}int Reserve(char *strToken) //用strToken中的单词去查关键字表。

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

实验一文法的机内表示与输入输出实验题目:文法的机内表示与输入输出实验目的:输入文法,按照所提供的各种要求输出所需结果。

实验准备:在学习了规则和有关文法的一些基本概念后,用本实验来加深各个概念间的关系。

例如规则、文法、识别符、Chomsky文法、终结符、非终结符等。

设计考虑:实验代码:#include<iostream.h>int t=0;char A[20];struct LeftItem;struct RightNode{char right;RightNode* nextsibling;RightNode* nextrule;RightNode(char abc){right=abc; nextsibling=NULL; nextrule=NULL;}};struct LeftItem{char left;RightNode* therule;};////////////////////////////////////////////////////////////////////////////// void Insert(RightNode*& pNode,char* temp){pNode=new RightNode(*temp);RightNode* qNode=pNode;temp++;while(*temp!='\0'){qNode->nextsibling=newRightNode(*temp);qNode=qNode->nextsibling;temp++;}}void Bianli1(LeftItem Array[],int length,RightNode* pNode){RightNode* qNode=pNode->nextrule;while(pNode!=NULL){for(int i=0;i<length;i++){if(pNode->right==Array[i].left) break;}if(i==length){for(i=0;i<t;i++){if(pNode->right==A[i]) break;}if(i==t){if(i!=0) cout<<", ";cout<<pNode->right;A[t]=pNode->right;t++;}}pNode=pNode->nextsibling;}if(qNode!=NULL)Bianli1(Array,length,qNode);}void Bianli2(RightNode* pNode){RightNode* qNode=pNode->nextrule;while(pNode!=NULL){cout<<pNode->right;pNode=pNode->nextsibling;}if(qNode!=NULL){cout<<"|";Bianli2(qNode);}}void SelectMenu(LeftItem Array[],int length){int sel2;do{cout<<"请选择您要查询的项目."<<endl;cout<<"--查询全体规则请按------> 1"<<endl;cout<<"--查询指定规则请按------> 2"<<endl;cin>>sel2;}while(sel2!=1&&sel2!=2);if(sel2==1){for(int i=0;i<length;i++){cout<<Array[i].left<<"::=";Bianli2(Array[i].therule);cout<<endl;}}else{char temp;int k;cout<<endl;cout<<"请输入要查询规则左部:";cin>>temp;for(int i=0;i<length;i++){if(temp==Array[i].left){k=i;break;}}if(i==length)cout<<"本文法规则中没有对应的规则!"<<endl;else{cout<<Array[k].left<<"::=";Bianli2(Array[k].therule);}}}////////////////////////////////////////////////////////////////////////////// void main(){char temp[20];int size=0;int k,sel,m,n,j;cout<<"请输入文法规则的数目:";cin>>n;LeftItem* Array=new LeftItem[n];for(int i=0;i<n;i++){cout<<"请输入文法规则:";cin>>temp;if(*temp==NULL) break;for(j=0;j<size;j++){if(Array[j].left==*temp){k=j;break;}}if(j==size){Array[size].left=*temp;Insert(Array[size].therule,temp+4);size++;}else{RightNode* t=Array[k].therule;while(t->nextrule!=NULL)t=t->nextrule;Insert(t->nextrule,temp+4);}}cout<<"文法规则存储完毕!"<<endl<<endl<<endl;cout<<"欢迎进入查询系统!"<<endl<<endl;aaa:cout<<endl;do{cout<<"请选择您要查询的项目."<<endl;cout<<"--查询识别符请按--------> 1"<<endl;cout<<"--查询非终结符请按------> 2"<<endl;cout<<"--查询终结符请按--------> 3"<<endl;cout<<"--查询具体规则请按------> 4"<<endl;cout<<"--输出Chomsky文法请按---> 5"<<endl;cout<<"--退出系统请按----------> 6"<<endl;cin>>sel;}while(sel!=1&&sel!=2&&sel!=3&&sel!=4&&sel !=5&&sel!=6);switch(sel){case 1:cout<<endl;cout<<"该文法规则中识别符为:";cout<<Array[0].left<<endl;break;case 2:cout<<endl;cout<<"该文法规则中非终结符为:";for(m=0;m<size;m++){cout<<Array[m].left;if(m!=size-1) cout<<" ,";}cout<<endl;break;case 3:t=0;cout<<endl;cout<<"该文法规则中终结符为:";for(m=0;m<size;m++)Bianli1(Array,size,Array[m].therule);cout<<endl;break;case 4:cout<<endl;SelectMenu(Array,size);cout<<endl;break;case 5:t=0;cout<<"Chomsky文法形式如下:"<<endl;cout<<"G"<<"=";cout<<"(Vn,Vt,P,"<<Array[0].left<<")"<<endl;cout<<"Vn={ ";for(m=0;m<size;m++){cout<<Array[m].left;if(m!=size-1) cout<<" ,";}cout<<" }"<<endl;cout<<"Vt={ ";for(m=0;m<size;m++)Bianli1(Array,size,Array[m].therule);cout<<"}"<<endl;cout<<"其中P:"<<endl;for(m=0;m<size;m++){cout<<Array[m].left<<"::=";Bianli2(Array[m].therule);cout<<endl;}break;case 6:break;}if(sel!=6) goto aaa;}实验截图:。

相关文档
最新文档