实验报告-有穷状态自动机
编译原理 实验1 有穷自动机的构造与实现
}
char digitprocess(char buffer, FILE* fp)
{
int i=-1;
while((IsDigit(buffer)))
{
digittp[++i]=buffer;
buffer=fgetc(fp);
}
digittp[i+1]=\0';
return(buffer);
buffer=fgetc(fp);
}
alphatp[i+1]='\0';
return(buffer);
}
int main(int argc, char* argv[])
{
FILE *fp;//文件指针,指向要分析的源程序
char cbuffer;//保存最新读入的字符
if((fp=fopen(sourceFile,"r"))==NULL)//判断源文件是否存在
}
int main(int argc, char* argv[])
{
FILE *fp;//文件指针,指向要分析的源程序
char cbuffer;//保存最新读入的字符
if((fp=fopen(sourceFile,"r"))==NULL)//判断源文件是否存在
printf("文件%s不存在", sourceFile);
(2)无符号整型数,要求长度不超过20。
四、实验结果
1.识别标识符(以字母开始由字母和数字构成的字符串,要求长度不超过10)。
#include <stdio.h>
#include <string.h>
利用自动机进行词法分析
利用自动机进行词法分析一.实验目的1. 编写一个确定的有穷自动机程序, 并进行词法分析2. 掌握自动机的识别逻辑二.实验平台Windows+VisualC++三.实验内容编写一个简单的自动机程序, 仅用来识别标识符, 输入一个字符串若该字符串符合标识符规则, 程序输出‘YES', 否则输出‘NO”。
四.实验步骤1 写出判断输入串的正规式。
2 画出有限自动机的状态图。
3 画出有限自动机的状态表。
4用C语言程序实现对输入串的判定,基本原理以有限自动机最终得到的状态表或状态图来实现。
五.具体步骤我们知道:标识符是由,英文字母、数字、 '_'和 '$'组成,但必须满足,第一个字符不能是数字这一条件。
对于标识符而言,英文字母同'_'和'$'功能相同,没有区别。
因此,我们假设,用L 来表示:英文字母、 '_'、'$',用 D 来表示数字。
于是可以得到下列结果:1.正规式:L(L|D)* 。
2.状态图:(比较难画,略)3. 初始状态用0表示,末状态用1表示,不存在的状态用-1 表示。
状态表为:F(0,L)=1 F(0,D)=-1 F(0,其他)=-1 F(0,#)=0F(1,L)=1 F(1,D)=-1 F(1.其他)=-1 F(1,#)=14. C语言程序如下:#include<stdio.h> #include<iostream.h>#define MAX 100 // 定义最大的字符串长度main(){int f[2][4]={{1,-1,-1,0},{1,1,-1,1}};char DataInput[MAX];int DataInputC[MAX];int i,sub;char ynexit;printf(" 程序功能:输入一个字符串,判断它是否是无符号定点实数。
实验报告-有穷状态自动机
if(temp>='A'&&temp<='Z')//非终结符号的判断条件
{
bool state=true;
for(int k=0;k<VN;k++)
{
if (temp==K[k]) //避免重复
{state=false;break;}
{ char temp=p[i][j]; //暂时存放一个确定的符号
if(!((temp>='A'&&temp<='Z')||temp==':'||temp=='='||temp=='\0'))
//终结符号的判断条件
{
bool state=true;
for(int k=0;k<VT;k++)
{
if (temp==E[k]) //避免重复
*****大学**学院学生实验报告
学号:年月日
系别
专业
计算机科学与技术
班级
姓名
课程名称
编译原理
课程类型
必修课
学时数
实验名称
从正则文法构造有穷状态自动机及运行
实验目的:
一、从正则文法构造有穷状态自动机(1)、掌握有穷状态自动机的概念、其存储表示及其与正则文法的联系。(2)、输入任意的正则文法,输出相应的有穷状态自动机。
(3)、将文法按五元组形式输出。
(4)、编写若干个函数,其中包括在规则中找出终结符号和非终结符号的函数,字符串输入及识别字符串函数,DFA和NFA的相关判断和输出函数,映射关系函数。
有穷状态自动机
有穷状态自动机
实验内容: 实验内容:
输入:任意的正则文法和待识别的字符串。 输入:任意的正则文法和待识别的字符串。 输出: 对输入的字符串运行相应有穷状态 输出 自动机过程。 自动机过程。 要求: 对任意的输入字符串给出运行过程,最后 入字符串是否为所输入 给出识别结论 输入字符串是否为所输入 文法的句子)。 文法的句子 。
有穷状态自动机
有穷状态自动机很容易用程序实现, 有穷状态自动机很容易用程序实现,这只 需让每个状态对应一小段程序。 需让每个状态对应一小段程序。当一个节 点有不止一条的弧自它射出时, 点有不止一条的弧自它射出时,表明将有 不止一种的情况出现,因此让它对应于if语 不止一种的情况出现,因此让它对应于 语 句和goto语句配合组成的程序段。终止状 语句配合组成的程序段。 句和 语句配合组成的程序段 态一般对应于出口或返回语句。 态一般对应于出口或返回语句。
例
字母或数字
s
字母
1
其他
s E
可有如下程序: 可有如下程序:
例
STATES: Getchar(); if(letter()) goto STATES; else goto FALURE; STATES1: Getchar(); while(letter()||digit()) Getchar(); STATEE: return; FALURE: 出错处理; 出错处理;
编译原理实验一报告
【实验题目】接受无符号实数语言的有穷状态自动机(上机4学时)【实验目的】1. 理解有穷自动机的作用;进一步理解自动机理论。
2. 用状态图和状态矩阵表示有穷自动机;3. 以程序实现有穷自动机的运行过程;4. 掌握文法转换成自动机的技术及有穷自动机实现的方法。
【实验内容】无符号实数的有穷自动机的实现。
利用状态表和有穷自动机的运行原理编制程序,使得程序能够识别一个输入串是否为一个无符号实数。
【实验要求】设计要求:利用状态图或状态表相关理论,利用有穷自动机理论。
功能要求:输入一个单行无空格的字符串(以“#”结束),如果该字符串是一个合法的输入,则显示“接受”,否则显示“不接受”。
输入/输出样例:(1) 输入:3.58,输出:接受(2) 输入:3.5.8,输出:不接受;(3) 输入:3fk,输出:不接受【实验分析】(一)无符号实数的文法:〈无符号数〉→d〈余留无符号数〉|.〈十进小数〉|e〈指数部分〉〈余留无符号数〉→d〈余留无符号数〉|.〈十进小数〉|e〈指数部分〉|ε〈十进小数〉→d〈余留十进小数〉〈余留十进小数〉→e〈指数部分〉|d〈余留十进小数〉|ε〈指数部分〉→d〈余留整指数〉|s〈整指数〉〈整指数〉→d〈余留整指数〉〈余留整指数〉→d〈余留整指数〉|ε其中s表示正或负号(+,-),d表示0~9中的任一数字。
(二)由此构造状态转换图,DFA。
(三)构造状态矩阵:将有穷自动机的状态S1 S2 ……Sn及输入的字a1 a2 ……am 构成一个n*m的矩阵。
1)根据状态矩阵设计出一个识别无符号实数的词法分析程序。
2)扫描无符号实数,根据文法给出无符号实数出错的位置。
chapter 3-有穷状态自动机
1 0 q1 1 q2 0
0 1 q3
0,1
q4
第三章、有穷状态自动机
例2、假设字母表为{0,1},构造一个识别含有001子串的所有 字符串的DFA的状态图。
1 0 q1 1 q2 0
0 1 q3
0,1
q4
第三章、有穷状态自动机
关键问题:DFA与NFA等价吗?
第三章、有穷状态自动机
第三章、有穷状态自动机
NFA与DFA的等价性
NFA与DFA等价是指两种模型识别相同的语言类(正则语言)。 对于任意给定的DFA,存在一个NFA与之等价; 对于任意给定的NFA,存在一个DFA与之等价。 DFA本身就是一种NFA,所以,要证明DFA与NFA等价,只需证明 对于任意给定的NFA,存在一个DFA与之等价。 下面根据给定的NFA构造一个DFA: 这里M2=(Q2,Σ,δ,q0,F ),Q2 =P(Q),
第三章、有穷状态自动机
δ1
q01 q1 q2
0 1
q1 q2 q1
0 q02 q3 q4
q01 q1 Q2
1 q3 q4 q5
δ2
q02 q3 q4
q5
q5
q5
第三章、有穷状态自动机
下面构造M= (Q,Σ,δ,q,F), (1)Q={(r1,r2) ∣ r1∈Q1且r2∈Q2}; (2)Σ= {0,1}; (3)转移函数 δ((r1,r2) ,a)= δ (δ1 (r1,a) ,δ 2(r2,a)), 如下页表所示; (4)q0=(q01,q02)是M的起始状态; (5)F={(q2,q02),(q2,q3),(q2,q4),(q2,q5),(q01,q4), (q1,q4)}。
无符号的有穷自动机的实现
内蒙古工业大学信息工程学院实验报告课程名称:编译原理实验名称:无符号数的有穷自动机的实现综合性□ 设计性□实验类型:验证性班级:软件08-2班学号:200810205028姓名:赵中军组别:同组人:成绩:实验日期:实验一无符号数的有穷自动机的实现一、目的通过上机实习,熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。
掌握文法转换成自动机的技术及有穷自动机实现的方法。
二、题目无符号数的有穷自动机的实现三、要求及提示1、无符号数的BNF描述如下:0.<无符号数> → d <余留无符号数> | . <十进制数> | e <指数部分>1.<余留无符号数> → d <余留无符号数> | . <十进制数> | e <指数部分> | ε 2.<十进制小数> → d <余留十进制小数>3.<余留十进制小数> e <指数部分> | d <余留十进制小数> | ε4.<指数部分> → d <余留整指数> | + <整指数> | - <整指数>5.<整指数> → d <余留整指数>6.<余留整指数> → d <余留整指数> | ε2、将G[<无符号数>]文法转换成有穷自动机。
3、构造状态矩阵;将有穷自动机的状S1 S2……S n及输入的字a1 a2……a m构成一个n*m的矩阵。
1、状态矩阵设计出一个词法分析程序识别无符号数。
2、扫描无符号数,根据文法给出无符号数出错的位置。
3、工具:C语言或其它高级语言4、实践时间:8学时四、实践报告1、写出无符号数词法分析的思想。
2、画出算法流程图。
3、写出调试程序出现的问题及解决的方法。
4、打印实践报告及程序清单。
应用有穷状态自动机研究网络故障诊断
应用有穷状态自动机研究网络故障诊断网络故障诊断一直是网络运维中非常重要的一个环节,也是网络管理者不可或缺的技能之一。
当网络中出现故障时,如果不能及时准确地定位问题所在,则会给整个网络带来严重的影响,甚至导致系统瘫痪、数据丢失等灾难性后果。
因此,研究网络故障诊断方法显得尤为关键。
有穷状态自动机(Finite State Machine, FSM)作为一种有效的描述和分析系统行为的工具,被广泛应用于各个领域,其中包括网络故障诊断。
FSM是一种具有特定状态和转移规则的数学模型,它可以描述一个系统在特定条件下的所有可能行为。
在网络故障诊断中,FSM可以用于描述网络中各个设备之间的交互关系,提供从网络开始工作到出现故障的完整描述,帮助管理员清晰了解故障根源,快速准确地进行故障定位。
应用FSM进行网络故障诊断的基本流程包括以下几个步骤:1. 搜集网络数据在进行故障诊断前,需要先搜集网络数据。
数据搜集的方式有多种,例如抓取网络包、检测网络流量、记录设备日志等。
搜集到的数据包含了网络中各个设备之间的交互信息,是后续进行故障诊断的基础。
2. 根据数据建立模型根据搜集到的数据,建立基于FSM的模型。
FSM模型通常包括状态集合、初始状态、转移函数、终止状态等元素。
在建立模型时,需要深入理解网络中各个设备之间的交互关系,将其转化为FSM的状态和转移规则,从而形成完整的网络行为描述。
3. 诊断故障建立FSM模型后,可以通过模拟测试等方式进行故障诊断。
例如,输入一个特定的数据包序列,模拟其在网络中传输的过程,然后观察FSM模型的状态变化,判断是否存在异常状态,从而得出故障诊断结果。
在应用FSM进行网络故障诊断时,需要注意以下几点:1. FSM的建立过程需要对网络拓扑和设备的交互关系进行深入理解,需要具备一定的网络知识。
2. FSM建立的质量直接影响故障诊断的准确性,需要进行多次测试和优化,不断完善模型。
3. 在进行故障诊断时,需要基于实际网络环境和故障场景进行模拟测试,确保诊断结果准确可靠。
实现有穷状态自动机
#include <stdio.h>#include <string.h>#define STATE_NUMBER 4 //状态数目#define CHAR_NUMBER 2 //输入字符的种类: d 和 .#define DIGIT 0 //输入数字在状态表中位于第0列#define DOT 1 //小数点位于状态表的第1列//State[][]为状态表,以整数组形式存放,0,1,2,3表示状态,-1表示没有此状态int State[STATE_NUMBER][CHAR_NUMBER]= {{1,-1},{1,2},{3,-1},{3,-1}};int Q[STATE_NUMBER] = {0,1,0,1}; //终态标志:0非终态,1终态。
//缓冲区://输入缓冲区:由专门函数操作(ReadALine(),GetChar())#define BUFFER_SIZE 1000 //表达式缓冲区大小char Buffer[BUFFER_SIZE]; //表达式缓冲区,以'\0'表示结束int ipBuffer = 0; //表达式缓冲区当前位置序号char ch; //存放取得的一个字符//*****************************************************//函数声明:bool Run(); //对存储在缓冲区的一行字符串(以'#'结束)进行运行void Init(); //全局初始化bool ReadALine(); //从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中char GetChar(); //从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中//*****************************************************//主程序:void main(){Init();while(ReadALine()) //读一行成功,对它进行判断{if(Run()) //对该行进行运行,看是否能被接受?printf("接受\n\n");elseprintf("不接受\n\n");}}//对存储在缓冲区的一行字符串(以'#'结束)进行运行//返回:如果是无符号定点实数,返回true;否则返回:falsebool Run(){int S=0; //S存放运行时的当前状态,目前为初态while(GetChar()!='#'){if(ch >= '0' && ch <= '9') //数字S = State[S][DIGIT]; //将状态转换成输入数字后的状态else if(ch == '.') //小数点S = State[S][DOT]; //将状态转换成输入小数点后的状态else //其他都为非法字符return false;if(S == -1) //处于非法状态return false;}//运行结束,判断S是否为终态if(Q[S] == 1) //终态return true;else //非终态return false;}//全局初始化void Init(){//好像无需初始化printf("程序功能:输入一个字符串,判断它是否是无符号定点实数。
编译原理不确定有穷自动机的确定化。
编译原理实验报告实验三安徽大学计算机科学与技术学院1,实验名称不确定有穷自动机的确定化。
2,实验目的不确定有穷自动机的确定化。
3,实验原理1.NFA:一个不确定的有穷自动机M是一个五元组,M=(K,E,f,S,Z)其中a. K是一个有穷集,它的每个元素称为一个状态;b. E是一个有穷字母表,它的每个元素称为一个输入符号;c. f是一个从K×E*到K的子集的映像,即:K*E*->2k,其中2k表示K的幂集;d. S包含于K,是一个非空初态集;e. Z包含于K,是一个终态集。
2.DFA:一个确定的有穷自动机M是一个五元组,M=(K,E,f,S,Z)其中a. K是一个有穷集,它的每个元素称为一个状态;b. E是一个有穷字母表,它的每个元素称为一个输入符号;c. f是转换函数,是K×E->K上的映像,即,如f(ki,a)=kj(ki∈K,kj∈K)就意味着,当前状态为ki,输入字符为a时,将转换到下一状态kj,我们把kj称作ki的一个后继状态;d. S∈K,是唯一的一个初态;e. Z包含于K,是一个终态集,终态也称可接受状态或结束状态。
3,正规式正规式是一种表示正规集的工具,正规式是描述程序语言单词的表达式,对于字母表∑其上的正规式及其表示的正规集可以递归定义如下。
①ε是一个正规式,它表示集合L(ε)={ε}。
②若a是∑上的字符,则a是一个正规式,它所表示的正规集L(a)={a}。
③若正规式r和s分别表示正规集L(r)、L(s),则(a)r|s是正规式,表示集合L(r)∪L(s);(b)r·s是正规式,表示集合L(r)L(s);(c)r*是正规式,表示集合(L(r))*;(d)(r)是正规式,表示集合L(r)。
仅由有限次地使用上述三个步骤定义的表达式才是∑上的正规式。
运算符“|”、“·”、“*”分别称为“或”、“连接”和“闭包”。
在正规式的书写中,连接运算符“·”可省略。
03 有穷状态自动机
13
例3-2
构造一个 DFA,它接受的语言为{ x000y | x, y∈{0, 1}* }。 关键:是否出现了子串“000”? q0——M 的启动状态; q1——M 读到了一个 0,这个 0 可能是子串“000”的第 1 个0; q2——M 在 q1 后紧接着又读到了一个 0,这个 0 可能是子串 “000”的第 2 个0; q3——M 在 q2 后紧接着又读到了一个 0,发现输入字符串含 有子串“000”;因此,这个状态应该是终止状态。 可以给出 M 的状态转移函数的部分定义: δ(q0 ,0)=q1——M 读到了一个0,这个 0 可能是子串 “000”的 第1个0。 δ(q1,0)=q2——M 又读到了一个 0,这个 0 可能是子串 “000” 的第2个0。 δ(q2 ,0)=q3——M 找到了子串 “000”。
14
例3-2
δ(q0,1)=q0——M 在 q0 读到了一个 1,它需要继续在 q0 “等待” 可能是子串“000”的第 1 个 0 的输入字符 0; δ(q1,1)=q0——M 在刚刚读到了一个 0 后,读到了一个 1,表明 在读入这个 1 之前所读入的 0 并不是子串“000”的第 1 个 0, 因此,M 需要重新回到状态 q0,以寻找子串“000”的第1个0; δ(q2,1)=q0——M 在刚刚发现了00后,读到了一个1,表明在读入 这个1之前所读入的00并不是子串“000”的前两个0,因此, M 需要重新回到状态 q0,以寻找子串“000”的第 1 个 0; δ(q3,0)=q3——M 找到了子串“000”,只用读入该串的剩余部分。 δ(q3,1)=q3——M 找到了子串“000”,只用读入该串的剩余部分。
开始状态
状态
q0 q1
输入字符
第03章有穷状态自动机-电子科技大学
即时描述
设M = (Q, , , q0, F)为一个FA,x, y *, (q0, x)=q,xqy称为M的一个即时描述。 它表示xy是M 正在处理的一个字符串,x引导M 从q0启动并到达状态q,当前正指向y的首字符。 如果xqay是M的一个即时描述,且(q, a)=p,则 经过字符a的处理后,即时描述变为xapy。这一 过程记作: xqay
证明思路
(1) 显然,DFA是NFA的特殊形式;即所有 的DFA已经用NFA的形式表示; (2) 需要证明对于任意给定的NFA,存在与 之等价的DFA。
根据NFA构造DFA,将状态集合从Q变换到2Q, 这样DFA中的任意一个状态实际上是NFA中某 些状态的组合(这里避免使用术语“集合”)。 使用归纳法证明DFA与NFA的状态转移存在一 一对应关系。 证明由DFA和NFA能识别相同的语言。 L(M1) = L(M2)
作为对DFA的修改 q1 0 0 S 1 0 q0 1 1 q2
构造接受语言
0,1
q3
L={x| x{0,1}*,且 x含有子串00或11}的DFA
“直接”的FA
q1
0,1
S q0
0 1
0 1
0,1
q3
q2 希望是接受语言 L={x| x{0,1}*,且 x含有子串00或11}的FA
与DFA的区别
当这个子集为空时,表示没有状态与之对应;
当这个子集的元素个数大于1时,表示有多个状 态与之对应。
实验3--词法分析-FA的应用(已完成)
实验三词法分析——有穷自动机的应用一、实验目的:一:输入正则文法二:FA1.生成FA(DFA或NFA)2.运行FA,DFA(自动);NFA(交互)3.**NFA→DFA二、实验设想:对输入的文法存储并判断是确定的有穷状态自动机还是不确定是有穷状态自动机,并给出标准的表示形式,若是DFA,可直接测试一个符号串是否是文法的句子,即能否被有穷状态机接受,给出过程及结果;若是NFA,首先将其转化为DFA,再测试一个符号串是否是文法的句子,亦即是否能被DFA接受。
例如:输入文法规则的数目:7输入开始状态: S输入文法Z::=Za Z::=Bb Z::=Aa B::=Ab B::=b A::=Ba A::=a此为确定有穷状态自动机!DFA D=({Z,A,B},{a,b},M,S,{Z})其中M:M(Z,a)=ZM(B,b)=ZM(B,a)=AM(A,a)=ZM(A,b)=BM(S,b)=BM(S,a)=A输入要推导的符号串:ababaaM(S,ababaa)=M(M(S,a),babaa)=M(A,babaa)=M(M(A,b),abaa)=M(B,abaa)=M(M(B,a),baa)=M(A,baa)=M(M(A,b),aa)=M(B,aa)=M(M(B,a),a)=M(A,a)=Z该符号串能被有穷状态所接受!输入文法规则的数目:7输入开始状态: S输入规则:Z::=Ab Z::=Ba Z::=Zc A::=Ba A::=a B::=Ab B::=b 文法规则存储完毕!此为非确定有穷状态自动机!NFA N=({Z,B,A},{b,a,c},M,{S},{Z})其中M:M(A,a)=$M(A,b)={Z,B}M(A,c)=$M(B,a)={Z,A}M(B,b)=$M(B,c)=$M(Z,a)=$M(Z,b)=$M(Z,c)={Z}M(S,a)={A}M(S,b)={B}M(S,c)=$将NFA转化为DFA!DFA N'=({[S],[B],[A],[AZ],[BZ],[Z]},{[b],[a],[c]}, M',[S],F')其中M':M'([S],b)=[B]M'([S],a)=[A]M'([B],a)=[AZ]M'([A],b)=[BZ]M'([AZ],b)=[BZ]M'([AZ],c)=[Z]M'([BZ],a)=[AZ]M'([BZ],c)=[Z]M'([Z],c)=[Z]其中F'={[AZ],[BZ],[Z]}输入要推导的字符串:ababcM'([S],ababc)=M'(M'([S],a),babc)=M'([A],babc)=M'(M'([A],b),abc)=M'([BZ],abc)=M'(M'([BZ],a),bc)=M'([AZ],bc)=M'(M'([AZ],b),c)=M'([BZ],c)=[Z][Z]属于终止状态集合!该字符串能被有穷状态所接受!三、参考程序#include<iostream.h>#include<String.h>struct LeftItem;struct RightNode //存储状态转换关系中弧与终止状态结点结构{char tran;char nextstate;RightNode* nextsibling;RightNode(char x,char y){tran=x; nextstate=y; nextsibling=NULL;}};struct LeftItem //存储状态转换关系中初始状态结点结构{char state;RightNode* link;};struct StateItem //存放确定化的NFA状态结点结构{char newstates[10];StateItem(){newstates[0]='\0';}};////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int CheckState(LeftItem Array[],int size){RightNode* p;RightNode* q;for(int i=0;i<size;i++){p=Array[i].link;q=p->nextsibling;if(q==NULL) return 1;while(q!=NULL){if(p->tran==q->tran) return 0;q=q->nextsibling;}}return 1;}int CheckExist(StateItem SArray[],int& length,char temp[])//将NFA确定化创建二维矩阵时判别新产生的状态是否在状态数组中存储过{int i=0,k,m;while(i<=length){if(strlen(SArray[i].newstates)==strlen(temp)){if(strcmp(SArray[i].newstates,temp)==0){k=i;break;}}i++;}if(i>length){length++;m=length;return m;}elsereturn k;}int getcount1(LeftItem Array[],int size) //取得FA中状态的个数{char temp[20];int len=0,count=0;int i,j;RightNode* pNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode){for(j=0;j<len;j++)if(pNode->nextstate==temp[j]) break;if(j==len){count++;temp[len]=pNode->nextstate;len++;}pNode=pNode->nextsibling;}}return count;}int getcount2(LeftItem Array[],int size) //取得FA中输入字母的个数{char temp[20];int len=0,count=0;int i,j;RightNode* pNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode){for(j=0;j<len;j++)if(pNode->tran==temp[j]) break;if(j==len){count++;temp[len]=pNode->tran;len++;}pNode=pNode->nextsibling;}}return count;}int getstate(RightNode* pNode,char arc) //判定一个状态是否能通过一条弧进入下一状态{while(pNode){if(pNode->tran==arc) return 1;pNode=pNode->nextsibling;}return 0;}void Sort(char A[],int n) //将取得的新状态进行排序{for(int i=n-1;i>0;i--)for(int j=0;j<i;j++){if(A[j+1]<A[j]){char temp=A[j+1];A[j+1]=A[j];A[j]=temp;}}}void Bianli1(LeftItem Array[],int size) //输出FA中有穷非空的状态集合{char temp[20];int len=0;int i,j;RightNode* pNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode){for(j=0;j<len;j++)if(pNode->nextstate==temp[j]) break;if(j==len){if(len==0) cout<<pNode->nextstate;elsecout<<","<<pNode->nextstate;temp[len]=pNode->nextstate;len++;}pNode=pNode->nextsibling;}}}void Bianli2(LeftItem Array[],int size)//输出FA中有穷的输入字母表{char temp[20];int len=0;int i,j;RightNode* pNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode){for(j=0;j<len;j++)if(pNode->tran==temp[j]) break;if(j==len){if(len==0) cout<<pNode->tran;elsecout<<","<<pNode->tran;temp[len]=pNode->tran;len++;}pNode=pNode->nextsibling;}}}void Bianli31(LeftItem Array[],int size)//输出DFA状态转换关系的集合M{int i;RightNode* pNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode!=NULL){cout<<" M("<<Array[i].state<<","<<pNode->tran<<")="<<pNode->nextstate<<endl;pNode=pNode->nextsibling;}}}void Bianli32(LeftItem Array[],int size) //输出NFA状态转换关系集合M {char K[20];int len=0;int i,j;RightNode* pNode;RightNode* qNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode){for(j=0;j<len;j++)if(pNode->tran==K[j]) break;if(j==len){K[len]=pNode->tran;len++;}pNode=pNode->nextsibling;}}Sort(K,len);for(i=0;i<size;i++){for(j=0;j<len;j++){pNode=Array[i].link;cout<<" M("<<Array[i].state<<","<<K[j]<<")=";if(getstate(pNode,K[j])){cout<<"{";while(pNode){if(pNode->tran==K[j]){qNode=pNode->nextsibling;cout<<pNode->nextstate;break;}pNode=pNode->nextsibling;}while(qNode){if(qNode->tran==K[j])cout<<","<<qNode->nextstate;qNode=qNode->nextsibling;}cout<<"}"<<endl;}elsecout<<"$"<<endl;}}}void Initiate(LeftItem Array[],int size,char TArray[]) //将FA中的输入字母表存入数组TArray[] {int len=0;int i,j;RightNode* pNode;for(i=0;i<size;i++){pNode=Array[i].link;while(pNode){for(j=0;j<len;j++)if(pNode->tran==TArray[j]) break;if(j==len){TArray[len]=pNode->tran;len++;}pNode=pNode->nextsibling;}}}void GetState(LeftItem Array[],int size,char nstate[],char arc,char temp[])//将NFA确定化创建二维矩阵时取得新状态{int i=0;while(nstate[i]!='\0'){for(int j=0;j<size;j++){if(Array[j].state==nstate[i]){RightNode* p=Array[j].link;while(p!=NULL){if(p->tran==arc){int k=0;while(temp[k]!='\0'){if(p->nextstate==temp[k]) break;k++;}if(temp[k]=='\0'){temp[k]=p->nextstate;temp[k+1]='\0';}}p=p->nextsibling;}}}i++;}}void Change(StateItem SArray[],char temp[],int& length,int MArray[][20],int index,int i) //取得新状态后对状态数组以及状态转换矩阵进行对应变化{int k;if(temp[0]!='\0'){k=CheckExist(SArray,length,temp);MArray[index][i]=k;if(k==length)strcpy(SArray[length].newstates,temp);}}char FindNewState(LeftItem Array[],int size,char S,char arc) //得到当前状态的下一状态{int i;for(i=0;i<size;i++){if(Array[i].state==S){RightNode* p=Array[i].link;while(p!=NULL){if(p->tran==arc) return p->nextstate;p=p->nextsibling;}}}return NULL;}int Findy(char TArray[],char s) //取得输入字母在字母表中的下表{int i=0;while(TArray[i]!='\0'){if(TArray[i]==s) return i;i++;}}void CreateFA1(LeftItem Array[],int size,char start,char end)//根据输入文法创建FA{if(CheckState(Array,size)){cout<<"此为确定有穷状态自动机!"<<endl;cout<<"DFA D=(";}else{cout<<"此为非确定有穷状态自动机!"<<endl;cout<<"NFA N=(";cout<<"{";Bianli1(Array,size);cout<<"},{";Bianli2(Array,size);cout<<"},M,";if(CheckState(Array,size)) cout<<start;else cout<<"{"<<start<<"}";cout<<","<<"{"<<end<<"})"<<endl;cout<<"其中M:"<<endl;if(CheckState(Array,size))Bianli31(Array,size);elseBianli32(Array,size);}void CreateFA2(LeftItem Array[],int size,char start,char end,StateItem SArray[],char TArray[],int& length,int MArray[][20])//将NFA转换为DFA{char temp[20];int index=0;int i;do{i=0;while(TArray[i]!='\0'){temp[0]='\0';GetState(Array,size,SArray[index].newstates,TArray[i],temp);Sort(temp,strlen(temp));Change(SArray,temp,length,MArray,index,i);i++;}index++;}while(index<=length);}void Display(StateItem SArray[],char TArray[],int MArray[][20],int x,int y,char start,char end)//输出确定化的NFA{int i,j,k;cout<<"将NFA转化为DFA!"<<endl;cout<<"DFA N'=({";for(i=0;i<x;i++)if(i==0) cout<<"["<<SArray[i].newstates<<"]";else cout<<",["<<SArray[i].newstates<<"]";}cout<<"},{";for(i=0;i<y;i++){if(i==0) cout<<"["<<TArray[i]<<"]";elsecout<<",["<<TArray[i]<<"]";}cout<<"}, M',["<<start<<"],F')"<<endl;cout<<"其中M':"<<endl;for(i=0;i<x;i++)for(j=0;j<y;j++){if(MArray[i][j]!=-1){k=MArray[i][j];cout<<"M'(["<<SArray[i].newstates<<"],"<<TArray[j]<<")=["<<SArray[k].newstates<<"]"<<endl;}}cout<<"其中F'={";k=0;for(i=0;i<x;i++){j=0;while(SArray[i].newstates[j]!='\0'){if(SArray[i].newstates[j]==end) break;j++;}if(SArray[i].newstates[j]!='\0'){if(k==0) cout<<"["<<SArray[i].newstates<<"]";elsecout<<",["<<SArray[i].newstates<<"]";k++;}}cout<<"}"<<endl;}void RunFA1(LeftItem Array[],int size,char start,char end){char TD[20];int i=0,j;char s=start;cout<<"请输入要推导的符号串:";cin>>TD;cout<<" M("<<s<<",";for(j=0;TD[j]!='\0';j++)cout<<TD[j];cout<<")"<<endl;while(TD[i]!='\0'){if(TD[i+1]!='\0'){cout<<"=M(M("<<s<<","<<TD[i]<<"),";for(j=i+1;TD[j]!='\0';j++)cout<<TD[j];cout<<")"<<endl;}s=FindNewState(Array,size,s,TD[i]);if(s==NULL) break;if(TD[i+1]=='\0')cout<<"="<<s<<endl;else{cout<<"=M("<<s<<",";for(j=i+1;TD[j]!='\0';j++)cout<<TD[j];cout<<")"<<endl;}i++;}if(TD[i]=='\0'){if(s==end)cout<<"该符号串能被有穷状态所接受!"<<endl<<endl;elsecout<<"该符号串不能被有穷状态所接受!"<<endl<<endl;}elsecout<<"该符号串不能被有穷状态所接受!"<<endl<<endl;void RunFA2(StateItem SArray[],char TArray[],int start,int end,int MArray[][20]){char TD[20];int i,j,k,x,y;char s=start;cout<<"请输入要推导的字符串:";cin>>TD;cout<<" M'(["<<s<<"],";for(i=0;TD[i]!='\0';i++)cout<<TD[i];cout<<")"<<endl;x=0;i=0;while(TD[i]!='\0'){if(TD[i+1]!='\0'){cout<<"=M'(M'([";cout<<SArray[x].newstates;cout<<"]";cout<<","<<TD[i]<<"),";for(j=i+1;TD[j]!='\0';j++)cout<<TD[j];cout<<")"<<endl;}y=Findy(TArray,TD[i]);x=MArray[x][y];if(x==-1) break;if(TD[i+1]=='\0'){cout<<"=";cout<<"["<<SArray[x].newstates<<"]"<<endl;}else{cout<<"=M'(";cout<<"["<<SArray[x].newstates<<"],";for(j=i+1;TD[j]!='\0';j++)cout<<TD[j];cout<<")"<<endl;}i++;}if(TD[i]=='\0'){for(k=0;SArray[x].newstates[k]!='\0';k++)if(SArray[x].newstates[k]==end) break;if(SArray[x].newstates[k]!='\0'){cout<<"["<<SArray[x].newstates<<"]"<<"属于终止状态集合!"<<endl;cout<<"该字符串能被有穷状态所接受!"<<endl<<endl;}elsecout<<"该字符串不能被有穷状态所接受!"<<endl<<endl;}elsecout<<"该字符串不能被有穷状态所接受!"<<endl<<endl;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void main(){int size=0,sign=0;int i,j,n,sel;int count1,count2;int length=0;char start;char end;char temp[10];int MArray[20][20];RightNode* p;cout<<"请输入文法规则的数目:";cin>>n;cout<<"请输入开始状态: ";cin>>start; //得到初始状态LeftItem* Array=new LeftItem[n];for(i=0;i<n;i++){do{cout<<"请输入第"<<i+1<<"条规则:";cin>>temp;}while(strlen(temp)>6);if(strlen(temp)==6){for(j=0;j<size;j++)if(Array[j].state==temp[4]) break;if(j==size){Array[size].state=temp[4];Array[size].link=new RightNode(temp[5],temp[0]);size++;}else{for(p=Array[j].link;p->nextsibling!=NULL;p=p->nextsibling) {}p->nextsibling=new RightNode(temp[5],temp[0]);}}else{for(j=0;j<size;j++)if(Array[j].state==start) break;if(j==size){Array[size].state=start;Array[size].link=new RightNode(temp[4],temp[0]);size++;}else{for(p=Array[j].link;p->nextsibling!=NULL;p=p->nextsibling) {}p->nextsibling=new RightNode(temp[4],temp[0]);}}}end=Array[0].link->nextstate; //得到终止状态cout<<endl<<"文法规则存储完毕!"<<endl<<endl;count1=getcount1(Array,size);count2=getcount2(Array,size);StateItem* SArray=new StateItem[100];char* TArray=new char[count2+1];SArray[0].newstates[0]=start;SArray[0].newstates[1]='\0';Initiate(Array,size,TArray);TArray[count2]='\0';for(i=0;i<20;i++)for(j=0;j<20;j++)MArray[i][j]=-1;cout<<endl;aaa:cout<<"-----生成FA请按1-----"<<endl;cout<<"-----运行FA请按2-----"<<endl;cout<<"-----退出请按3-------"<<endl;do{cin>>sel;}while(sel!=1&&sel!=2&&sel!=3);switch(sel){case 1:CreateFA1(Array,size,start,end); //根据输入文法建立FAif(!CheckState(Array,size)) //将NFA确定化{CreateFA2(Array,size,start,end,SArray,TArray,length,MArray);Display(SArray,TArray,MArray,length+1,count2,start,end);}sign++;break;case 2:if(sign==0){cout<<"请先生成FA!"<<endl;goto aaa;}if(CheckState(Array,size))RunFA1(Array,size,start,end); //运行DFA elseRunFA2(SArray,TArray,start,end,MArray); //运行确定化的NFAbreak;case 3:break;}if(sel!=3) goto aaa;}四、实验截图1、DFA2、NFA- 21 -- 21 -。
从NFA到DFA的转化实验报告
从NFA到DFA的转化实验报告实验名称:从NFA到DFA的转化实验一、实验目的:1.理解并掌握从非确定有穷状态自动机(NFA)到确定有穷状态自动机(DFA)的转换方法;2.掌握NFA和DFA之间的关系及其转换规则;3.通过实际操作,加深对自动机理论的理解和应用。
二、实验原理:1.非确定有穷自动机(NFA):一台具有多个可能的下一状态的状态机,在给定一个输入后,可能进入多个不同的状态;2.确定有穷自动机(DFA):一台具有唯一确定的下一状态的状态机,在给定一个输入后,只能进入一个确定的状态。
三、实验步骤:1.给定一个NFA,包括起始状态、接受状态和状态转移函数;2.构建一个DFA的转换表,包括状态和转移条件的组合;3.根据转换表,构建DFA的状态转移图;4.分析和比较NFA和DFA之间的差异。
四、实验材料:1.NFA转换表,包括起始状态、接受状态和状态转移函数的定义;2.纸与笔,用于绘制状态转移图。
五、实验过程:假设我们有一个NFA,如下所示:起始状态:q0接受状态:q4状态转移函数:q0,0->q1q1,0->q2q1,1->q4q2,1->q3q3,0->q41.根据给定的NFA,我们可以先绘制其状态转移图,以便更直观地观察和分析它的结构。
根据转移函数和起始状态、接受状态,我们可以得到如下的状态转移图。
/-0-\q0->q1-q2->q3-\/\10\/,q4<-q4<-q4<-q4<-2.根据给定的NFA状态转移图,我们可以开始构建DFA的转换表。
a.DFA的起始状态为{q0},即NFA的起始状态的ε闭包。
b.根据DFA起始状态{q0}和输入0,我们可以通过NFA状态转移图得到{q1}。
c.继续根据DFA状态{q1}和输入0,我们可以得到{q2,q4},即NFA 状态q1经过一个输入0可以到达的状态。
d.类似地,我们可以构建其他的状态组合和输入的转换关系。
不确定有穷自动机的确定化
不确定有穷自动机的确定化不确定有穷自动机的确定化实验时间_____ 2022年4月10日_______院系_______管理信息工程学院_______班级_______11计算机科学与技术____学号______2022年0102022年9____________姓名________姜高__________________1、实验目的不确定有穷自动机的确定化2、实验原理用子集构造算法构造子集加入子集族中直到收敛(所有构造的子集都已存在于子集族)为止。
如原来不确定有穷自动机的五元组形式为:M=(K,,F,S,Z),其中K为状态集,为字母表,F为转换函数,S为初始态,Z为终态集。
用子集族S代替K,新的转换函数D代替F,形成新的五元组M=(S,,D,S,Z)即将原不确定有穷自动机转换为确定有穷自动机。
3、实验内容(1)闭包计算:closure(I)(2)转换函数:move(I,a)4、伪代码假定构造的子集族为S=(T1,T2。
),K为状态集:(1)开始,令closure(K0)为S中唯一成员,并且未被标记(2)WHILE(C中存在尚未被标记的子集T)DO{标记T;For 每输入字母aDO{U:=closure(move(T,a));If U 不在S中then将U作为未被标记的子集加在S中}}5.代码实现#includeiostream#includestring#define MAXS 100using namespace std;string NODE; //结点集合string CHANGE; //终结符集合int N; //NFA边数struct edge{string first;string change;string last;};struct chan{string ltab;string jihe[MAXS];};void kong(int a){int i;for(i=0;ii++)cout' ';}//排序void paixu(string a){int i,j;char b;for(j=0;ja.length();j++)for(i=0;ia.length();i++)if(NODE.find(a[i])NODE.find(a[i+1])) {b=a[i];a[i]=a[i+1];a[i+1]=b;}}void eclouse(char c,string he,edge b[]) {int k;for(k=0;kk++){if(c==b[k].first)if(b[k].change==“*"){if(he.find(b[k].last)he.length())he+=b[k].last;eclouse(b[k].last,he,b);}}void move(chan he,int m,edge b[]){int i,j,k,l;k=he.ltab.length();l=he.jihe[m].length();for(i=0;ii++)for(j=0;jj++)if((CHANGE[m]==b[j].change)(he.ltab[i]==b[j].first))if(he.jihe[m].find(b[j].last)he.jihe[m].length())he.jihe[m]+=b[j].last;for(i=0;ii++)for(j=0;jj++)if((CHANGE[m]==b[j].change)(he.jihe[m][i]==b[j].first)) if(he.jihe[m].find(b[j].last)he.jihe[m].length())he.jihe[m]+=b[j].last;}//输出void outputfa(int len,int h,chan *t)int i,j,m;cout" I ";for(i=0;ii++)cout'I'CHANGE[i]" ";coutendl"-------------------------"endl; for(i=0;ii++){cout' 't[i].ltab;m=t[i].ltab.length();for(j=0;jj++){kong(8-m);m=t[i].jihe[j].length();coutt[i].jihe[j];}coutendl;}}void main(){edge *b=new edge[MAXS];int i,j,k,m,n,h,x,y,len;bool flag;string jh[MAXS],endnode,ednode,sta;cout"请输入NFA各边信息(起点条件[空为*] 终点),以"endl;for(i=0;iMAXS;i++) #结束:cinb[i].first;if(b[i].first=="#") break;cinb[i].changeb[i].last;}N=i;/*for(j=0;jj++)coutb[j].firstb[j].changeb[j].lastendl;*/for(i=0;ii++){if(NODE.find(b[i].first)NODE.length())NODE+=b[i].first;if(NODE.find(b[i].last)NODE.length())NODE+=b[i].last;if((CHANGE.find(b[i].change)CHANGE.length())(b[i].change!="*"))CHANGE+=b[i].change;}len=CHANGE.length();cout"结点中属于终态的是:"endl;cinendnode;for(i=0;iendnode.length();i++)if(NODE.find(endnode[i])NODE.length())cout"所输终态不在集合中,错误!"endl;return;}//cout"endnode="endnodeendl;chan *t=new chan[MAXS];t.ltab=b.first;h=1;eclouse(b.first,t.ltab,b); //求e-clouse//coutt.ltabendl;for(i=0;ii++){for(j=0;jt[i].ltab.length();j++)for(m=0;mm++)eclouse(t[i].ltab[j],t[i].jihe[m],b); //求e-clousefor(k=0;kk++){//coutt[i].jihe[k]"-move(t[i],k,b); //求move(I,a)//coutt[i].jihe[k]endl;for(j=0;jt[i].jihe[k].length();j++)eclouse(t[i].jihe[k][j],t[i].jihe[k],b); //求e-clouse }for(j=0;jj++){paixu(t[i].jihe[j]); //对集合排序以便比较for(k=0;kk++){flag=operator==(t[k].ltab,t[i].jihe[j]);if(flag)break;}if(!flagt[i].jihe[j].length())t[h++].ltab=t[i].jihe[j];}}coutendl"状态转换矩阵如下:"endl; outputfa(len,h,t); //输出状态转换矩阵//状态重新命名string *d=new string[h];NODE.erase();coutendl"重命名:"endl;for(i=0;ii++){sta=t[i].ltab;t[i].ltab.erase();t[i].ltab='A'+i;NODE+=t[i].ltab;cout'{'sta"}="t[i].ltabendl;for(j=0;jendnode.length();j++)if(sta.find(endnode[j])sta.length())d=ednode+=t[i].ltab;for(k=0;kk++)for(m=0;mm++)if(sta==t[k].jihe[m])t[k].jihe[m]=t[i].ltab;}for(i=0;iNODE.length();i++)if(ednode.find(NODE[i])ednode.length()) d+=NODE[i];endnode=ednode;coutendl"DFA如下:"endl;outputfa(len,h,t); //输出DFAcout"其中终态为:"endnodeendl;//DFA最小化m=2;sta.erase();flag=0;for(i=0;ii++){//cout"d["i"]="d[i]endl;for(k=0;kk++){//cout"I"CHANGE[k]endl;y=m;for(j=0;jd[i].length();j++){for(n=0;nn++){if(d[n].find(t[NODE.find(d[i][j])].jihe[k])d[n].length()||t[NODE.find(d [i][j])].jihe[k].length()==0){if(t[NODE.find(d[i][j])].jihe[k].length()==0)x=m;elsex=n;if(!sta.length()){sta+=x+48;}elseif(sta!=x+48){d[m]+=d[i][j];flag=1;d[i].erase(j,1);//coutd[i]endl;j--;}break; //跳出n}}//n}//jif(flag){m++;flag=0;}//cout"sta="staendl; sta.erase();}//k}//icoutendl"集合划分:"; for(i=0;ii++) cout"{"d[i]"} "; coutendl;//状态重新命名chan *md=new chan[m];NODE.erase();coutendl"重命名:"endl;for(i=0;ii++){md[i].ltab='A'+i;NODE+=md[i].ltab;cout"{"d[i]"}="md[i].ltabendl;}for(i=0;ii++)for(k=0;kk++)for(j=0;jj++){if(d[i]==t[j].ltab){for(n=0;nn++){if(!t[j].jihe[k].length())break;elseif(d[n].find(t[j].jihe[k])d[n].length()) {md[i].jihe[k]=md[n].ltab;break;}}break;}}ednode.erase();for(i=0;ii++)for(j=0;jendnode.length();j++)if(d[i].find(endnode[j])d[i].length()ednode.find(md[i].ltab)) ednode+=md[i].ltab;。
【免费下载】无符号数的有穷自动机的实现
第
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根通保据过护生管高产线中工敷资艺设料高技试中术卷资,配料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高与中带资负料荷试下卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并3中试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内 纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
print_1();//调用输出映射集合的函数
Search_big();//调用输出有穷非空的状态集合的函数
for(i=0;i<m;i++)
{ while(str[i]!='\0')//循环判断条件(不为空)
{
for(j=0;j<line;j++)
{
if(G==ch[j][2]&&str[i]==ch[j][4])
}
else
{
ch[i][2]='S'; ch[i][4]=p[i][4];ch[i][7]=p[i][0];
}
}
}
//转换过程(把具有相同规则右部的映射合并)
void print_2()
{ //此输出主要是针对NFA,因为其一个状态可能对应多个映射弧,则要在输出时进行状态合并
print_1();//调用1,针对某些一对一映射
ch[k1][k2]=ch[k1+1][k2];
line--;
}
else break;
}
}
}
void print_D()//输出DFA
{
print_1();
cout<<"M:"<<endl;
for(i=0;i<line;i++)
{
for(j=0;j<=7;j++)
{
cout<<ch[i][j];
if(j==7)
cout<<endl;
}
}
}
void print_N()//输出NFA
{
print_2();
cout<<"M:"<<endl;
for(i=0;i<line;i++)
{
for(j=0;j<7;j++)
{
cout<<ch[i][j];
}
cout<<"{";
for(j=7;j<strlen(ch[i]);j++)
for(int s=0;s<6;s++)
{
cout<<ch[j][s];
}
}
int length=m;//从键盘输入的字符串的第一个开始判断,设输入的字符为M个
for(int t=0;t<length;t++)
{
str[t]=str[t+1];//字符串整体向前移动
}
length--;//长度逐次递减,移向下一个字符
*****大学**学院学生实验报告
学号:年月日
系别
专业
计算机科学与技术
班级
姓名
课程名称
编译原理
课程类型
必修课
学时数
实验名称
从正则文法构造有穷状态自动机及运行
实验目的:
一、从正则文法构造有穷状态自动机(1)、掌握有穷状态自动机的概念、其存储表示及其与正则文法的联系。(2)、输入任意的正则文法,输出相应的有穷状态自动机。
}
for( i=0;i<20;i++)
{
for(int j=0;j<20;j++)
{
ch[i][j]='\0';//将存放映射的数组初始化
}
}
}
//求出有穷非空的输入字母表
void zhongjie()
{
VT=0;
for(int i=0;i<line;i++) //逐行遍历
for(int j=0;j<6;j++)
二、运行有穷状态自动机(1)、以简便方式输入有穷状态自动机。(2)、除给出运行过程,还给出识别结论(输入字符串能否为相应的有穷状态自动机所接受)。
(3)、对于非确定的有穷状态自动机的运行采用交互式方式,以简便形式输出运行过程。
内容和步骤:
(1)、输入任意的正则文法。
(2)、采用二维矩阵数据结构,先将文法输入到二维矩阵中,对数据结构进行操作,可以从中分离出非终结符号和终结符号。
{
G=ch[j][7];//把M中的每个映射的等号右端的字符赋给G
if(G==K[0])//如果G等于终结符号
{
cout<<"=";
for(int s=0;s<6;s++)
{
cout<<ch[j][s];
}
cout<<"="<<G;
cout<<endl;
break;
}
else
{
cout<<"="<<"M"<<"(";
#include<iostream>
# include<string.h>
using namespace std;
class grammer
{
private:
int flag;//判别是NFA还是DFA的标识符
char K[50];//有穷非空状态集合
char E[50];//有穷非空的输入字母表
char str[50];//存放待识别的字符串
{ char temp=p[i][j]; //暂时存放一个确定的符号
if(temp>='A'&&temp<='Z')//非终结符号的判断条件
{
bool state=true;
for(int k=0;k<VN;k++)
{
if (temp==K[k]) //避免重复
{state=false;break;}
{ char temp=p[i][j]; //暂时存放一个确定的符号
if(!((temp>='A'&&temp<='Z')||temp==':'||temp=='='||temp=='\0'))
//终结符号的判断条件
{
bool state=true;
for(int k=0;k<VT;k++)
{
if (temp==E[k]) //避免重复
{cout<<ch[i][j];}
cout<<"}"<<endl;
}
}
void print()//输出五元组
{
Search_big();
cout<<"DFA N=({"<<"S"<<",";
for(int i=0;i<VN-1;i++)
{
cout<<K[i];
cout<<",";
}
cout<<K[VN-1];
char ch[20][20];//存放从K*E到K的映射
public:
char**p; //数组指针
int line; //确定行的位置
int m;//要识别的字符串长度
int VN;//控制非终结符号输出的变量
int VT;//控制终结符号输出的变量
int i,j;
grammer() //构造函数
cout<<"输入完成,输出有穷状态自动机(五元组):"<<endl;
cout<<endl;
a.print();//调用输出有穷状态自动机的五元组的函数
a.Identify();//识别是DFA还是NFA且输出其映射集合
cout<<endl<<endl;
cout<<"----------------------------------------\n";
cout<<",";
for(int q=0;q<length;q++)
{
cout<<str[q];//输出剩余字符串
}
cout<<")";
count++;
}
}
}
if(count==m)
{
cout<<"该文法可被识别!";
break;
}
else
{
cout<<"该文法不能被识别!";
break;
}
}
}
//输出映射集合
cout<<"运行有穷状态自动机!\n";
cout<<"----------------------------------------\n";
a.string();//输入要识别的字符串
cout<<"}"<<",";
zhongjie();
cout<<"{";
for(int j=0;j<VT-1;j++)