2017CCSP第二题

大佬做的,我拷过来存着,正确性未知

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <sstream>

using namespace std;

//#define DEBUG_TRACE_FUNCTION //启用函数追踪

int popspace(){
    while(cin.peek()==' ')
        cin.get();
    return cin.peek();
}
//判断ch是否为合法标识符
bool validch(int ch){
    const static char str[]="+-*/!?=<>_";
    if(ch>='A'&&ch<='Z')
        return true;
    if(ch>='a'&&ch<='z')
        return true;
    if(ch>='0'&&ch<='9')
        return true;
    int i=0;
    while(str[i]&&str[i]!=ch)
        i++;
    return str[i]!='\0';
}
//当发生错误时调用此函数
void err(string str){
    cerr<<"ERR:"<<str<<endl;
    exit(0);
}
//表达式基类
class Expr{
public:
    //表达式计算
    virtual Expr * val(){
        err("invalid expr");
        return nullptr;
    }
    //表达式的值
    virtual string value(){
        err("undefined value");
        return "ERROR";
    }
};
//上下文环境
class Env{
public:
    Env * upward;
    map<string,Expr *> context;

    Env(Env * upward):upward(upward){}

    void push(string name,Expr * c){
        context[name]=c;
    }
    Expr * get(string str){
        if(context.count(str)==1)
            return context[str];
        else{
            if(upward == nullptr)
                return nullptr;
            return upward->get(str);
        }
    }
};

Env * globalEnv;//全局环境,所有环境均指向globalEnv
Env * curEnv;//当前使用的运行时环境
//原子类型,用作标识符,需要从当前运行时环境取得具体常量值
class E_Atom:public Expr{
public:
    string val_str;

    E_Atom(string s):val_str(s){}

    virtual Expr * val(){
        Expr * ret = curEnv->get(val_str);
        if(ret == nullptr){
            cerr<<"atom \""<<val_str<<"\" error. env:"<<(curEnv)<<" size:"<<curEnv->context.size()<<endl;
            err("invalid atom");
        }
        return ret;
    }
    virtual string value(){
        return val_str;
    }
};
//int类型
class E_int:public Expr{
public:
    int val_int;

    E_int(string s){
        st
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值