概述
http://blog.csdn.net/xuzengqiang/article/details/7596357
这是源地址,个人并没有做太大改动,于是就不写原创。
写编译原理实验的时候,当写到
- Expression->Term|Expression+Term|Expression-Term
- Term->Factor|Term*Factor|Term/Factor
- Factor->(Expression)| number
这里原作者进行了语法改动。
- E->TE2
- E2->+TE2 | -TE2 | ε
- T->*FT2
- T2->*FT2 | /FT2 |ε
- F->(E) | i
版本1:
原作者的编码我只是进行了小的改动能识别多位数
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
char expr[1010];
int start=0;
string T();
string T2();
string F();
string E2();
string F2();
string E()
{ string a=T(),b=E2();
return a+b;
}
string E2()
{ string a,b;
switch(expr[start])
{ case '+':start++;a=T();b=E2();return a+"+"+b;
case '-':start++;a=T();b=E2();return a+"-"+b;
default:return "";
}
}
string T()
{ string a=F(),b=T2();
return a+b;
}
string T2()
{ string a,b;
switch(expr[start])
{ case '*':start++;a=F();b=T2();return a+"*"+b;
case '/':start++;a=F();b=T2();return a+"/"+b;
default:return "";
}
}
string F()
{ if(expr[start]=='(')
{ string a;
start++;a=E();start++;
return a;
}
return F2();
}
int min(int a,int b)
{
if(a<b)
return a;
return b;
}
string F2()
{
string ans;
for(int i=start;i<strlen(expr);i++)
{
if(expr[i]=='*'||expr[i]=='-'||expr[i]=='+'||expr[i]=='/'||expr[i]==')')
{
start=i;
return ans;
}
else
{
char *p=&expr[i];
ans.append(p,1);
}
}
return ans;
}
int main()
{ scanf("%s",expr);
start=0;
cout<<E()<<endl;
}
然后是版本2:
- Expression->Term|Expression+Term|Expression-Term
- Term->Factor|Term*Factor|Term/Factor
- Factor->(Expression)| number |id
- Define->(int|float|num) id=num
最终实验我们要计算出值,于是我进行了一次比较大的改动,先识别是否有Define,将定义名称保存在string name[]中,定义的实际值保存在double num[]中。如果没有实际值,bool flag[]则为0。然后对后缀表达式中所有数字和id用加#来分隔。然后根据后缀表达式计算出结果。(马上考四级了,还没过啊)!!!!!
#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
string name[100];
bool flag[100];
double num[100];
char expr[1010];
int id=0;
int start=0;
string T();
string T2();
string F();
string E2();
string F2();
string E()
{ string a=T(),b=E2();
return a+b;
}
string E2()
{ string a,b;
switch(expr[start])
{ case '+':start++;a=T();b=E2();return a+"+"+b;
case '-':start++;a=T();b=E2();return a+"-"+b;
default:return "";
}
}
string T()
{ string a=F(),b=T2();
return a+b;
}
string T2()
{ string a,b;
switch(expr[start])
{ case '*':start++;a=F();b=T2();return a+"*"+b;
case '/':start++;a=F();b=T2();return a+"/"+b;
default:return "";
}
}
string F()
{ if(expr[start]=='(')
{ string a;
start++;a=E();start++;
return a;
}
return F2();
}
int min(int a,int b)
{
if(a<b)
return a;
return b;
}
string F2()
{
string ans="#";
for(int i=start;i<strlen(expr);i++)
{
if(expr[i]=='*'||expr[i]=='-'||expr[i]=='+'||expr[i]=='/'||expr[i]==')')
{
start=i;
return ans;
}
else
{
char *p=&expr[i];
ans.append(p,1);
}
}
return ans;
}
double stringtodouble(string tmp)
{
double d=0;
double k=10;
bool fa=0;
for(int i=0;i<tmp.length();i++)
{
if(!fa)
{
if(tmp[i]!='.')
d=d*10+(int)(tmp[i]-'0');
else fa=1;
}
else
{
d+=((int)(tmp[i]-'0'))/k;
k*=10;
}
}
return d;
}
void gtmdbyyl2(string tmp)
{
if(tmp.find("=")!=string::npos)
{
string na=tmp.substr(0,tmp.find("="));
string va=tmp.substr(tmp.find("=")+1);
name[id]=na;
num[id]=stringtodouble(va);
flag[id]=1;
}
else
{
name[id]=tmp;
flag[id]=0;
}
id++;
}
void gtmdbyyl(string tmp)
{
while(tmp.find(",")!=string::npos)
{
gtmdbyyl2(tmp.substr(0,tmp.find(",")));
tmp=tmp.substr(tmp.find(",")+1);
}
if(tmp.find(";")!=string::npos)
{
gtmdbyyl2(tmp.substr(0,tmp.length()-1));
}
else
gtmdbyyl2(tmp);
}
int findname(string tmp)//-1代表没有 -2代表没有值
{
for(int i=0;i<id;i++)
{
if(tmp==name[i])//别问我为什么不用运算符重载,我用了不对,我也不知道为什么。
{
if(flag[i]==1)
return i;
else
return -2;
}
}
return -1;
}
bool isnum(string tmp)
{
bool fa=0;
for(int i=0;i<tmp.length();i++)
{
if(tmp[i]=='.'&&!fa)
fa=1;
else if(tmp[i]>='0'&&tmp[i]<'9')
continue;
else return false;
}
return true;
}
void ans()
{
string key=E();
//cout<<key<<endl;
stack<double> va;
string c="";
for(int i=1;i<key.length();i++)
{
if(key[i]!='*'&&key[i]!='/'&&key[i]!='+'&&key[i]!='-'&&key[i]!='#')
{
char *p=&key[i];
c.append(p,1);
if(i==key.length()-1)
{
if(isnum(c))
{
va.push(stringtodouble(c));
c.clear();
}
else
{
int ans=findname(c);
if(ans==-1)
{
cout<<"error"<<endl;
exit(0);
}
else if (ans==-2)
{
cout<<"error"<<endl;
exit(0);
}
else
va.push(num[ans]);
}
}
}
else
{
if(c!="")
{
if(isnum(c))
{
va.push(stringtodouble(c));
c.clear();
}
else
{
int ans=findname(c);
if(ans==-1)
{
cout<<"error"<<endl;
return;
}
else if (ans==-2)
{
cout<<"error"<<endl;
return;
}
else
va.push(num[ans]);
c.clear();
}
}
if(key[i]=='*')
{
if(va.size()>=2){
double x=va.top();va.pop();double y=va.top();va.pop();va.push(x*y);}
else{
cout<<"error"<<endl;return;}
}
else if(key[i]=='/')
{
if(va.size()>=2){
double x=va.top();va.pop();double y=va.top();va.pop();va.push(x/y);}
else{
cout<<"error"<<endl;return;}
}
else if(key[i]=='+')
{
if(va.size()>=2){double x=va.top();va.pop();double y=va.top();va.pop();va.push(x+y);}
else if(va.size()==0){cout<<"error"<<endl;return;}
}
else if(key[i]=='-')
{
if(va.size()>=2)
{double x=va.top();va.pop();double y=va.top();va.pop();va.push(x-y);}
else if(va.size()==0)
{cout<<"error"<<endl;return;}
else{
double x=va.top();x=-x;va.pop();va.push(x);
}
}
}
}
cout<<"输出:n"<<va.top()<<endl;
}
bool input(string tmp)
{
if((tmp.substr(0,3)=="int")&&(tmp[3]==' '))
{
gtmdbyyl(tmp.substr(4));
}
else if((tmp.substr(0,6)=="double")&&(tmp[6]==' '))
{
gtmdbyyl(tmp.substr(7));
}
else if((tmp.substr(0,5)=="float")&&(tmp[5]==' '))
{
gtmdbyyl(tmp.substr(6));
}
else
{
strcpy(expr,tmp.c_str());
ans();
return false;
}
return true;
}
int main()
{
string c;
freopen("in.txt","r",stdin);
cout<<"输入:"<<endl;
while(getline(cin,c))
{
//cout<<c<<endl;
//getchar();
if(!input(c))
{
cout<<"输入continue回车继续测试,输入end结束测试"<<endl;
//getchar();
}
else
continue;
string key;
cin>>key;
//cout<<key<<endl;
if(key=="continue")
{
id=0;
start=0;
memset(expr,'