📄 赋值语句.cpp
字号:
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
#define MAXSIZE 100 //定义栈的大小
#define N -2
typedef char datatype; //以char作为栈中元素
typedef struct //定义一个栈结构
{
datatype data[MAXSIZE];
int top;
}stack;
stack OPR; //操作数栈OPR
stack OPT; //操作符栈OPT
char *p; //全局变量指针,用来指向待分析字符串
//int count=1;
int matr[20][20]={
{N,-1,-1,-1,-1,N,1}, //算符优先矩阵
{N,1,-1,-1,-1,1,1},
{N,1,1,-1,-1,1,1},
{1,1,1,N,N,1,1},
{N,-1,-1,-1,-1,0,N},
{N,1,1,N,N,1,1},
{-1,N,N,-1,N,N,0}
};
/*算符优先关系距阵
//-1表示对应的行元素的优先级低于对应的列元素的优先级
//0表示对应的行元素的优先级等于对应的列元素的优先级
//1表示对应的行元素的优先级高于对应的列元素的优先级
//N表示对应的行元素与列元素不存在优先关系
= + * i ( ) $
= < < < < >
+ > < < < > >
* > > < < > >
i > > > > >
( < < < < =
) > > > >
$ < < =
*/
int row,line; //全局变量,分别来表示算符优先矩阵的行和列
int compare(char m,char n){ //算符的优先级
switch(m){
case '=':row=0;break;
case '+':row=1;break;
case '*':row=2;break;
case 'i':row=3;break;
case '(':row=4;break;
case ')':row=5;break;
case '$':row=6;break;
default: return -10;break;
}
switch(n){
case '=':line=0;break;
case '+':line=1;break;
case '*':line=2;break;
case 'i':line=3;break;
case '(':line=4;break;
case ')':line=5;break;
case '$':line=6;break;
default: return -10;break;
}
return matr[row][line];
}
//定义对操作数栈的基本操作
void OPRsetNull() //设置操作数栈空
{
OPR.top=-1;
}
bool OPRempty() //判断操作数栈是否为空
{
if(OPR.top>=0)
return false;
else
return true;
}
void OPRpush(char x) //往操作数栈push一个操作数i
{
if(OPR.top==MAXSIZE-1)
cout<<"栈产生上溢!"<<endl;
else {
OPR.top++;
OPR.data[OPR.top]=x;
}
}
datatype OPRpop() //从操作数栈中pop出一个操作数
{
if(OPRempty())
{
cout<<"栈产生下溢!"<<endl;
//return NULL;
}
else
{
OPR.top--;
return(OPR.data[OPR.top+1]);
}
}
//定义对操作数栈的基本操作结束
datatype OPRtop() //获取操作数栈的栈顶的操作数
{
if(OPRempty())
{
cout<<"栈产生下溢!"<<endl;
//return NULL;
}
else
return(OPR.data[OPR.top]);
}
void OPTsetNull() //设置操作符栈空
{
OPT.top=-1;
}
bool OPTempty() //判断操作符栈是否为空
{
if(OPT.top>=0)
return false;
else
return true;
}
void OPTpush(char x) //往操作符栈push一个操作数
{
if(OPT.top==MAXSIZE-1)
cout<<"栈产生上溢!"<<endl;
else
{
OPT.top++;
OPT.data[OPT.top]=x;
}
}
datatype OPTpop() //从操作数符中pop出一个操作数
{
if(OPTempty())
{
cout<<"栈产生下溢!"<<endl;
//return NULL;
}
else
{
OPT.top--;
return(OPT.data[OPT.top+1]);
}
}
datatype OPTtop() //获取操作符栈的栈顶的操作数
{
if(OPTempty())
{
cout<<"栈产生下溢!"<<endl;
//return NULL;
}
else return(OPT.data[OPT.top]);
}
//定义对操作符栈的基本操作结束
void OUTPUT(char opt,char op1,char op2,int num) //输出四元式
{
//if(op1=='i'&&op2=='i') cout<<(opt,op1,op2,num);
//if(op1!='i'&&op2=='i') cout<<(opt,op1,op2,num);
//if(op2!='i'&&op1=='i') cout<<(opt,op1,op2,num);
//if(op1!='i'&&op2!='i') cout<<(opt,op1,op2,num);
if(op1=='i'&&op2=='i') printf("(%c,%c,%c,t%d)\n",opt,op1,op2,num);
if(op1!='i'&&op2=='i') printf("(%c,t%d,%c,t%d)\n",opt,op1,op2,num);
if(op2!='i'&&op1=='i') printf("(%c,%c,t%d,t%d)\n",opt,op1,op2,num);
if(op1!='i'&&op2!='i') printf("(%c,t%d,t%d,t%d)\n",opt,op1,op2,num);
}
void scan()//扫描语法分析程序
{
int count=1;
char opt;
char op1,op2;
if(*p=='$') OPTpush(*p);//将待分析的字符串的首字符$压栈
p++;
while(*p!='$')//循环直到待分析字符串尾
{
if(*p=='i') OPRpush(*p);//如果当前字符是操作数则入栈,只有i一种操作数
else {
opt=OPTtop();
//否则是操作符与操作符栈顶的字符比较优先级
P: switch(compare(opt,*p)){
case -1: OPTpush(*p); break;
//如果栈顶操作符优先级下,则将当前字符压栈
case N: break;
//若无优先级 则说明待分析字符有误,不合语法规范
//出现语法错误
case 0: OPTpop(); break;
//若操作符优先级相等则说明栈顶
//符合当前操作符分别是左右括号
//将栈顶的左括号出栈即可
case 1: op1=OPRpop();
//若栈顶操作符优先级高,则将操作符栈最上两个操作数出栈
op2=OPRpop();
OUTPUT(opt,op1,op2,count);//输出四元式
OPRpush(count); //并将生成的t的序数压栈(t1,t2等);
count++;
opt=OPTpop();//将已规约的输出的操作符出栈
opt=OPTtop();//取栈顶操作符跳转到继续下一步。
goto P; break;
}
}
p++;
}
while(!OPTempty()&&!OPRempty()&&(OPTtop()!='$')){
//这里用来处理当p指向待分析字符串最后一个字符$时
//但是操作符和操作数栈中依然有字符的情况
op1=OPRpop();
op2=OPRpop(); //这种情况一般是栈底操作符优先级低于其上的操作符
opt=OPTpop(); //所以只要从上往下直接规约和输出四元式
if(opt!='='){ //在这里判断是否到'='来改换一个输出方式
OUTPUT(opt,op1,op2,count);
OPRpush(char(count));
count++;
}
if(opt=='=') cout<<(opt,count-1)<<endl;
}
}
ifstream& open_file(ifstream &in, const string &file)
{
in.close();
in.clear();
in.open(file.c_str());
return in;
}
int main(int argc,char **argv)
{
//char ch1;
//string str1;
OPRsetNull();
OPTsetNull();
//ifstream infile;
//if(argc<2||!open_file(infile,argv[1])){
// cerr<<"No input file!"<<endl;
// return EXIT_FAILURE;
// }
//while(infile)
//{
//infile.get(ch1);
//if(ch1=='\n')
//str1+=ch1;
// }
//infile.close();
//char ch[]="str1";
//p=ch;
//p++;
//int d;
//OPRsetNull();//操作数栈清空
//OPTsetNull();//操作数栈清空
char ch[]="$i=i+(i*i)$";//赋值语句
p=ch;
scan();//扫描分析输出
system("pause");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -