大佬做的,我拷过来存着,正确性未知
#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