编译原理实验一:DFA的编程实现

实验一(一) 基于C语言的TINY编译器与TM虚拟机(1学时)

 

实验目的

初步认识编译器系统和目标机,体会系统编程,了解条件编译和增量编程。

 

实验任务

  1. 获取TINY语言编译器相关源代码。
  2. 了解TINY语言定义,可参见文档《TINY语言及其编译器实现》。第一次实验时对TINY语言有大致了解即可,后续实验中会陆续阅读更多TINY语言及其编译器的文档,详细了解其词法、语法、语义、运行时环境、目标机器、目标语言等内容,最终能编写出该语言的编译器。
  3. 生成和使用TINY语言的编译器。
  4. 大致了解TINY编译器源代码。

 

实验内容

  1. 生成TINY编译器
  2. 生成TM虚拟机
  3. 通过条件编译生成部分编译器
  4. 使用flex生成TINY编译器
  5. 使用bison生成TINY编译器

具体步骤详见tiny编译器的使用.ppt。

 

备注

1.实验资料

  1. TINY编译器及TM虚拟机源代码

下载loucom.ZIP并解压。

  1. FLEX和Bison程序

下载flexbison.zip并解压。

  1. 开发环境

兼容C的开发环境,如:VS或者DEV C++。

 

此部分实验学生自行完成,要求人人过关。

(一)不写实验报告,把心得体会写在实验一(二)的实验报告的心得体会部分。

 

实验建议

这个实验环境配置比较麻烦,当时做实验的时候见过很多人环境配置出错,甚至装了XP虚拟机的都有。。。建议使用VC++6.0版本建立工程,可以省去很多麻烦。

 

实验一(二)DFA的编程实现(3学时)

 

实验目的

通过本次实验,加深对DFA及其识别的语言的理解,学习对一般的DFA的表达方法与编程实现方法。

 

实验任务

编写一个C语言程序,模拟实现DFA识别字符串的过程。

 

实验内容

  1. DFA的输入;
  2. DFA的存储与读写;
  3. DFA的正确性检查;
  4. DFA的语言集列表显示;
  5. DFA的规则字符串判定;

 

内容说明:

(1)DFA的输入:

分别输入DFA的“字符集”、“状态集”、“开始状态”、“接受状态集”、“状态转换表”等内容,并保存在设定的变量中。

(2)DFA的存储与读写:

将上述DFA的五元组保存在一个文本文件中,扩展名指定为.dfa。请自行设计DFA文件的存储格式,并说明其含义。能将保存在内存变量中的DFA写入DFA文件,也能将DFA文件读入内存中。(思考:对稀疏DFA(转换表中为空的地方较多)或用“或”表达转换的DFA(如下的测试用例三),如何改进DFA转换表的表达。)

(3)DFA的正确性检查:

  1. 检查所有集合的元素的唯一性。
  2. 检查“开始状态”是否唯一,并是否包含在“状态集”中。
  3. 检查“接受状态集”是否为空,并是否包含在“状态集”中。
  4. 检查“状态转换表”是否满足DFA的要求。
  5. 检查“状态转换表”并非填满时的处理是否得当…

(4)DFA的语言集列表显示:

输入待显示的字符串的最大长度N,输出以上定义的DFA的语言集中长度≤N的所有规则字符串。(提示:注意算法中while循环的次数)

(5)DFA的规则字符串判定:

输入(或用字符集随机生成)一个字符串,模拟DFA识别字符串的过程判定该字符串是否是规则字符串(属于DFA的语言集)。

 

代码实现

#include
#include
#include
#include
#include
using namespace std;

struct TransitionDiagram   //状态转换图类 
{
	char cur,next,input;   //当前状态,下一状态,转换条件 
	TransitionDiagram(char c,char i,char n)   //构造函数 
	{
		cur=c;
		input=i;
		next=n;
	}
};

struct DFA_class   //DFA结构体 
{
	string state;   //状态集 
	string letter;   //字符集 
	string start_state;   //开始状态(实际使用时只取一个,也就是字符串的[0]位) 
	string end_state;   //接收状态集,可以多个 
	int count;   //符合条件的字符串个数 
	vectorTrans_Rule;   //转换规则数组,数组的类型是上面定义的class 
}DFA;   //一个对象 

int find_letter(char a,string s)   //从一个字符串s中查找是否有字符a 
{
	int len=s.length();
	for(int i=0;i>DFA.letter;
	}while(Check_letter(DFA.letter)==0);
	DFA.letter+='O';   //输入字符集之后,在字符集的最后加上一个O代表others 
	do{
		if(Check_letter(DFA.state)==0)
		cout<<"状态重复,请重新";
		cout<<"输入状态集:";
	    cin>>DFA.state;
	}while(Check_letter(DFA.state)==0);	
	
	do{
		if(find_start_state(DFA.start_state)==0 && flag==true || DFA.start_state.length()>1)
		cout<<"开始状态输入错误,请重新";
		cout<<"请输入开始状态:";
	    cin>>DFA.start_state;
	    flag=true;
	}while(find_start_state(DFA.start_state)==0 || DFA.start_state.length()>1);
	
	do{
		if(find_end_state(DFA.end_state)==0)
		cout<<"接受状态集输入错误,请重新";
		cout<<"请输入接受状态集:";
	    cin>>DFA.end_state;
	}while(find_end_state(DFA.end_state)==0);
	
	cout<<"请输入状态转换表,格式(1a2),O代表其他字符,输入星号‘*’停止:"<>Rule)
	{
		if(Rule[0]=='*')
		break;
		else if(Check_rule(Rule))
		DFA.Trans_Rule.push_back(TransitionDiagram(Rule[0],Rule[1],Rule[2]));
		else
		cout<<"转换表输入错误,请检查状态和字符是否在范围内。"<>DFA.letter>>DFA.state>>DFA.start_state>>DFA.end_state;
	DFA.letter+='O';
	while(!ff.eof())
	{
		ff>>tmp;
		DFA.Trans_Rule.push_back(TransitionDiagram(tmp[0],tmp[1],tmp[2]));
	}
	cout<<"文件读取完毕!"<>choice;
	if(choice==1)
	init_and_input();
	else
	read();
	write();
	cout<<"请输入一个整数,求满足DFA长度不大于该整数的所有字符串:";
	cin>>n;
	generate(DFA.start_state[0],n);
	cout<<"一共有上述"<>s;
	identify(s);
	return 0;
}

 

你可能感兴趣的:(编译原理实验)