首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

编译原理中表达式求值,是用栈还是用二叉树?该怎么处理

2012-05-13 
编译原理中表达式求值,是用栈还是用二叉树?如题,有点忘记了。依稀记得是用逆波兰式然后用两个栈,一个保存操

编译原理中表达式求值,是用栈还是用二叉树?
如题,有点忘记了。
依稀记得是用逆波兰式然后用两个栈,一个保存操作符一个保存操作数。但是好像在ANTLR这种工具中是先变成语法树?
是直接扫描表达式的时候就改成逆波兰式压栈完全不用语法树?
还是先生成语法树然后后序遍历获得逆波兰式?

[解决办法]
用栈用数就可以解决。
[解决办法]
逆波兰
[解决办法]
不管是RR文法还是LR文法,都是用栈实现吧,只不过逻辑上是一棵树
[解决办法]
栈模拟 或 表达式树
[解决办法]
中缀到后缀

C/C++ code
#include<iostream>#include<string>#include<map>#include<utility>#include<stack>using namespace std;map<char,int> ope;int getNumber(const string& str,int& pos){    int val=0;    int l=str.length();    while(pos<l&&str[pos]<='9'&&str[pos]>='0'){        val*=10;        val+=str[pos]-'0';        ++pos;    }    return val;}int calculator(const string& str){    stack<char> sta_ope;    string postfix="";    int pos=0,l=str.length();    bool isNumber=(str[0]>='0'&&str[0]<='9'?true:false);    while(pos<l){        switch(str[pos]){        case '(':            sta_ope.push('(');            isNumber=false;            break;        case ')':            while(sta_ope.top()!='('){                postfix+=" ";                postfix+=sta_ope.top();                sta_ope.pop();            }            sta_ope.pop();            isNumber=false;            break;        case '+':        case '-':        case '*':        case '/':            while(!sta_ope.empty()&&sta_ope.top()!='('&&ope[sta_ope.top()]>=ope[str[pos]]){                postfix+=" ";                postfix+=sta_ope.top();                sta_ope.pop();            }            sta_ope.push(str[pos]);            isNumber=false;            break;        default:            if(str[pos]>='0'&&str[pos]<='9'){                if(!isNumber)                    postfix+=" ";                postfix+=str[pos];                isNumber=true;            }            else return -1;        }        ++pos;    }    while(!sta_ope.empty()){        postfix+=" ";        postfix+=sta_ope.top();        sta_ope.pop();    }    stack<int> sta_num;    pos=0,l=postfix.length();    int a,b;    while(pos<l){        switch(postfix[pos]){        case '+':            a=sta_num.top();            sta_num.pop();            b=sta_num.top();            sta_num.pop();            sta_num.push(b+a);            break;        case '-':            a=sta_num.top();            sta_num.pop();            b=sta_num.top();            sta_num.pop();            sta_num.push(b-a);            break;        case '*':            a=sta_num.top();            sta_num.pop();            b=sta_num.top();            sta_num.pop();            sta_num.push(b*a);            break;        case '/':            a=sta_num.top();            if(a==0)return -1;            sta_num.pop();            b=sta_num.top();            sta_num.pop();            sta_num.push(b/a);            break;        case ' ':            break;        default:            int n=getNumber(postfix,pos);            sta_num.push(n);        }        ++pos;    }    return sta_num.top();}int main(){    ope.insert(make_pair('+',1));    ope.insert(make_pair('-',1));    ope.insert(make_pair('*',2));    ope.insert(make_pair('/',2));    ope.insert(make_pair('(',3));    string str="(12-(2/(2/2)+2*4))/2-10";    cout<<calculator(str)<<endl;    return 0;}
[解决办法]
C/C++ code

/*表达树形式,只不过树用的数组形式表示*/#include<iostream>#include<cstring>using namespace std;const int MAX=1000;int lchild[MAX],rchild[MAX];char ope[MAX];int data[MAX];int count=0;bool isPureData(const string& str,int from,int to,int& data){    data=0;    for(int i=from;i<to&&str[i]<='9'&&str[i]>='0';++i){        data*=10;        data+=str[i]-'0';    }    return i==to;}int build_tree(const string& str,int from,int to){    int p=0,f1=-1,f2=-1;    int da;    if(isPureData(str,from,to,da)){        int n=count++;        lchild[n]=-1,rchild[n]=-1;        data[n]=da;        return n;    }    int t=from;    while(t<to){        switch(str[t]){        case '(':            --p;            break;        case ')':            ++p;            break;        case '+':        case '-':            if(!p)f1=t;            break;        case '*':        case '/':            if(!p)f2=t;            break;        }        ++t;    }    if(f1<0)f1=f2;    if(f1<0) return build_tree(str,from+1,to-1);//( )    int lch=build_tree(str,from,f1);    int rch=build_tree(str,f1+1,to);    int n=count++;    lchild[n]=lch;    rchild[n]=rch;    ope[n]=str[f1];    return n;}int val(int pos){    if(lchild[pos]==-1) return data[pos];    int a=val(lchild[pos]);    int b=val(rchild[pos]);    switch(ope[pos]){    case '+':        return a+b;        break;    case '-':        return a-b;        break;    case '*':        return a*b;        break;    case '/':        if(b==0)return -1;        return a/b;        break;    }}int calculator(const string& str,int l){    count=0;    build_tree(str,0,l);    return val(count-1);}int main(){    string str="(12-(2/(2/2)+2*4))/2-10";    cout<<calculator(str,str.length())<<endl;    return 0;}
[解决办法]
和语法结合就应该加到语法树里面。 这样遍历时直接就可以知道求值顺序了

如果是纯表达式,编译时可求出的用栈肯定简单些。

热点排行