上一个计算器有bug,还是用语法制导的方法计算表达式,这个没有bug,用的是LL(1)表达式文法,以=号结束

pointer计数指针

pointer.h

#ifndef _pointer_h
#define _pointer_h
template<class T>  
class pointer  
{  
public:  
    pointer():ptr(NULL),pCnt(new int(0)){} 
    pointer(T* src):ptr(src),pCnt(new int(1))  
    {  
    }  
    pointer(const pointer<T>& src):ptr(src.ptr),pCnt(src.pCnt)  
    {  
        ++(*pCnt);  
    }  
    pointer<T>& operator=(const pointer<T>& rhs)  
    {  
        if(ptr != rhs.ptr)  
        {  
            Release();  
            ptr = rhs.ptr;  
            pCnt = rhs.pCnt;  
            ++*pCnt;  
        }  
        return (*this);  
    }  
    T* operator->()  
    {  
        return ptr;  
    }  
    const T* operator->()const  
    {  
        return ptr;  
    }  
    T& operator*()  
    {  
        return (*ptr);  
    }  
    const T& operator*()const  
    {  
        return (*ptr);  
    }  
    ~pointer()  
    {  
        Release();  
    }  
public:  
    T* ptr;  
    int *pCnt;  
    void Release()  
    {  
        if(--*pCnt == 0)  
        {  
            delete ptr;  
            delete pCnt;  
        }  
    }  
};  
#endif 

表达式节点有两种,符号节点和数字节点

express_node.h

#ifndef _express_node_h
#define _express_node_h 
#include<iostream>
using std::cout; 
class node{
public:
    node(){}
    virtual float getNum(){return -1;} 
    virtual char getChar(){return '#';} 
    virtual ~node(){
        //cout<<"~node\n";
        //system("pause");
    } 
};    
class char_node:public node{
    char sym;
public:
    char_node(char c):sym(c){}
    void setChar(char c){sym=c;}
    virtual char getChar(){return sym;}
    virtual ~char_node(){
        //cout<<"~char_node\n";
        //system("pause");
    }
};    
class num_node:public node{
    float num;
public:
    num_node(float n):num(n){}
    void setNum(float n){num=n;}
    virtual float getNum(){return num;}
    virtual ~num_node(){
        //cout<<"~num_node\n";
        //system("pause");
    }
};  
#endif 

主函数

main.cpp

#include<vector>
#include<memory> 
#include<stack> 
#include<iostream> 
#include"express_node.h"
#include"pointer.h" 
using namespace std;

void E();
void Ts();
void T();
void Ps();
void P();
 
void error(){
    cout<<"语法错误\n"<<endl;system("pause");exit(1); 
} 

bool isNum(pointer<node> a){
    return dynamic_cast<num_node*>(&(*a))!=NULL;
}  
bool isChar(pointer<node> a){
    return dynamic_cast<char_node*>(&(*a))!=NULL; 
} 

void print1(node* a){
    if(dynamic_cast<char_node*>(a)!=NULL){
        cout<<dynamic_cast<char_node*>(a)->getChar()<<endl;
    }    
    else{
        cout<<dynamic_cast<num_node*>(a)->getNum()<<endl;
    }    
}  
void print2(node& a){
    if(dynamic_cast<char_node*>(&a)!=NULL){
        cout<<dynamic_cast<char_node*>(&a)->getChar()<<endl;
    }    
    else{
        cout<<dynamic_cast<num_node*>(&a)->getNum()<<endl;
    }    
}   
void print4(pointer<node>& a){
    if(dynamic_cast<char_node*>(&(*a))!=NULL){
        cout<<dynamic_cast<char_node*>(&(*a))->getChar()<<endl;
    }    
    else{
        cout<<dynamic_cast<num_node*>(&(*a))->getNum()<<endl;
    }    
}  
  
vector<pointer<node> > v;
vector<pointer<node> >::iterator current;

stack<float> s;
 
