more +-*/

class simple_script{
	typedef std::list<std::string> exp_list;
	typedef exp_list::const_iterator exp_item;
	typedef std::map<std::string,std::string> exp_results;
public:
	simple_script(const std::string& script){
		parse_script(script,expr);
	}
public:
	void do_script(){
		excute_block(expr.begin(),expr.end());
	}
protected:
	exp_item assign_op(exp_item b, exp_item e){
		std::string key = *b++;//var 
		std::string asg = *b++;// =
		if(*b == "function"){
			b = skip_function(b,e);
			return ++b;
		}
		exp_item ret = std::find(b,e,";");
		results[key] = calculate_string(b,ret);
		return ++ret;
	}
	exp_item test_op(exp_item b, exp_item e){
		exp_item te = std::find(b,e,"]");
		exp_item tb = std::find(b, te,"[");
		std::string rst = calculate_string(tb,te);
		tb = get_block_range(++te,e);
		if(!rst.empty() && string_cast<int>(rst)){			
			excute_block(++te,tb);
		}
		return ++tb;
	}
protected:
	exp_item skip_function(exp_item b, exp_item e){		
		if(b == e || *b !="function"){
			return b;
		}
		b = std::find(b,e,"{");
		return get_block_range(b,e);
	}
public:
	/*
	sub function operation
	*/
	std::string get_sub_result(const std::string& function_name,exp_item pb,exp_item pe){
		exp_item b = std::find(expr.begin(),expr.end(),function_name);
		exp_item e = expr.end();
		if(b == e){
			return "";
		}
		b = std::find(b,e,"<");
		for(++b,++pb; b != e && pb != pe && *b != ">"; ++b,++pb){
			if(*b == ",") continue;
			results[*b] = *pb;
		}
		e = get_block_range(++b,e);
		excute_block(++b,e);
		return results[function_name];
	}
	const exp_results& get_results(void)const{
		return results;
	}
protected:
	void excute_block(exp_item b,const exp_item& e){
		for(; b != e;){
			std::string key = *b;			
			if(key == "if"){
				b = test_op(b,e);
			}else{
				b = assign_op(b,e);
			}
		}
	}
	exp_item get_block_range(exp_item b ,exp_item e){
		int tag = 1;
		for(++b; b != e; ++b){			
			if("{" == *b) ++tag;
			if("}" == *b) --tag;
			if(0 == tag) break;
		}
		return b;
	}
protected:
	exp_list expr;
protected:
	/*
		the script no local var only glob var
	*/
	exp_results results;
	std::string get_result(const std::string& key){
		exp_results::const_iterator it = results.find(key);
		return (it == results.end()) ? key : (it->second);
	}

protected:
	/*
	base operation
	*/
	std::string sub(const std::string& v){
		return "-" + get_result(v);
	}
	std::string add(const std::string& l,const std::string& r){
		const std::string lv = get_result(l);
		const std::string rv = get_result(r);
		return to_string(string_cast<double>(lv) + string_cast<double>(rv));
	}
	std::string mut(const std::string& l,const std::string& r){
		const std::string lv = get_result(l);
		const std::string rv = get_result(r);
		return to_string(string_cast<double>(lv) * string_cast<double>(rv));
	}
	std::string div(const std::string& l,const std::string& r){
		const std::string lv = get_result(l);
		const std::string rv = get_result(r);
		return to_string(string_cast<double>(lv) / string_cast<double>(rv));
	}
	std::string calculate_string(exp_item b,exp_item e){
		std::stack<std::string> results;
		results.push(*b);
		for(++b; b != e; ++b){
			switch(b->c_str()[0]){
			case '<':{
				std::string l = results.top();
				results.pop();
				exp_item it = std::find(b,e,">");
				results.push(get_sub_result(l,b,it));
				b = it;
				break;
					 }
			case '+':{
				break;
					 }
			case '-':{
				results.push(sub(*(++b)));
				break;
					 }
			case '*':{
				std::string l = results.top();
				results.pop();
				results.push(mut(l,*(++b)));
				break;
					 }
			case '/':{
				std::string l = results.top();
				results.pop();
				results.push(div(l,*(++b)));
				break;
					 }
			default:{
				results.push(*b);
				break;
					}
			}			
		}
		if(results.size() == 1){
			return get_result(results.top());
		}
		std::string result = results.top();	
		for(results.pop();!results.empty();results.pop()){
			result = add(result,results.top());
		}
		return result;
	}
protected:	
	/*
		parse the script
	*/
	void parse_script(const std::string& script,exp_list& results){
		std::string::const_iterator b = script.begin();
		std::string::const_iterator e = script.end();
		std::string value;
		for(; b != e ;++b){
			switch(*b){
			case '\t':
			case '\n':
			case ' ':{
				break;
					 }
			case '[':
			case ']':
			case '<':
			case '>':
			case '=':
			case ';':
			case '(':
			case ')':
			case ',':
			case '{':
			case '}':
			case '+':
			case '-':
			case '*':
			case '/':{					
				if(!value.empty()) results.push_back(value);
				results.push_back(op_v(*b));
				value.clear();
				break;
					 }
			default:{
				value += *b;
				break;
					}
			}
		}
	}
};
int main(int argc, char* argv[]){
	std::string script = "d=1+2+3+4+5+6+7+8+9+10*10;\n"
		"a= 1*3-4;\n"
		"c=a+d;\n"
		"test = function<x,y>{\n"
		"result = 0;\n"
		"if[c]{\n"
		"result = 1;\n"
		"}"
		"test = result + x + y;\n"
		"}\n"
		"e = test<10,8>;\n"
		"f = test<23,32>;";

	std::cout << script << std::endl;
	simple_script ss(script);
	ss.do_script();
	std::list<std::string> param;
	param.push_back("<");
	param.push_back("46");
	param.push_back(",");
	param.push_back("64");
	param.push_back(">");
	std::cout << ss.get_sub_result("test",param.begin(),param.end()) << std::endl;
	std::map<std::string,std::string> vals = ss.get_results();
	std::map<std::string,std::string>::const_iterator b = vals.begin();
	for(; b != vals.end();++b){
		std::cout << b->first << "=" << b->second << std::endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值