编译原理上机题简单实现(二)
2013-06-15 23:55
411 查看
续上编译原理上机题简单实现:②使用算符优先分析方法实现其语法分析程序:
符号表:+ - * / ( ) = i v #
算符优先关系表:
表达式为:A1=1.2+3*(4-6/3)
句子串为:v=i+i*(i-i/i)
代码:
#include<iostream>
using namespace std;
int SuanFuYouXian(char ch);
int IsChT(char ch);
int GetCuChNo( char CuCh);
int GetTopChNo( char topCh);
int CuChIsYouXian(char cuch);
int FindNotEch();
//终结字符集合
char ChT[10]={'+','-','*','/','(',')','=','i','v','#'};
//优先算符表
char youxian[10][10]={
{'>','>','<','<','<','>','n','<','<','>'},
{'>','>','<','<','<','>','n','<','<','>'},
{'>','>','>','>','<','>','n','<','<','>'},
{'>','>','>','>','<','>','n','<','<','>'},
{'<','<','<','<','<','=','n','<','<','n'},
{'>','>','>','>','n','>','<','<','<','>'},
{'<','<','<','<','<','n','n','<','<','>'},
{'>','>','>','>','n','>','<','n','n','>'},
{'>','>','>','>','n','>','>','n','n','>'},
{'<','<','<','<','<','n','<','<','<','='}
};
//符号栈
int Stack[100];
int Top=0;//栈顶指针 ,始终指向最上面的符号的位置
void PrintStack()//输出栈内容
{
/*
int index=0;
do{
if(Stack[index]!=' ')
{
//printf("%c",Stack[index]);
cout<<Stack[index]<<" ";
}
index++;
}while(index<100);
printf("\n");
*/
for(int j=0;j<100;j++)
{
//cout<<Stack[j]<<" ";
cout.put(Stack[j]);
}
cout<<endl;
}
//判断是否为终结字符
int IsChT(char ch)
{
for(int i=0;i<10;i++)
{
if(ch==ChT[i])
{
return 1;//是某个终结字符时返回1
}
}
return 0;//不是终结字符时返回0
}
//查找当前的终结字符在优先表中的位置(行号)
int GetCuChNo( char CuCh)
{
for(int i=0;i<10;i++)
{
if(ChT[i]==CuCh)
{
return i;
}
}
return -1;//出错时返回-1
}
int GetTopChNo( char topCh)//查找栈顶符号在优先表中的位置(列号)
{
for(int i=0;i<10;i++)
{
if(ChT[i]==topCh)
{
return i;
}
}
return -1;//出错时返回-1
}
//判断当前字符与栈顶字符的优先级关系,当前字符优先于栈顶符号返回1,否则返回0
int CuChIsYouXian(char cuch)
{
int cuchNo= GetCuChNo(cuch);//找到当前字符在优先表中的行号
int topChNo =GetTopChNo(Stack[Top]);//找到栈顶字符在优先表中的列号
char youxianji=youxian[cuch][topChNo];//找到优先值
switch(youxianji)
{
case '>':return 1;break;
case '=': return 1;break;
case '<':return 0;break;
}
return -1;//出错时返回-1
}
int FindNotEch()//查找离栈顶最近的终结符位置
{
for(int m=Top;m>=0;m--)
{
if(Stack[m]!='E')
{
return m;
}
}
return -1;
}
int SuanFuYouXian(char ch)//算符优先算法语法分析函数
{
if(Stack[Top]==')')
{
int index=FindNotEch();
char notEch=Stack[index];
int NotEIndex=GetTopChNo(notEch);
int cuchIndex=GetCuChNo(ch);
if((youxian[NotEIndex][cuchIndex]=='=')||(youxian[NotEIndex][cuchIndex]=='<'))
{//移进
Top++;
Stack[Top]=ch;
PrintStack();
return 1;//移进使当前字符推进1
}
else
{//归约
Stack[Top]=' ';
Top-- ;
Stack[Top]=' ';
Top-- ;
Stack[Top]='E';
PrintStack();
int index=FindNotEch();
char notEch=Stack[index];
if(notEch=='#')
{
Stack[Top]='S';
PrintStack();
return 1;//接收,当前字符推进到结束位置
}
return 0;
}
}
else if(Stack[Top]=='E')
{
int index=FindNotEch();
char notEch=Stack[index];
int NotEIndex=GetTopChNo(notEch);
int cuchIndex=GetCuChNo(ch);
if((youxian[NotEIndex][cuchIndex]=='=')||(youxian[NotEIndex][cuchIndex]=='<'))
{//移进
Top++;
Stack[Top]=ch;
PrintStack();
return 1;
}
else
{//归约
Stack[Top]=' ';
Top-- ;
Stack[Top]=' ';
Top-- ;
Stack[Top]='E';
PrintStack();
int index=FindNotEch();
char notEch=Stack[index];
if(notEch=='#')
{
Stack[Top]='S';
PrintStack();
return 1;//接收,当前字符推进到结束位置
}
return 0;//普通归约当前字符位置不变
}
}
else
{
int topchIndex=GetTopChNo(Stack[Top]);
int cuchIndex=GetCuChNo(ch);
if((youxian[topchIndex][cuchIndex]=='=')||(youxian[topchIndex][cuchIndex]=='<'))
{//移进
Top++;
Stack[Top]=ch;
PrintStack();
return 1;
}
else//归约
{
Stack[Top]='E';
PrintStack();
return 0;
}
}
}
int main()
{
//表达式为A1=1.2+3*(4-6/3)
cout<<"表达式为:"<<"A1=1.2+3*(4-6/3)"<<endl;
string S="1.2+3*(4-6/3)";
double result=1.2+3*(4-6/3);
string ConStr[13]={"A1","=","1.2","+","3","*","(","4","-","6","/","3",")"};
char ConChs[14]={'v','=','i','+','i','*','(','i','-','i','/','i',')','#'};
cout<<"句子串为:"<<"v=i+i*(i-i/i)"<<endl;
//算符优先分析
cout<<"算符优先分析过程如下:"<<endl;
Stack[0]='#';//首先#压栈
int k=0;
while(k<14)
{
char c= ConChs[k];
int i=SuanFuYouXian(ConChs[k]);
k=k+i;
}
if(Stack[Top]=='S')
{
cout<<"语法分析通过!"<<endl;
cout<<"符号栈最终内容为:";
for(int j=0;j<100;j++)
{
//cout<<Stack[j]<<" ";
cout.put(Stack[j]);
}
printf("\n");
system("pause");
return 0;
}
else
{
cout<<"表达式有错,未通过语法分析!"<<endl;
for(int j=0;j<100;j++)
{
cout<<Stack[j]<<" ";
//cout.put(Stack[j]);
}
}
system("pause");
return 0;
}
测试结果:
符号表:+ - * / ( ) = i v #
算符优先关系表:
表达式为:A1=1.2+3*(4-6/3)
句子串为:v=i+i*(i-i/i)
代码:
#include<iostream>
using namespace std;
int SuanFuYouXian(char ch);
int IsChT(char ch);
int GetCuChNo( char CuCh);
int GetTopChNo( char topCh);
int CuChIsYouXian(char cuch);
int FindNotEch();
//终结字符集合
char ChT[10]={'+','-','*','/','(',')','=','i','v','#'};
//优先算符表
char youxian[10][10]={
{'>','>','<','<','<','>','n','<','<','>'},
{'>','>','<','<','<','>','n','<','<','>'},
{'>','>','>','>','<','>','n','<','<','>'},
{'>','>','>','>','<','>','n','<','<','>'},
{'<','<','<','<','<','=','n','<','<','n'},
{'>','>','>','>','n','>','<','<','<','>'},
{'<','<','<','<','<','n','n','<','<','>'},
{'>','>','>','>','n','>','<','n','n','>'},
{'>','>','>','>','n','>','>','n','n','>'},
{'<','<','<','<','<','n','<','<','<','='}
};
//符号栈
int Stack[100];
int Top=0;//栈顶指针 ,始终指向最上面的符号的位置
void PrintStack()//输出栈内容
{
/*
int index=0;
do{
if(Stack[index]!=' ')
{
//printf("%c",Stack[index]);
cout<<Stack[index]<<" ";
}
index++;
}while(index<100);
printf("\n");
*/
for(int j=0;j<100;j++)
{
//cout<<Stack[j]<<" ";
cout.put(Stack[j]);
}
cout<<endl;
}
//判断是否为终结字符
int IsChT(char ch)
{
for(int i=0;i<10;i++)
{
if(ch==ChT[i])
{
return 1;//是某个终结字符时返回1
}
}
return 0;//不是终结字符时返回0
}
//查找当前的终结字符在优先表中的位置(行号)
int GetCuChNo( char CuCh)
{
for(int i=0;i<10;i++)
{
if(ChT[i]==CuCh)
{
return i;
}
}
return -1;//出错时返回-1
}
int GetTopChNo( char topCh)//查找栈顶符号在优先表中的位置(列号)
{
for(int i=0;i<10;i++)
{
if(ChT[i]==topCh)
{
return i;
}
}
return -1;//出错时返回-1
}
//判断当前字符与栈顶字符的优先级关系,当前字符优先于栈顶符号返回1,否则返回0
int CuChIsYouXian(char cuch)
{
int cuchNo= GetCuChNo(cuch);//找到当前字符在优先表中的行号
int topChNo =GetTopChNo(Stack[Top]);//找到栈顶字符在优先表中的列号
char youxianji=youxian[cuch][topChNo];//找到优先值
switch(youxianji)
{
case '>':return 1;break;
case '=': return 1;break;
case '<':return 0;break;
}
return -1;//出错时返回-1
}
int FindNotEch()//查找离栈顶最近的终结符位置
{
for(int m=Top;m>=0;m--)
{
if(Stack[m]!='E')
{
return m;
}
}
return -1;
}
int SuanFuYouXian(char ch)//算符优先算法语法分析函数
{
if(Stack[Top]==')')
{
int index=FindNotEch();
char notEch=Stack[index];
int NotEIndex=GetTopChNo(notEch);
int cuchIndex=GetCuChNo(ch);
if((youxian[NotEIndex][cuchIndex]=='=')||(youxian[NotEIndex][cuchIndex]=='<'))
{//移进
Top++;
Stack[Top]=ch;
PrintStack();
return 1;//移进使当前字符推进1
}
else
{//归约
Stack[Top]=' ';
Top-- ;
Stack[Top]=' ';
Top-- ;
Stack[Top]='E';
PrintStack();
int index=FindNotEch();
char notEch=Stack[index];
if(notEch=='#')
{
Stack[Top]='S';
PrintStack();
return 1;//接收,当前字符推进到结束位置
}
return 0;
}
}
else if(Stack[Top]=='E')
{
int index=FindNotEch();
char notEch=Stack[index];
int NotEIndex=GetTopChNo(notEch);
int cuchIndex=GetCuChNo(ch);
if((youxian[NotEIndex][cuchIndex]=='=')||(youxian[NotEIndex][cuchIndex]=='<'))
{//移进
Top++;
Stack[Top]=ch;
PrintStack();
return 1;
}
else
{//归约
Stack[Top]=' ';
Top-- ;
Stack[Top]=' ';
Top-- ;
Stack[Top]='E';
PrintStack();
int index=FindNotEch();
char notEch=Stack[index];
if(notEch=='#')
{
Stack[Top]='S';
PrintStack();
return 1;//接收,当前字符推进到结束位置
}
return 0;//普通归约当前字符位置不变
}
}
else
{
int topchIndex=GetTopChNo(Stack[Top]);
int cuchIndex=GetCuChNo(ch);
if((youxian[topchIndex][cuchIndex]=='=')||(youxian[topchIndex][cuchIndex]=='<'))
{//移进
Top++;
Stack[Top]=ch;
PrintStack();
return 1;
}
else//归约
{
Stack[Top]='E';
PrintStack();
return 0;
}
}
}
int main()
{
//表达式为A1=1.2+3*(4-6/3)
cout<<"表达式为:"<<"A1=1.2+3*(4-6/3)"<<endl;
string S="1.2+3*(4-6/3)";
double result=1.2+3*(4-6/3);
string ConStr[13]={"A1","=","1.2","+","3","*","(","4","-","6","/","3",")"};
char ConChs[14]={'v','=','i','+','i','*','(','i','-','i','/','i',')','#'};
cout<<"句子串为:"<<"v=i+i*(i-i/i)"<<endl;
//算符优先分析
cout<<"算符优先分析过程如下:"<<endl;
Stack[0]='#';//首先#压栈
int k=0;
while(k<14)
{
char c= ConChs[k];
int i=SuanFuYouXian(ConChs[k]);
k=k+i;
}
if(Stack[Top]=='S')
{
cout<<"语法分析通过!"<<endl;
cout<<"符号栈最终内容为:";
for(int j=0;j<100;j++)
{
//cout<<Stack[j]<<" ";
cout.put(Stack[j]);
}
printf("\n");
system("pause");
return 0;
}
else
{
cout<<"表达式有错,未通过语法分析!"<<endl;
for(int j=0;j<100;j++)
{
cout<<Stack[j]<<" ";
//cout.put(Stack[j]);
}
}
system("pause");
return 0;
}
测试结果:
相关文章推荐
- 编译原理上机题简单实现
- 编译原理:用flex和bison实现一个简单的计算器
- 深入浅出编译原理-4-一个简单词法分析器的C语言实现
- 编译原理课设之简单编译器实现
- 设计有穷自动机DFA实现C++简单程序的词法分析、扫描(编译原理实验) 推荐
- 编译原理课设之简单编译器实现
- [置顶] 编译原理---四则运算表达式的计算简单实现
- 深入浅出编译原理-5-一个简单语法分析器的C语言实现
- 编译原理—(从零开始)用flex、bison实现一个简单的计算器
- 编译原理 龙书 第二章 一个简单的算术式(+,-)翻译器实现
- Skinned Mesh 原理解析和一个最简单的实现示例 作者:n5 Email: happyfirecn##yahoo.com.cn Blog: http://blog.csdn.net/n5
- hrtimer的简单使用 + 原理和实现
- Linux 邮件服务器原理介绍,编译安装Postfix实现本地的邮件服务。
- 单点登录原理与简单实现
- Dubbo原理解析-Dubbo内核实现之动态编译
- 双缓冲技术绘图原理及简单的VC实现
- 简单线性迭代聚类SLIC的原理及opencv实现
- 【编译原理】LL(1)文法分析全过程(FIRST/FLLOW/SELECT集等)实现(c++语言)
- 编译原理:用bison实现huiwen.y和huiwen.lex判断是否为回文
- VS2005 Web项目安装部署:利用预编译的Dll 隐藏.cs文件 的简单实现