编译原理上机题简单实现
2013-06-15 22:32
267 查看
一、实验目的
通过本实验使学生进一步熟悉和掌握程序设计语言的词法分析程序的设计原理及相关的设计技术,如何针对确定的有限状态自动机进行编程序;熟悉和掌握程序设计语言的语法分析程序的设计原理、熟悉和掌握算符优先分析方法。
二、实验要求
本实验要求:①要求能熟练使用C++程序设计语言编程;②在上机之前要有详细的设计报告(预习报告);③要编写出完成相应任务的程序并在计算机上准确地运行;④实验结束后要写出上机实验报告。
三、实验题目
针对下面文法G(S):
S→ v = E
E→E+E│E-E│E*E│E/E│(E)│ v │ i
其中,v为标识符,i为整型或实型数。
该文法为:G(Vn,Vt,P,S)
Vn={S,E}
Vt={v,i,+,-,*,/,(,),=}
P={S→v = E,
E→E+E,
E→E-E,
E→E*E,
E→E/E,
E→(E),
E→v,
E→i
}
要求完成
① 使用自动机技术实现一个词法分析程序;
② 使用算符优先分析方法实现其语法分析程序;
解答:①.算法思想:制造自动机状态,扫描输入的表达式字符串,每个状态对应若干字符,识别出状态,归纳出"单词"
自动机状态图:
代码:
#include<iostream>
using namespace std;
/*
编号规定:
001:加法运算符
002:减法运算符
003:乘法运算符
004:除法运算符
005:界符
008.标识符
010.整数
011.等号运算符
012.浮点数
error:错误字段
*/
void State11(int j);
void State1(int j);
void State2(int j);
void State3(int j);
void State4(int j);
void State5(int j);
void State6(int i,int j);
void State7(int i,int j);
void State8(int i,int j);
void State9(int i,int j);
void State10(int i,int j);
void State12(int i,int j);
char Code[10000];//存储“源代码 ”的字符数组 ,即词法分析的对象
bool IsDengHao(char ch)//判断是否是字符'='
{
if(ch=='=')
{
return true;
}
else
{
return false;
}
}
bool IsJiaHao(char ch)//判断是否是字符'+'
{
if(ch=='+')
{
return true;
}
else
{
return false;
}
}
bool IsJianHao(char ch)//判断是否是字符'-'
{
if(ch=='-')
{
return true;
}
else
{
return false;
}
}
bool IsChengHao(char ch)//判断是否是字符'*'
{
if(ch=='*')
{
return true;
}
else
{
return false;
}
}
bool IsChuHao(char ch)//判断是否是字符'-'
{
if(ch=='/')
{
return true;
}
else
{
return false;
}
}
bool IsJieFu(char ch)//判断是否是界符
{
if(ch=='('||ch==')')
{
return true;
}
else
{
return false;
}
}
void State0(int i,int j)//状态0,初始状态
{
if(Code[j]=='#')
{
return ;
}
if(IsDengHao(Code[j])==true)//如果当前字符是加号进入状态11
{
State11(j);
return ;
}
if(IsJiaHao(Code[j])==true)//如果当前字符是加号进入状态1
{
State1(j);
return ;
}
if(IsJianHao(Code[j])==true)//如果当前字符是减号进入状态2
{
State2(j);
return ;
}
if(IsChengHao(Code[j])==true)//如果当前字符是乘号进入状态3
{
State3(j);
return ;
}
if(IsChuHao(Code[j])==true)//如果当前字符是除号进入状态4
{
State4(j);
return ;
}
if(IsJieFu(Code[j])==true)//如果当前字符是界符进入状态5
{
State5(j);
return;
}
if(isalpha(Code[j])!=0)//直接调用系统函数isalpha判断字符是否为英文字母
{
State6(i,j+1);//是字母就进入状态6
return ;
}
if(isdigit(Code[j])!=0)//直接调用系统函数isdigit判断字符是否是数字
{
State7(i,j+1);//是数字就进入状态7
return ;
}
cout<<"(error,"<<Code[j]<<")" <<endl;
State0(i,j+1);
}
void State11(int j)//状态11,表示字符为等号运算符
{
cout<<"(011,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State1(int j)//状态1,表示字符为加法运算符
{
cout<<"(001,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State2(int j)//状态2,表示字符为减法运算符
{
cout<<"(002,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State3(int j)//状态3,表示字符为乘法运算符
{
cout<<"(003,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State4(int j)//状态4,表示字符为除法运算符
{
cout<<"(004,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State5(int j)//状态5,字符为界符
{
cout<<"(005,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State6(int i,int j)//状态6,准标识符
{
//Code[i]为准标识符的第一个字符,是个字母 ,而Code[j-1]是字母或数字
if(isdigit(Code[j])||isalpha(Code[j]))
//如果当前字符仍然为字母或数字则再次进入状态6
{
State6(i,j+1);
return;
}
else//如果当前字符为非数字及字母字符,则表明Code[i]~Code[j-1]这一段是标识符
{
/*cout<<"(008,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j,j);*/
State8(i,j);//进入状态8
}
}
void State7(int i,int j)//状态7,准实数
{
//Code[i]为准实数的第一个字符,是个字母 ,而Code[j-1]是数字或小数点
if(isdigit(Code[j])!=0)//如果当前字符仍然是数字,则再次进入状态7
{
State7(i,j+1);
return;
}
if(Code[j]=='.')//如果当前字符是小数点,进入状态9
{
State9(i,j+1);
return;
}
if((Code[j]!='.')&&(isdigit(Code[j])==0))
//如果当前字符既不为小数点也不是数字 ,则表明Code[i]~Code[j-1]这一段是个实数
{
/* cout<<"(010,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")"<<endl;
State0(j,j);*/
State10(i,j);//进入状态10
}
}
void State8(int i,int j)//状态8,标识符
{
cout<<"(008,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j,j);
}
void State9(int i,int j)//状态9,整数后接个小数点的中间态
{
//Code[i]~Code[j-1]之中含有小数点
if(Code[j]=='.')
/*若当前字符仍为小数点,则判断Code[i]~Code[j]这一段属于无效字段的一部分,
包括Code[j]后面直接连接的数字、小数点字符构成整个无效字段 */
{
cout<<"(error,";
int q=i;//从Code[i]开始算起
while((isdigit(Code[q])!=0)||(Code[q])=='.')
//直接相连的数字或小数点都属于这个无效字段的一部分
{
cout<<Code[q];
q++;
}
cout<<")" <<endl;
//Code[q]此时为无效字段的下一个字符
State0(q,q);
return;
/*for(int k=i;k<=j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j+1,j+1);*/
}
if(isdigit(Code[j])!=0)//如果当前字符是数字,则再次进入状态9
{
State9(i,j+1);
return;
}
if(isdigit(Code[j])==0)
//如果当前字符是非数字字符,说明Code[i]~Code[j-1]这一段是浮点数
{
State12(i,j);//进入终态12
}
}
void State10(int i,int j)//状态10,整数
{
cout<<"(010,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")"<<endl;
State0(j,j);
}
void State12(int i,int j)//状态12,浮点数
{
cout<<"(012,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j,j);
}
int main()
{
char code_char;
int n=0,m=0;
cout<<"请输入“源代码”(即字符串),(以#为结束符)"<<endl;
do{
code_char=getchar();
if(code_char=='#'&&n==0)
{
cout<<"源代码为空,无法进行词法分析!"<<endl;
getchar();
return 0;
}
if(code_char=='#')
{
cout<<" 词法分析开始!";
cout<<" .................."<<endl;
}
Code
= code_char;
n++;
}while(code_char!='#');
cout<<"词法分析结束,结果如下:" <<endl;
State0(0,0);
system("pause");
return 0;
}
运行测试:
通过本实验使学生进一步熟悉和掌握程序设计语言的词法分析程序的设计原理及相关的设计技术,如何针对确定的有限状态自动机进行编程序;熟悉和掌握程序设计语言的语法分析程序的设计原理、熟悉和掌握算符优先分析方法。
二、实验要求
本实验要求:①要求能熟练使用C++程序设计语言编程;②在上机之前要有详细的设计报告(预习报告);③要编写出完成相应任务的程序并在计算机上准确地运行;④实验结束后要写出上机实验报告。
三、实验题目
针对下面文法G(S):
S→ v = E
E→E+E│E-E│E*E│E/E│(E)│ v │ i
其中,v为标识符,i为整型或实型数。
该文法为:G(Vn,Vt,P,S)
Vn={S,E}
Vt={v,i,+,-,*,/,(,),=}
P={S→v = E,
E→E+E,
E→E-E,
E→E*E,
E→E/E,
E→(E),
E→v,
E→i
}
要求完成
① 使用自动机技术实现一个词法分析程序;
② 使用算符优先分析方法实现其语法分析程序;
解答:①.算法思想:制造自动机状态,扫描输入的表达式字符串,每个状态对应若干字符,识别出状态,归纳出"单词"
自动机状态图:
代码:
#include<iostream>
using namespace std;
/*
编号规定:
001:加法运算符
002:减法运算符
003:乘法运算符
004:除法运算符
005:界符
008.标识符
010.整数
011.等号运算符
012.浮点数
error:错误字段
*/
void State11(int j);
void State1(int j);
void State2(int j);
void State3(int j);
void State4(int j);
void State5(int j);
void State6(int i,int j);
void State7(int i,int j);
void State8(int i,int j);
void State9(int i,int j);
void State10(int i,int j);
void State12(int i,int j);
char Code[10000];//存储“源代码 ”的字符数组 ,即词法分析的对象
bool IsDengHao(char ch)//判断是否是字符'='
{
if(ch=='=')
{
return true;
}
else
{
return false;
}
}
bool IsJiaHao(char ch)//判断是否是字符'+'
{
if(ch=='+')
{
return true;
}
else
{
return false;
}
}
bool IsJianHao(char ch)//判断是否是字符'-'
{
if(ch=='-')
{
return true;
}
else
{
return false;
}
}
bool IsChengHao(char ch)//判断是否是字符'*'
{
if(ch=='*')
{
return true;
}
else
{
return false;
}
}
bool IsChuHao(char ch)//判断是否是字符'-'
{
if(ch=='/')
{
return true;
}
else
{
return false;
}
}
bool IsJieFu(char ch)//判断是否是界符
{
if(ch=='('||ch==')')
{
return true;
}
else
{
return false;
}
}
void State0(int i,int j)//状态0,初始状态
{
if(Code[j]=='#')
{
return ;
}
if(IsDengHao(Code[j])==true)//如果当前字符是加号进入状态11
{
State11(j);
return ;
}
if(IsJiaHao(Code[j])==true)//如果当前字符是加号进入状态1
{
State1(j);
return ;
}
if(IsJianHao(Code[j])==true)//如果当前字符是减号进入状态2
{
State2(j);
return ;
}
if(IsChengHao(Code[j])==true)//如果当前字符是乘号进入状态3
{
State3(j);
return ;
}
if(IsChuHao(Code[j])==true)//如果当前字符是除号进入状态4
{
State4(j);
return ;
}
if(IsJieFu(Code[j])==true)//如果当前字符是界符进入状态5
{
State5(j);
return;
}
if(isalpha(Code[j])!=0)//直接调用系统函数isalpha判断字符是否为英文字母
{
State6(i,j+1);//是字母就进入状态6
return ;
}
if(isdigit(Code[j])!=0)//直接调用系统函数isdigit判断字符是否是数字
{
State7(i,j+1);//是数字就进入状态7
return ;
}
cout<<"(error,"<<Code[j]<<")" <<endl;
State0(i,j+1);
}
void State11(int j)//状态11,表示字符为等号运算符
{
cout<<"(011,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State1(int j)//状态1,表示字符为加法运算符
{
cout<<"(001,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State2(int j)//状态2,表示字符为减法运算符
{
cout<<"(002,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State3(int j)//状态3,表示字符为乘法运算符
{
cout<<"(003,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State4(int j)//状态4,表示字符为除法运算符
{
cout<<"(004,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State5(int j)//状态5,字符为界符
{
cout<<"(005,"<<Code[j]<<")" <<endl;
State0(j+1,j+1);
}
void State6(int i,int j)//状态6,准标识符
{
//Code[i]为准标识符的第一个字符,是个字母 ,而Code[j-1]是字母或数字
if(isdigit(Code[j])||isalpha(Code[j]))
//如果当前字符仍然为字母或数字则再次进入状态6
{
State6(i,j+1);
return;
}
else//如果当前字符为非数字及字母字符,则表明Code[i]~Code[j-1]这一段是标识符
{
/*cout<<"(008,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j,j);*/
State8(i,j);//进入状态8
}
}
void State7(int i,int j)//状态7,准实数
{
//Code[i]为准实数的第一个字符,是个字母 ,而Code[j-1]是数字或小数点
if(isdigit(Code[j])!=0)//如果当前字符仍然是数字,则再次进入状态7
{
State7(i,j+1);
return;
}
if(Code[j]=='.')//如果当前字符是小数点,进入状态9
{
State9(i,j+1);
return;
}
if((Code[j]!='.')&&(isdigit(Code[j])==0))
//如果当前字符既不为小数点也不是数字 ,则表明Code[i]~Code[j-1]这一段是个实数
{
/* cout<<"(010,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")"<<endl;
State0(j,j);*/
State10(i,j);//进入状态10
}
}
void State8(int i,int j)//状态8,标识符
{
cout<<"(008,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j,j);
}
void State9(int i,int j)//状态9,整数后接个小数点的中间态
{
//Code[i]~Code[j-1]之中含有小数点
if(Code[j]=='.')
/*若当前字符仍为小数点,则判断Code[i]~Code[j]这一段属于无效字段的一部分,
包括Code[j]后面直接连接的数字、小数点字符构成整个无效字段 */
{
cout<<"(error,";
int q=i;//从Code[i]开始算起
while((isdigit(Code[q])!=0)||(Code[q])=='.')
//直接相连的数字或小数点都属于这个无效字段的一部分
{
cout<<Code[q];
q++;
}
cout<<")" <<endl;
//Code[q]此时为无效字段的下一个字符
State0(q,q);
return;
/*for(int k=i;k<=j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j+1,j+1);*/
}
if(isdigit(Code[j])!=0)//如果当前字符是数字,则再次进入状态9
{
State9(i,j+1);
return;
}
if(isdigit(Code[j])==0)
//如果当前字符是非数字字符,说明Code[i]~Code[j-1]这一段是浮点数
{
State12(i,j);//进入终态12
}
}
void State10(int i,int j)//状态10,整数
{
cout<<"(010,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")"<<endl;
State0(j,j);
}
void State12(int i,int j)//状态12,浮点数
{
cout<<"(012,";
for(int k=i;k<j;k++)
{
cout<<Code[k];
}
cout<<")" <<endl;
State0(j,j);
}
int main()
{
char code_char;
int n=0,m=0;
cout<<"请输入“源代码”(即字符串),(以#为结束符)"<<endl;
do{
code_char=getchar();
if(code_char=='#'&&n==0)
{
cout<<"源代码为空,无法进行词法分析!"<<endl;
getchar();
return 0;
}
if(code_char=='#')
{
cout<<" 词法分析开始!";
cout<<" .................."<<endl;
}
Code
= code_char;
n++;
}while(code_char!='#');
cout<<"词法分析结束,结果如下:" <<endl;
State0(0,0);
system("pause");
return 0;
}
运行测试:
相关文章推荐
- 编译原理上机题简单实现(二)
- 编译原理课设之简单编译器实现
- 编译原理课设之简单编译器实现
- [置顶] 编译原理---四则运算表达式的计算简单实现
- 深入浅出编译原理-5-一个简单语法分析器的C语言实现
- 编译原理—(从零开始)用flex、bison实现一个简单的计算器
- 编译原理 龙书 第二章 一个简单的算术式(+,-)翻译器实现
- 编译原理:用flex和bison实现一个简单的计算器
- 深入浅出编译原理-4-一个简单词法分析器的C语言实现
- 设计有穷自动机DFA实现C++简单程序的词法分析、扫描(编译原理实验) 推荐
- .NET 1.1中预编译ASP.NET页面实现原理浅析 [1] 自动预编译机制浅析
- 编译原理(九) LR(0)文法分析法(算法描述和C++代码实现)
- 多线程断点续传的原理及其简单实现
- 单点登录原理与简单实现
- 编译原理(七) 算符优先分析法(构造算符优先关系表算法及C++实现)
- 交叉编译实践-交叉编译原理与简单应用
- 编译原理简单介绍
- 智能指针原理,并实现一个简单的智能指针
- 栈的链表实现,以及编译原理中的括号匹配
- HashMap简单实现原理及遍历map的几种方式