void GenCode(char c){
    //cout<<"生成中间代码\n"; 
    float p1=s.top();s.pop();//cout<<"弹出"<<p1<<endl; 
    float p2=s.top();s.pop();//cout<<"弹出"<<p2<<endl; 
    switch(c){
        case '+':
            s.push(p2+p1);
            //cout<<"相加 "; 
            //cout<<"压入"<<p1+p2<<endl; 
            break;
        case '-':
            s.push(p2-p1);
            //cout<<"相减 ";
            //cout<<"压入"<<p2-p1<<endl;  
            break;
        case '*':
            s.push(p2*p1); 
            //cout<<"相乘 ";
            //cout<<"压入"<<p1*p2<<endl; 
            break;
        case '/':
            s.push(p2/p1); 
            //cout<<"相除 ";
            //cout<<"压入"<<p2/p1<<endl; 
            break; 
    } 
} 
void match(char c){
    //cout<<"match(char)\n"; 
    //system("pause"); 
    if(isChar(*current)){
        if((*current)->getChar()==c){
            //cout<<"匹配"<<c<<endl;
            current++;
            return;
        } 
        else{
            //cout<<((*current)->getChar())<<"不匹配"<<endl;
            error();
        } 
    } 
    else{
        error(); 
    } 
} 
void E(){
    //cout<<"E()\n"; 
    if(isChar(*current)){
        //system("pause");cout<<"当前值为字符\n"; 
        if((*current)->getChar()=='('){
            //cout<<"当前值为字符'('\n"; 
            T();Ts();
        }
        else{error();} 
    } 
    else{
        if(isNum(*current)){
            //system("pause");cout<<"当前值为数字\n";
            T();Ts();
        }
        else{
            error(); 
        } 
    } 
    //cout<<"退出E()\n";     
} 
void Ts(){
    //cout<<"Ts()\n"; 
    if(isChar(*current)){
        //system("pause");cout<<"当前值为字符\n";
        if((*current)->getChar()=='#' || (*current)->getChar()==')'){
            //cout<<"当前值为字符#或)\n";
        } 
        else{
            if((*current)->getChar()=='+'){match('+');T();GenCode('+');Ts();}
            else{
                if((*current)->getChar()=='-'){
                    match('-');T();GenCode('-');Ts(); 
                } 
                else{
                    error(); 
                } 
            } 
        } 
    } 
    else{
        error(); 
    } 
    //cout<<"退出Ts()\n"; 
} 
void T(){
    //cout<<"T()\n"; 
    if(isChar(*current)){
        //system("pause");cout<<"当前值为字符\n"; 
        if((*current)->getChar()=='('){P();Ps();}
        else{error();} 
    }
    else{
        if(isNum(*current)){
            //system("pause");cout<<"当前值为数字\n";
            P();Ps();
        }
        else{error();} 
    } 
    //cout<<"退出T()\n"; 
} 
void Ps(){
    //cout<<"Ps()\n"; 
    if(isChar(*current)){
        //system("pause");cout<<"当前值为字符\n"; 
        if((*current)->getChar()=='+' || (*current)->getChar()=='-' || (*current)->getChar()=='#' || (*current)->getChar()==')'){
            //cout<<"当前值为字符+或-或#或)\n"; 
        }
        else{
            if((*current)->getChar()=='*'){match('*');P();GenCode('*');Ps();}
            else{
                if((*current)->getChar()=='/'){match('/');P();GenCode('/');Ps();} 
                else{error();} 
            } 
        } 
    } 
    else{error();} 
    //cout<<"退出Ps()\n"; 
} 
void P(){
    //cout<<"P()\n"; 
    if(isNum(*current)){
        //system("pause");cout<<"当前值为数字\n"; 
        s.push((*current)->getNum());
        //cout<<"压入"<<((*current)->getNum())<<endl; 
        current++; 
    } 
    else{
        if(isChar(*current)){
            //system("pause");cout<<"当前值为字符\n"; 
            if((*current)->getChar()=='('){match('(');E();match(')');}
            else{error();} 
        }  
    } 
    //cout<<"退出P()\n"; 
} 
int main(){
    //while(1){ 
    //while(!s.empty()){s.pop();} 
    //while(v.size()!=0){v.clear();} 
    
    string str;
    cin>>str;//输入字符串,以#号结束 
    //如  (1+3)*(2-4/1)# 
    //如    (-0.3)*(2+2)# 
    
    if(str.at(0)=='+' || str.at(0)=='-'){str="0"+str;}
    
    int pos=0;
    while((pos=str.find('+',pos))!=string::npos && str.at(pos-1)!=')'){
        if(!isdigit(str.at(pos-1))){
            str.insert(pos,"0");pos+=1;
        }
        pos++; 
    } 
    pos=0;
    while((pos=str.find('-',pos))!=string::npos && str.at(pos-1)!=')'){
        if(!isdigit(str.at(pos-1))){str.insert(pos,"0");pos+=1;}
        pos++; 
    } 
    
    //cout<<"processed :"<<str<<endl;
    
    const char* iter=str.c_str();
     
    iter=str.c_str();
    
    while(*iter!='\0'){
        if(*iter=='+' || *iter=='-' || *iter=='*' || *iter=='/' || *iter=='=' || *iter=='(' || *iter==')'){
            if(*iter=='='){v.push_back(pointer<node>(new char_node('#')));} 
            else{
                v.push_back(pointer<node>(new char_node(*iter)));
            } 
            iter++; 
        }
        else{
            float f=atof(iter);
            v.push_back(pointer<node>(new num_node(f)));
            while((*iter>='0' && *iter<='9') || *iter=='.'){iter++;} 
        } 
    } 
    
    //cout<<"total parts : "<<v.size()<<endl; 
    
    //for_each(v.begin(),v.end(),print4); 
    
    current=v.begin();  
    
    E(); 
    match('#');
    
    if(!s.empty()){cout<<s.top()<<endl;} 
    
    //char c; 
    //cout<<"继续?y/n\n";cin>>c;if(c=='n')break; 
    //} 
    
    system("pause");
}    
用的是表达式文法

E -> T Ts

Ts -> null

Ts -> +T Ts

Ts -> -T Ts

T -> P Ps

Ps -> null

Ps -> * P Ps

Ps -> / P Ps

P -> C

P -> (E)


程序中输入如

(9-2)/2=

(-3)/(4-2)=

....

如果有语法错误,会终止





  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值