编译原理课程设计报告(无符号数的有穷自动机的实现)
- 格式:doc
- 大小:178.00 KB
- 文档页数:7
课程设计报告( 2021--2022年度第一学期)名称:编译技术课程设计题目:算符优先分析法研究院系:班级:学号:学生姓名:指导教师:设计周数:一周成绩:日期:2021年12 月31日1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。
设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术。
1.2 课程设计的要求1. 文法使用产生式来定义;2. 分别给出每一个非终结符的FIRSTVT和LASTVT集。
3. 画出算符优先关系表;4. 判定给定的文法是否是算符优先文法;5. 给定符号串判定是否是文法中的句子,分析过程用分析表格的方式打印出来。
2 系统描述举例如下:本次实验使用Visual Studio 2019软件,利用只规定终结符之间的优先关系的自底向上移进-规约法实现对算符优先分析法的研究,输出非终结符的FIRSTVT和LASTVT集,算符优先关系表和对句子的分析表格,均在DOS窗口显示。
2.1 文法的描述G[S]: S->#E#;E->E+T|T;F-P!F|P;T->T*F|F;P->(E)|i2.2 属性文法的描述表2-1 条件语句及其语义规则3 概要设计3.1 概要设计(体现系统的设计思路和主要功能)主要步骤包括:用户自己输入文法,实质上是算数表达式的计算。
构建每个非终结符的FirstVT()和LastVT()集。
构建优先关系符号表。
构建词法分析的程序。
编写主函数,用户输入文法对语句利用算符优先文法进行判别。
算法的主体思想:用栈存储已经看到的输入符号,用优先关系指导移动归约语法分析器的动作,如果栈顶的终结符和下一个输入符之间的优先关系是<或=,则语法分析器移动,表示还没有发现句柄的右端,如果是>关系,就调用归约。
3.2 开发环境实验采用C++程序语言进行设计开发工具为Visual Studio 20194 详细设计4.1 系统的类图图4-1 文法类图4.2 主要算法的流程图图4-2 求非终结符的FIRSTVT 和LASTVT 集流程图求LASTVT 集的过程与此类似,但符号串的扫描顺序是从后开始若产生式右部第一个字符为非终结符 则直接将其加入first 集中else first[x].insert(str[0]);寻找该非终结符 的first 集 dfs(y);将该非终结符的first 集也加进去for (; it != first[y].end(); it++)first[x].insert(*it);if (isupper(str[0]))若产生式右部第一个字符为非终结符 string& left = VN_set[x].left;string&str = VN_set[x].right[i];产生产生式左部非终结符的FIRSTVT 集图4-3 构造算符优先关系表流程图图4-4 对输入串进行算符优先分析流程图4.3 数据分析与定义char relation[MAX][MAX]; //算符优先关系表vector<char> VT;vector<WF> VN_set; //类型为文法的数组VN_setmap<string, int> VN_dic; //map映射,一条产生式对应的第几条的序号set<char> first[MAX]; //FIRSTVT集set<char> last[MAX]; //LASTVT集4.4 系统界面设计用户输入文法个数和每条产生式的内容后,输出结果格式如下:分为:产生式、FIRSTVT集、;LASTVT集、算符优先关系表和分析过程图4-5 系统输出界面概况5 测试方法和测试结果5.1 测试用例1输入如程序5-1所示。
编译原理实验1有穷自动机的构造与实现一、实验目的1.正确理解正规式和正规集以及有穷自动机的定义。
2.熟练掌握用状态转换图表示有限自动机的方法。
二、实验的基础知识1.正规表达式就是一种形式化的表示法,它可以表示单词符号的结构,从而精确地定义单词符号集。
正规表达式简称为正规式,它表示的集合即为正规集。
2.状态转换图是一张当输入不同内容时选择不同分析路径的有向图。
一个状态转换图可用于识别一定的字符串。
3.标识符和无符号整形数可以使用正规式进行表示。
标识符的正规式为l(l|d)*,无符号整形数的正规式为dd*,其中,d为0~9的任意数,I 为a~z 或A~Z的任意字母。
三、实验内容构造识别如下字符串的状态转换图,并将其编程实现。
(1)识别标识符(以字母开始由字母和数字构成的字符串,要求长度不超过10)。
(2)无符号整型数,要求长度不超过20。
四、实验结果1.识别标识符(以字母开始由字母和数字构成的字符串,要求长度不超过10)。
#include <stdio.h>#include <string.h>#include "stdlib.h"//字符串处理的头文件char *sourceFile=,,D:\\AnalyzeFile.txt,,;char alphatp[10];//判断一个字符是不是字母bool lsletter(char ch){if(ch>=,a, && ch<=,z, 11 ch>=,A, && ch<=,Z,) return true;return false;)//判断一个字符是不是数字bool lsDigit(char ch){if(ch>=,0, && ch<=,9,)return true;return false;) //标识符char alphaprocess(char buffer z FILE* fp) {int i=-l;while ((Isletter(buffer)) 11 (IsDigit(buffer))) {alphatp[++i]=buffer; buffer=fgetc(fp); }alphatp[i+l]=,\O'; return(buffer);) int main(int argc, char* argv[]) {FILE *fp;char cbuffer;if((fp=fopen(sourceFile/'r ,,))==NULL)printf ("文件%s 不存在二 sourceFile); else {cbuffer = fgetc(fp); while (cbuffer!=EOF)if(lsletter(cbuffer))// 若为字母cbuffer=alphaprocess(cbuffer,fp); else printf(H This is not a label"); fclose(fp); return 0; } }printf(,,%s\n ,,,alphatp); } fclose(fp); return 0; } 2.无符号整型数,要求长度不超过20。
实验要求✧基本内容1)增加单词:保留字ELSE,REPEAT,DOWHILE,RETURN运算符+=,-=,++,--2)修改单词:不等号# 改为<>3)增加条件语句的ELSE子句4)扩充赋值运算:+= 和-=5)扩充语句(Pascal的FOR语句):①FOR <变量>:=<表达式> TO <表达式> DO <语句>②FOR <变量>:=<表达式> DOWNTO <表达式> DO <语句>其中,语句①的循环变量的步长为2,语句②的循环变量的步长为-2。
✧选做内容1)增加运算:++ 和--。
2)增加类型:①字符类型;②实数类型。
3)扩充函数:①有返回值和返回语句;②有参数函数。
4)增加一维数组类型(可增加指令)。
5)其他典型语言设施。
设计方案1.概述:源、目标语言:编译程序编绎的源程序是PL0,程序产生的目标代码是一个假想栈式计算机的汇编语言.称为类PCODE指令代码 ,指令格式格式如下:F L A其中F代表功能码,L表示层次差,A表示位移量,不同指令其含义有所区别。
PL/0语言是Pascal语言的一个子集,这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。
词法分析和代码生成作为独立的子程序供语法分析程序调用。
语法分析的同时,提供了出错报告和出错恢复的功能。
在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。
实现工具(平台),运行平台:编译器实现工具和运行平台程序用C++语言编写,在C++ Builder平台下运行。
2.结构设计说明:PL/0的编译过程采用一趟扫描方式,以语法分析为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读入单词时就调用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序。
2011-2012学年第二学期《编译原理》课程设计报告学院:计算机科学与工程学院班级:学生姓名:学号:成绩:指导教师:时间:2012年5 月目录一、课程设计的目的 ---------------------------------------------------------------- - 1 -二、课堂实验及课程设计的内容 -------------------------------------------------- - 1 -2.1、课堂实验内容-------------------------------------------------------------- - 1 -2.2、课程设计内容-------------------------------------------------------------- - 1 -三、visual studio 2008 简介------------------------------------------------------- - 2 -四、问题分析及相关原理介绍 ----------------------------------------------------- - 3 -4.1、实验部分问题分析及相关原理介绍 ---------------------------------- - 3 -4.1.1、词法分析功能介绍及分析------------------------------------- - 3 -4.1.2、语法分析功能介绍及分析------------------------------------- - 3 -4.1.3、语义分析功能介绍及分析------------------------------------- - 4 -4.2、课程设计部分问题分析及相关原理介绍 ---------------------------- - 5 -4.2.1、编译程序介绍 ----------------------------------------------------- - 5 -4.2.2、对所写编译程序的源语言的描述(C语言) -------------- - 6 -4.2.3、各部分的功能介绍及分析 -------------------------------------- - 7 -4.3、关键算法:单词的识别-------------------------------------------------- - 8 -4.3.1、算法思想介绍 ----------------------------------------------------- - 8 -4.3.2、算法功能及分析 -------------------------------------------------- - 8 -五、设计思路及关键问题的解决方法 ------------------------------------------ - 10 -5.1、编译系统------------------------------------------------------------------ - 10 -5.1.1、设计思路 --------------------------------------------------------- - 10 -5.2、词法分析器总控算法--------------------------------------------------- - 12 -5.2.1、设计思路 --------------------------------------------------------- - 12 -5.2.2、关键问题及其解决方法 --------------------------------------- - 13 -六、结果及测试分析-------------------------------------------------------------- - 14 -6.1、软件运行环境及限制--------------------------------------------------- - 14 -6.2、测试数据说明------------------------------------------------------------ - 14 -6.3、运行结果及功能说明--------------------------------------------------- - 16 -6.4、测试及分析说明--------------------------------------------------------- - 16 -七、总结及心得体会 --------------------------------------------------------------- - 17 -7.1、设计过程------------------------------------------------------------------ - 17 -7.2、困难与收获 ------------------------------------------------------------- - 17 -八、参考文献 ------------------------------------------------------------------------ - 18 -一、课程设计的目的通过设计、编写和调试词法分析程序(又称扫描器),了解扫描器的组成结构,不同种类单词的识别方法,加深了对词法分析作用的理解。
编译原理课程设计报告一、目的与要求目的:在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。
达到进一步了解程序编译过程的基本原理和基本实现方法的目的。
要求:对PL/0作以下修改扩充:基本内容(成绩范围:“中”、“及格”或“不及格”)(1)扩充赋值运算:+= 和-=(2)扩充语句REPEAT<语句序列>UNTIL <条件>其中,<条件>是循环条件,即条件不成立时,重复执行循环体的< 语句序列>;条件成立时,循环结束。
选做内容(成绩评定范围扩大到:“优”和“良”)(1)增加运算:++ 和--。
(2)增加类型:①字符类型;②实数类型。
(3)扩充函数:①有返回值和返回语句;②有参数函数。
(4)增加一维数组类型(可增加指令)。
(5)其他典型语言设施。
二、实验环境与工具(1)计算机及操作系统:PC机,WindowsXP(2)程序设计语言:C(3)教学型编译程序:PL/0三、设计方案(1)概述:源、目标语言,实现工具(平台),运行平台源语言: PL/0目标语言: 目标代码(生成的文件后缀为*.COD)实现平台: VC++ 6.0运行平台: WindowsXP(2)结构设计说明:各功能模块描述Error()出错处理,打印出错位置和错误编码GetCh()漏掉空格,读取一个字符GetSym()词法分析,读取一个单词GEN()目标代码生成过程,本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行TEST()测试当前单词是否合法过程testENTER()登陆符号表过程enterPOSITION() 在符号表中查找指定符号所在位置的函数position,如果找不到就返回0V ARDECLARATION()变量声明LISTCODE()列出目标代码清单;FACTOR()因子处理过程factorTERM()项处理过程term;EXPRESSION()表达式处理过程CONDITION()条件处理过程STATEMENT()语句处理过程BLOCK()语法分析过程BASE(): 通过静态链求出数据区基地址的函数,INTERPRET ():对目标代码解释运行过程(3)主要成分描述①符号表struct tablestruct{char name[al]; /* 名字*/enum object kind; /* 类型:const ,var ,procedure*/int val; /* 数值,仅const 使用*/int level; /* 所处层,仅const 不使用*/int adr; /* 地址,仅const 不使用*/Int size; /* 需要分配的数据区空间*/};struct tablestruct table[txmax]; /* 名字表*/②运行时存储组织和管理由于编译时目标程序运行的数据空间大小已经规定,所以存储组织属于静态存储。
编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。
本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。
二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。
此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。
三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。
在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。
首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。
然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。
在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。
对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。
(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。
在本次实验中,我们使用了递归下降的语法分析方法。
首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。
在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。
为了处理语法错误,在分析过程中添加了错误检测和处理机制。
当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。
(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。
在本次实验中,我们使用了三地址码作为中间代码的表示形式。
在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。
对于符合语义规则的语法结构,生成相应的三地址码指令。
四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。
编译原理课程设计报告实验名称编译原理课程设计班级学号姓名指导教师实验成绩2013 年06月一、实验目的➢通过设计、编写和调试,将正规式转换为不确定的有穷自动机,再将不确定的有穷自动机转换为与之等价的确定的有穷自动机,最后再将确定有穷自动机进行简化。
➢通过设计、编写和调试构造LR(0)项目集规范簇和LR分析表、对给定的符号串进行LR分析的程序,了解构造LR(0)分析表的步骤,对文法的要求,能够从文法G出发生成LR(0)分析表,并对给定的符号串进行分析。
二、实验内容➢正规式——>NFA——>DFA——>MFA1.正规式转化为不确定的有穷自动机(1)目的与要求通过设计、编写和调试将正规式转换为不确定的有穷自动机的程序,使学生了解Thompson算法,掌握转换过程中的相关概念和方法,NFA的表现形式可以是表格或图形。
(2)问题描述任意给定一个正规式r(包括连接、或、闭包运算),根据Thompson算法设计一个程序,生成与该正规式等价的NFA N。
(3)算法描述对于Σ上的每个正规式R,可以构造一个Σ上的NFA M,使得L(M)=L(R)。
步骤1:首先构造基本符号的有穷自动机。
步骤2:其次构造连接、或和闭包运算的有穷自动机。
(4)基本要求算法实现的基本要求是:(1) 输入一个正规式r;(2) 输出与正规式r等价的NFA。
(5)测试数据输入正规式:(a|b)*(aa|bb)(a|b)*得到与之等价的NFA N(6)输出结果2.不确定的有穷自动机的确定化(1)目的与要求通过设计、编写和调试将不确定的有穷自动机转换为与之等价的确定的有穷自动机的程序,使学生了解子集法,掌握转换过程中的相关概念和方法。
DFA的表现形式可以是表格或图形。
(2)问题描述任意给定一个不确定的有穷自动机N,根据算法设计一个程序,将该NFA N变换为与之等价的DFA D。
(3)算法描述用子集法将NFA转换成接受同样语言的DFA。
目录一.课程设计目的┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅2 二.课程设计题目描述和要求┅┅┅┅┅┅┅┅┅┅┅┅┅┅21、算术表达式的描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ 22、课程设计要求描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅23、实现的功能描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅25、分析器的使用描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅3三.课程设计实现描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅31、实现平台┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅32、课程设计基本思路描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅33、指定向下与递归下降分析方法的基本原理描述┅┅┅┅┅┅44、程序运行的最后界面┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ 55、演示分析┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅6 四.课程设计总结┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅7 五.实验中的代码描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅7 五.参考书目┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅19一、课程设计目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
加深对文法分析器的知识的掌握,掌握计算机语言的语法分析的过程。
以及掌握计算机语言的语法分析程序设计与文法应用的实现方法。
能够熟练运用一种分析方法,自上而下或自下而上的方法分析一个给定的文法,我使用的是自上而下的分析方法。
以及通过思考以及动手制作分析器的过程来锻炼自己的编程能力和逻辑思维能力,体会计算机编译器的奥妙之处。
二、课程设计题目描述和要求1、算术表达式的文法的描述:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/〈字母〉∷= a | b | … | z〈数字〉∷= 0 | 1 | … | 92、课程设计的要求描述:1)在递归下降法、LL(1)、算符优先分析法或者LR法中选择其中一种方法完成以上任务,中间代码选用四元式。
一.实验内容:掌握词法分析的基本思想,并用高级语言编写无符号数(包括整形和实数)的词法分析程序。
二.实验要求:从键盘上输入一串字符(包括字母,数字等),最后以”;”结束,编写程序识别出其中的无符号数。
三.实验源代码:#include<iostream>#include<cctype>#include<cstring>#include<cmath>using namespace std;int w=0; //尾数累加器int p=0; //指数累加器int j=0; //十进制小数位数计数器int e=1; //用来记录十进制数的符号,当指数为正时为1,为负时为-1int i=0; //用来标志元素位置int d=0; //用来表示每个数值型元素对应的数值const int N=40;//用来确定输入识别符的最大长度char data[N];//存放输入的识别符bool is_digit; //标志是否是数字string CJ1;//确定是整形还是实型double CJ2;//记数值//函数声明void check(char c);//检查首字母是否是数字的函数void deal_integer(char c);//处理识别符的整数部分void deal_point(char c);//用来处理小数部分void deal_index(char c);//用来处理指数部分void s_next();// 确定实型void z_next();//确定整型void last();// 计算CJ2void error();//程序中错误处理程序void deal();//处理函数主体int main(){ //主函数cout<<"please input your data,and its maximum length is "<<N<<":"<<endl;//等待用户输入识别符cin>>data;deal();//处理函数主体last();// 计算CJ2system("pause");return 0;}void check(char c) //判断输入的首字母是否是数字{is_digit=isdigit(c);while(is_digit!=true){//输入的首字母不是数字时cout<<"\nError! Try again.."<<endl;//要求重新输入cin>>data;check(data[0]);}}void deal_integer(char c){//处理识别符的整数部分d=(int)c-48;w=w*10+d;i++;if(isdigit(data[i])!=0)//下一个仍是数值时,调用程序本身deal_integer(data[i]);}void deal_point(char c){//用来处理小数部分int temp=i;if(isdigit(c)!=0)//是数值字符时deal_integer(c);else{ error(); //错误处理程序deal();//处理函数主体}j=i-temp;//记录十进制小数位数}void deal_index(char c){//用来处理指数部分if(c=='-') {e=-1;i++;}//是'-'号时else {if(c=='+') i++;//是'+' 号时else {if(isdigit(c)==false) //非数值字符时{ error();//错误处理程序deal();//处理函数主体}else{ d=(int)c-48;//把输入字符转换为整型goto pro2;}}}if(isdigit(data[i])!=0)pro1: d=(int)(data[i])-48;pro2: p=p*10+d;i++;if(isdigit(data[i])!=0)//是数值字符时goto pro1;else if(data[i]!='\0'){//非结束标志error();//错误处理程序deal();//处理函数主体}else s_next(); // 确定实型}void s_next(){// 确定实型i--;//退一个字符CJ1="实型";}void z_next(){//确定整型i--;//退一个字符CJ1="整型";}void last(){// 计算CJ2CJ2=w*pow((double)10,e*p-j);cout<<CJ1<<": "<<CJ2<<endl;//输出}void error(){//程序中错误处理程序cout<<"\nError! Try again.."<<endl;//重新输入数据cin>>data;p=0;w=0;j=0; //所有全局变量重新初始化e=1;i=0;d=0;//exit(0);}void deal(){check(data[0]);//判断输入的首字母是否是数字deal_integer(data[i]);//处理识别符的整数部分if(data[i]=='.'){ deal_point(data[++i]);//用来处理小数部分if(data[i]=='e'||data[i]=='E')//如果是e或E时deal_index(data[++i]);//用来处理指数部分else if(data[i]!='\0'){ error();//错误处理程序deal();//处理函数主体}else s_next();// 确定实型}else { if(data[i]=='e'||data[i]=='E')//如果是e或E时{ deal_index(data[++i]);//用来处理指数部分//CJ1="整型";}else if(data[i]!='\0'){ //非结束标志error();//错误处理程序deal();//处理函数主体}elsez_next();//确定整型}}四.实验结果截图:本科实验报告课程名称:编译原理实验项目:逆波兰式生成程序实验地点:迎西校区4506机房专业班级:学号:学生姓名:指导教师:2012年5月一.实验内容掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序。
编译原理实验教程课程设计背景编译原理是计算机科学专业的一门重要课程,它研究如何将高级语言翻译成低级语言,以便计算机执行。
编译器是实现这一过程的关键工具。
然而,对于很多学生来说,编译原理的理论知识学习起来比较抽象,难以掌握。
因此,本文旨在为编译原理的学习提供一些实验教程的设计思路。
实验一:词法分析器词法分析器是编译器的第一个模块,它的作用是将输入的字符流转化为一个个单词符号。
本实验的目的是设计并实现一个简单的词法分析器,实现以下功能:1.识别输入的程序中所包含的各个单词符号。
2.输出所有单词符号及其对应的单词类型。
3.当遇到不合法单词符号时,给出相应的错误提示。
具体实现可以采用有限自动机的思想,使用正则表达式或者手写代码,实现对于不同的单词类型的识别,并对于不合法单词进行识别和报错处理。
实验二:语法分析器语法分析器是编译器的第二个模块,它的作用是将词法分析器输出的单词序列转换成语法树或者语法分析表,以便后续进行语义分析和目标代码生成。
本实验的目的是设计并实现一个简单的语法分析器,实现以下功能:1.识别输入的程序是否符合所设计的文法规则。
2.输出语法树或语法分析表。
具体实现可以采用自上而下的递归下降分析法或自下而上的移进-规约分析法,实现对于不同的句型的识别,并生成语法树或语法分析表。
实验三:语义分析器语义分析器是编译器的第三个模块,它的作用是对语法分析器输出的语法树或语法分析表进行语义分析,并生成中间代码。
本实验的目的是设计并实现一个简单的语义分析器,实现以下功能:1.对语法树或语法分析表进行遍历,识别语法错误和语义错误,给出相应的错误提示。
2.生成中间代码。
具体实现可以采用语义规则和符号表的检查方式,识别语法错误和语义错误,并在生成中间代码时,根据中间代码语言的规则进行实现。
实验四:目标代码生成器目标代码生成器是编译器的第四个模块,它的作用是将中间代码转换成机器语言,以便计算机执行。
本实验的目的是设计并实现一个简单的目标代码生成器,实现以下功能:1.将中间代码转换成机器语言。
编译原理课程设计设计题目:有限自动机的运行年级:计062*名:***学号: ************日期: 2010-5-18****: ***广西工学院计算机工程系设计目的:1、理解有限自动机的作用2、利用转态图和状态表表示有限自动机3、以程序实现有限自动机的运行过程设计内容:(注:题目详细要求)利用状态表和有限自动机的运行原理编制程序,使得程序能够识别一个输入串是否为一个有效的符号串,具体可以选择下面之一:无符号定点实数、自然数、整数、十六进制数或其它自己定义的符号串。
一、分析原理词法分析:就是从左至右逐个字符地对源程序进行扫描,产生单词序列,用以语法分析。
在这里,我们先把文法转换成有穷自动机,然后构造出状态表,再由状态表构造出程序。
二、分析的算法将G[<无符号数>]文法转换成有穷自动机:构造状态矩阵;将有穷自动机的状S1 S2……Sn及输入的字a1a2……am构成一个n*m的矩阵。
输入状态d .e ε+/-0 1 2 41 12 4 Z2 33 34 Z再写一个程序,把状态矩阵用二维数组表示。
程序通过输入的字符转换状态,从而可以识别出单词。
本程序的关键在状态表和缓冲区的运用。
首先定义了一个布尔型函数ReadALine把输入的字符串送到缓冲区中;然后定义了布尔型函数Run 和Getchar实现对输入字符串的正确性判断,更改Run函数可以改变程序功能:如可将状态表改变成识别“偶数”的有限自动机的状态表。
三、程序流程图四、课程设计出现的问题及解决的方法刚开始写该程序时,虽然感觉个人的编程能力不错,但由于对编译原理的自动机的实现掌握不足,难以入手。
但经过对问题的更深入了解和分析,再通过网上和书本的资料的细读,最后终于把程序编写出来了。
程序中,碰到的最大的问题就是状态表的构造和如何把它转变为一个程序的实现过程。
解决的方法当然是看书。
五、课程设计的体会首先,题目给出的文法是有小毛病的。
我个人认为<无符号数>不可能推出 . <十进制数> 或者e <指数部分>的。
在写这个程序是只要对编译原理书本词法分析分析很熟悉就可以比较容易地写出该程序。
通过这次课程设计,我对程序的编译和运行有了更进一步的了解,更好地掌握了编译原理的词法分析过程。
六、程序清单#include <stdlib.h> //引入库函数#include <stdio.h> //引入基本的库函数#include <string.h> //引入字符串的库函数//状态表相关存储信息:#define STATE_NUMBER 7 //状态数目#define CHAR_NUMBER 4 //输入字符的种类: . ; d ; e/E ; +/-#define DOT 0 //输入数字在状态表中位于第0列#define DIGIT 1 //小数点位于状态表的第1列#define E 2 //E位于状态表的第2列#define AD 3 //+/-运算符位于状态表的第3列//State[][]为状态表,以整数组形式存放,0,1,2,3,4,5,6表示状态,-1表示没有此状态int State[STATE_NUMBER][CHAR_NUMBER]={{1,2,3,-1},{-1,4,-1,-1},{1,2,3,-1},{-1,5,-1,6},{-1,4,3,-1},{-1,5,-1,-1},{-1,5,-1,-1}};int Q[STATE_NUMBER] = {0,0,1,0,1,1,0}; //终态标志:0非终态,1终态。
int index=0;//错误坐标//缓冲区://输入缓冲区:由专门函数操作(ReadALine(),GetChar())#define BUFFER_SIZE 1000 //表达式缓冲区大小char Buffer[BUFFER_SIZE]; //表达式缓冲区,以'\0'表示结束int ipBuffer = 0; //表达式缓冲区当前位置序号char ch; //存放取得的一个字符//函数声明:int Run(); //对存储在缓冲区的一行字符串(以'#'结束)进行运行void Init(); //全局初始化int ReadALine(); //从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中char GetChar(); //从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中//主程序:void main(){Init();while(ReadALine()) //读一行成功,对它进行判断{if(Run()) //对该行进行运行,看是否能被接受?printf("接受\n\n");else{printf("不接受\n");printf("错误位置在第%d个字符!\n\n",index); //显示错误位置}}}//对存储在缓冲区的一行字符串(以'#'结束)进行运行//返回:如果是无符号定点实数,返回true;否则返回:falseint Run(){int S=0; //S存放运行时的当前状态,目前为初态index=0;while(GetChar()!='#'){index++;if(ch >= '0' && ch <= '9') //数字S = State[S][DIGIT]; //将状态转换成输入数字后的状态else if(ch == '.') //小数点S = State[S][DOT]; //将状态转换成输入小数点后的状态else if(ch == 'e'||ch == 'E') //eS = State[S][E]; //将状态转换成输入e后的状态else if(ch == '+'||ch == '-') //+或-符号S = State[S][AD]; //将状态转换成输入+或-后的状态else if(ch == NULL )return 0;else//其他都为非法字符return 0;if(S == -1) //处于非法状态return 0;}//运行结束,判断S是否为终态if(Q[S] == 1) //终态return 1;else//非终态return 0;}//全局初始化void Init(){printf("程序功能:输入一个字符串,判断它是否是无符号定点实数。
\n");printf("注意:若要退出,请输入“exit”或“#”!\n");printf("======================================================\n\n");}//从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中,以'#'结束,并置ipBuffer=0;//读到非空字符串:返回 true;读到单独的"#":返回 falseint ReadALine(){int l;char *ex="exit";printf("请输入以“#”号结束的无符号定点实数,\n");printf("或直接输入无符号定点实数:\n");scanf("%s",&Buffer);if(!strcmp(Buffer,ex)) exit(0); //判断是否退出l = strlen(Buffer); //读入的字符串的长度if(l == 0) return ReadALine(); //输入了空字符串,重新输入if(Buffer[0] == '#') return 0; //输入单独的'#'表示不再输入Buffer[l] = '#'; //最后一个字符用结束标记'#'代替(本来是'\0')ipBuffer = 0; //初始化缓冲区指针return 1;}//从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中//成功:返回字符;不成功:返回'#'char GetChar(){if((ch = Buffer[ipBuffer]) != '#' )ipBuffer ++; //位置序号加1return ch;}七、测试的结果该程序在Microsoft Visual C++ 6.0中调试通过,并且能够识别出一个输入串是否为一个有效的无符号数,测试结果符合题目要求。
具体结果如下图:。