zoukankan      html  css  js  c++  java
  • 【集训队互测2015】未来程序·改

    一个月之前写的题……

    http://uoj.ac/submission/293973

    真的毒瘤,调了5天……

    然而还是有很多缺陷

    1. 内存泄漏太严重,已经补救过一发了,然而还是有很多泄漏
    2. 把cincout当作了关键字,实际上当作变量更好写,重载后也符合正常观念,但是重写这部分的时候写挂了,所以回档了

    最后竟然被没有关键字引导的大括号卡RE了那么久

    跑的又慢,代码又长,真的是垃圾代码

    // ...
    // By Daklqw
    // 出题人 orz
    
    // MemoryPool 重构版本
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <map>
    #include <iomanip>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    namespace Mirai {
    #define LOCAL_TEST
    // Constant Variables
    // Array Size
    const int ProgramMaxLength = 50010;
    // Base Type
    const int TypeMask = 0xF;
    const int Symbol_t = 0x1;
    const int Variable_t = 0x2;
    const int Function_t = 0x3;
    const int Keyword_t = 0x4;
    // Symbol
    const int SymbolMask = 0xFF0;
    const int lsBracket_s = 0x010; 	// (
    const int rsBracket_s = 0x020; 	// )
    const int lmBracket_s = 0x030; 	// [
    const int rmBracket_s = 0x040; 	// ]
    const int Not_s = 0x050; 		// !
    const int Positive_s = 0x060; 	// + (sum)
    const int Negative_s = 0x070; 	// - (sum)
    const int Multi_s = 0x080; 		// *
    const int Divide_s = 0x090; 	// /
    const int Module_s = 0x0A0; 	// %
    const int Plus_s = 0x0B0; 		// +
    const int Minus_s = 0x0C0; 		// -
    const int lEq_s = 0x0D0;		// <= 
    const int rEq_s = 0x0E0; 		// >=
    const int Less_s = 0x0F0; 		// <
    const int Greater_s = 0x100; 	// >
    const int Eq_s = 0x110; 		// ==
    const int nEq_s = 0x120; 		// !=
    const int Xor_s = 0x130; 		// ^
    const int And_s = 0x140; 		// &&
    const int Or_s = 0x150; 		// ||
    const int valueEq_s = 0x160; 	// (variable) = (statement)
    const int lStream_s = 0x170; 	// ostream << (statememt)
    const int rStream_s = 0x180; 	// istream >> (variable)
    const int endOfAStatement_s = 0x190; // ;
    const int llBracket_s = 0x200;  // {
    const int rlBracket_s = 0x210;  // }
    const int Split_s = 0x220;      // ,
    const int Fill_s = 0xEE0; 		// Take Place
    // Variable
    const int VariableMask = 0xF000;
    const int CommonType_v = 0x1000; // int x;
    const int ArrayType_v = 0x2000; // int x[10];
    const int Constant_v = 0x3000; // 10
    // Function
    const int FunctionMask = 0xF0000;
    const int CustomType_f = 0x10000;
    const int BuiltinType_f = 0x20000;
    // Keyword
    const int KeywordMask = 0xF00000;
    const int Int_k = 0x100000;
    const int Cin_k = 0x200000;
    const int Cout_k = 0x300000;
    const int If_k = 0x400000;
    const int While_k = 0x500000;
    const int For_k = 0x600000;
    const int Return_k = 0x700000;
    const int Else_k = 0x800000;
    
    // Char Type
    const int CharMask = 0xFF;
    const int Digit_ct = 0x1;
    const int Space_ct = 0x2;
    const int Alpha_ct = 0x3;
    const int Upper_ct = 0x10;
    const int Lower_ct = 0x20;
    const int Symbol_ct = 0x4;
    
    // Flags
    void * FlagFalse = (void*) 0x12345;
    void * FlagTrue = (void*) 0x54321;
    const int EndlFlag = 0x23333;
    
    // Without const Warning
    
    // Debug Control
    int EnableDebug;
    
    // Utils
    class _Char_Checker_base {
    public:
    	inline bool isDigit(char x) { return '0' <= x && x <= '9'; }
    	inline bool isSpace(char x) { return x == ' ' || x == '
    ' || x == '
    ' || x == '	'; }
    	inline bool isAlpha(char x) { return ('A' <= x && x <= 'Z') || ('a' <= x && x <= 'z'); }
    	inline bool isUpper(char x) { return 'A' <= x && x <= 'Z'; }
    	inline bool isLower(char x) { return 'a' <= x && x <= 'z'; }
    	inline bool isSymbol(char x) { return !isDigit(x) && !isSpace(x) && !isAlpha(x); }
    	inline int getType(char x) {
    		if (isDigit(x)) return Digit_ct;
    		if (isSpace(x)) return Space_ct;
    		if (isAlpha(x)) return (isLower(x) ? Lower_ct : Upper_ct) | Alpha_ct;
    		return Symbol_ct;
    	}
    private:
    
    } Char_Checker;
    
    class _StringUtil_base {
    public:
    	inline unsigned length(const char * x) { return strlen(x); }
    	inline void cleanReturn(char * x) { char * cur = x + length(x) - 1; if (*cur == '
    ') *cur = 0; }
    	inline int strcmp(const char * a, const char * b, int lengthlimit = -1) {
    		if (~lengthlimit) return strncmp(a, b, lengthlimit);
    		return strcmp(a, b);
    	}
    	inline int parseInt(const char * buf) {
    		int x = 0;
    		while (*buf) x = ((x << 2) + x << 1) + (*buf++ & 15);
    		return x;
    	}
    	inline int parseInt(const string & buf) {
    		return parseInt(buf.c_str());
    	}
    	inline string substr(const string & x, const int l, const int r) {
    		return x.substr(l, r - l);
    	}
    	inline string int_to_string(int x) { return std::to_string(x); }
    	inline string toReturnFlag(const string & x) {
    		string res = x;
    		int cnt = 0;
    		for (int i = 0; i != res.length(); ++i) {
    			cnt += res[i] == '@';
    			if (cnt == 3) return substr(x, 0, i + 1) + "returnFlag";
    		}
    		return string("");
    	}
    	inline string getVariableName(const string & x) {
    		int at = 0;
    		for (int i = 0; i != x.length(); ++i)
    			if (x[i] == '@')
    				at = i;
    		return substr(x, at + 1, x.length());
    	}
    	inline string upFloor(const string & x) {
    		int cnt = 0;
    		for (int i = x.length() - 1; i; --i) {
    			cnt += x[i] == '@';
    			if (cnt == 2) 
    				return substr(x, 0, i + 1) + getVariableName(x);
    		}
    		return getVariableName(x);
    	}
    	inline int nxtChr(const string & x, const char ch) {
    		int cur = 0, res = -1;
    		while (cur != x.length()) {
    			if (x[cur] == ch) return cur;
    			++cur;
    		}
    		return -1;
    	}
    } StringUtil;
    
    class _NameManager_base {
    public:
    	_NameManager_base() { bak = 0; }
    	inline int getID(string x) {
    		map<string, int>::iterator it = name.find(x);
    		if (it != name.end()) return it -> second;
    		Q.push_back(x);
    		return name[x] = ++bak;
    	}
    	inline string getIDs(string x) { return StringUtil.int_to_string(getID(x)); }
    	inline string getNameByID(int x) { return Q[x - 1]; }
    private:
    	map<string, int> name;
    	vector<string> Q;
    	int bak;
    } NameManager;
    
    class _SymbolLevelManager_base {
    public:
    	inline bool isKeyword(int symbol) { return !!(symbol & KeywordMask); }
    	inline bool isBracket(int symbol) { 
    		switch (symbol & SymbolMask) {
    			case lsBracket_s: case rsBracket_s:
    			case lmBracket_s: case rmBracket_s:
    			case llBracket_s: case rlBracket_s:
    				return true;
    			default:
    				return false;
    		}
    	}
    	inline bool isControlKeyword(int symbol) {
    		switch (symbol & KeywordMask) {
    			case For_k: case If_k: case While_k:
    				return true;
    			default:
    				return false;
    		}
    	}
    	inline int getLevel(int symbol) {
    		int res = 0;
    		switch (symbol & SymbolMask) {
    			case lsBracket_s : res = 11; break;
    			case rsBracket_s : res = 11; break;
    			case lmBracket_s : res = 11; break;
    			case rmBracket_s : res = 11; break;
    			case Not_s : res = 10; break;
    			case Positive_s : res = 10; break;
    			case Negative_s : res = 10; break;
    			case Multi_s : res = 9; break;
    			case Divide_s : res = 9; break;
    			case Module_s : res = 9; break;
    			case Plus_s : res = 8; break;
    			case Minus_s : res = 8; break;
    			case lEq_s : res = 7; break;
    			case rEq_s : res = 7; break;
    			case Less_s : res = 7; break;
    			case Greater_s : res = 7; break;
    			case Eq_s : res = 6; break;
    			case nEq_s : res = 6; break;
    			case Xor_s : res = 5; break;
    			case And_s : res = 4; break;
    			case Or_s : res = 3; break;
    			case valueEq_s : res = 2; break;
    			case lStream_s : res = 1; break;
    			case rStream_s : res = 1; break;
    			default : res = -1; break;
    		}
    		return res;
    	}
    private:
    
    } SymbolLevelManager;
    
    // Base Type
    class _StatementType_base {
    public:
    	string val; // int typ;
    	// _StatementType_base(const string & _val, const int _typ) { val = _val; typ = _typ; }
    	_StatementType_base(const string & _val) { val = _val; }
    } ;
    class _SymbolTranslater_base {
    public:
    	_SymbolTranslater_base() {
    		S["("] = lsBracket_s;
    		S[")"] = rsBracket_s;
    		S["["] = lmBracket_s;
    		S["]"] = rmBracket_s;
    		S["!"] = Not_s;
    		S["+"] = Plus_s;
    		S["-"] = Minus_s;
    		S["*"] = Multi_s;
    		S["/"] = Divide_s;
    		S["%"] = Module_s;
    		S["<="] = lEq_s;
    		S[">="] = rEq_s;
    		S["<"] = Less_s;
    		S[">"] = Greater_s;
    		S["=="] = Eq_s;
    		S["!="] = nEq_s;
    		S["^"] = Xor_s;
    		S["&&"] = And_s;
    		S["||"] = Or_s;
    		S["="] = valueEq_s;
    		S["<<"] = lStream_s;
    		S[">>"] = rStream_s;
    		S[";"] = endOfAStatement_s;
    		S["{"] = llBracket_s;
    		S["}"] = rlBracket_s;
    		S[","] = Split_s;
    
    		S["int"] = Int_k;
    		S["cin"] = Cin_k;
    		S["cout"] = Cout_k;
    		S["if"] = If_k;
    		S["while"] = While_k;
    		S["for"] = For_k;
    		S["return"] = Return_k;
    		S["else"] = Else_k;
    	}
    	int trans(string s) { return S[s]; }
    private:
    	map<string, int> S;
    } SymbolTranslater;
    
    // Data Object
    class _StatementAutomaton_base {
    public:
    	inline bool haveNxt(int now, int tar) { return arr[now][tar]; }
    	_StatementAutomaton_base() {
    		const char buf1[] = "_$QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
    		for (int i = 0; i != 64; ++i)
    			for (int j = 0; j != 64; ++j)
    				arr[buf1[i]][buf1[j]] = true;
    		arr['=']['='] = true;
    		arr['<']['='] = true;
    		arr['>']['='] = true;
    		arr['!']['='] = true;
    		arr['&']['&'] = true;
    		arr['|']['|'] = true;
    		arr['<']['<'] = true;
    		arr['>']['>'] = true;
    		arr['/']['/'] = true; // Just For Fun
    		arr['+']['+'] = true; // Just For Fun
    		arr['-']['-'] = true; // Just For Fun
    		arr['-']['>'] = true; // Just For Fun Need to limit symbol length
    	}
    private:
    	bool arr[256][256];
    } StatementAutomaton;
    
    class _StatementAutomatonNode_base {
    public:
    	inline int nxt(int target) { if (StatementAutomaton.haveNxt(now, target)) return now = target; return -1; }
    	void setNode(int index) { now = index; }
    	_StatementAutomatonNode_base(int index) { now = index; }
    	_StatementAutomatonNode_base() {} 
    private:
    	int now;
    } ;
    
    class _ProgramBuffer_base {
    public:
    	void setBuf(const char * src) { memcpy(buf, src, StringUtil.length(src) + 1); cur = buf; }
    	inline char nextChar() { return *cur++; }
    	inline void backspace() { --cur; }
    	inline void seek(int index) { cur = buf + index; }
    	inline int indexNow() { return cur - buf; }
    	inline bool haveNext() {
    		const char * tcur = cur;
    		while (*tcur) { if (!Char_Checker.isSpace(*tcur)) return true; ++tcur; }
    		return false;
    	}
    	inline _StatementType_base nextStatement() {
    		int ch;
    		while (Char_Checker.isSpace(ch = nextChar())) ;
    		string res;
    		res.append(1, ch);
    		_StatementAutomatonNode_base node(ch);
    		while (true) {
    			ch = nextChar();
    			if (!~node.nxt(ch)) { backspace(); break; }
    			res.append(1, ch);
    		}
    		return _StatementType_base(res);
    	}
    	void init() {
    		while (true) {
    			fgets(linev, ProgramMaxLength, stdin);
    			if (StringUtil.strcmp(linev, "using namespace std;", StringUtil.length("using namespace std;")) == 0) break;
    		}
    		fread(buf, 1, ProgramMaxLength, stdin);
    		cur = buf;
    	}
    private:
    	char buf[ProgramMaxLength], linev[ProgramMaxLength];
    	const char * cur;
    } ProgramBuffer;
    
    class _ReadinBuffer_base {
    public:
    	int	nextInt() { return sums[cur++]; }
    	void init() {
    		int cnt, t; scanf("%d", &cnt);
    		for (int i = 1; i <= cnt; ++i) { scanf("%d", &t); sums.push_back(t); }
    	}
    private:
    	vector<int> sums;
    	int cur = 0;
    } ReadinBuffer;
    
    class _StatementLine_base {
    public:
    	void append(const _StatementType_base & x) { line.push_back(x); }
    	inline int size() { return line.size(); }
    	inline _StatementType_base operator [] (const int index) const  { return line[index]; }
    	void init() {
    		// Get Match
    		const int tz = size();
    		for (int i = 0; i != tz; ++i) {
    			const char ct = line[i].val[0];
    			if (Char_Checker.isSymbol(ct) && SymbolLevelManager.isBracket(SymbolTranslater.trans(line[i].val))) {
    				if (ct == '(' || ct == '[' || ct == '{') st[++top] = i;
    				else match[st[top--]] = i;
    			}
    			match[i] = i;
    		}
    	}
    	inline int getMatch(int pos) { return match[pos]; }
    	inline int findNxt(int now, int typ, int end = -1) {
    		int r = -1; if (!~end) end = size();
    		for (int i = now; i <= end; ++i)
    			if (SymbolTranslater.trans((this -> operator[] (i)).val) == typ) {
    				r = i;
    				break;
    			}
    		return r;
    	}
    	inline int findEnd(int now, int end = -1) {
    		return findNxt(now, endOfAStatement_s, end);
    	}
    	inline int getStatementEnd(int now, int end = -1) {
    		// cout << "getStatementEnd " << now << " " << end << endl;
    		int rr = -1;
    		string tbuf = (this -> operator[] (now)).val;
    		int typ = SymbolTranslater.trans(tbuf);
    		if (typ == If_k || typ == For_k || typ == While_k) {
    			int rr = this -> getMatch(now + 1);
    			return getStatementEnd(rr + 1, end);
    		} else if (typ == llBracket_s) // now + 1 ??? 
    			rr = this -> getMatch(now);
    		else
    			rr = this -> findEnd(now, end); 
    		return rr;
    	}
    private:
    	vector<_StatementType_base> line;
    	int st[ProgramMaxLength], top;
    	int match[ProgramMaxLength];
    } StatementLine;
    
    // Objects
    class _Object_base {
    public:
    	void setToken(const string & _token) { token = _token; }
    	string getToken() { return token; }
    	virtual _Object_base * getValue() = 0;
    	_Object_base() { is_Reference = false; }
    	bool isReference() { return is_Reference; }
    	void setReference(bool v = false) { is_Reference = v; }
    protected:
    	string token;
    	bool is_Reference;
    } ;
    
    // Object Object
    int FunctionCallDep;
    class _Function_base : public _Object_base {
    public:
    	virtual _Object_base * getValue() ;
    	void setRange(int _b, int _e) { begin = _b; end = _e; }
    	inline void argAppend(const string & x) { arg_list.push_back(x); }
    	inline string getArg(const int index) { return arg_list[index]; }
    	inline int getArgCount() { return arg_list.size(); }
    private:
    	vector<string> arg_list;
    	int begin, end;
    } ;
    
    class _Variable_base : public _Object_base {
    public:
    	int value;
    	_Variable_base() { value = 0; setReference(); }
    	virtual _Object_base * getValue() { return this; }
    	inline void setValue(int v) { value = v; }
    } ;
    
    class _Array_base : public _Object_base {
    public:
    	_Array_base(int arrsize) { arrsz = arrsize; arr = new _Object_base* [arrsize]; setReference(); }
    	// ~_Array_base() { delete [] arr; } // 玄学
    	virtual _Object_base * getValue() { return this; } // Warning
    	virtual _Object_base * getValue(int index) { if (index < 0) cerr << "ERR! " << index << endl; return arr[index]; }
    	inline void setValue(int index, _Object_base * src) { arr[index] = src; }
    	static _Object_base * makeVariableTree(vector<int>::iterator il, vector<int>::iterator ir) {
    		if (il == ir) {
    			_Variable_base * res = new _Variable_base();
    			res -> value = 0;
    			res -> setReference(true);
    			return static_cast<_Object_base*> (res);
    		} else {
    			_Array_base * res = new _Array_base(*il);
    			for (int i = 0; i != *il; ++i)
    				res -> setValue(i, makeVariableTree(il + 1, ir));
    			res -> setReference(true);
    			return static_cast<_Object_base*> (res);
    		}
    	}
    	static void clearVariableTree(_Object_base * now, vector<int>::iterator il, vector<int>::iterator ir) {
    		if (il == ir) static_cast<_Variable_base*> (now) -> value = 0;
    		else for (int i = 0; i != *il; ++i)
    			clearVariableTree(static_cast<_Array_base*> (now) -> getValue(i), il + 1, ir); 
    	}
    	int arrsz;
    	_Object_base ** arr;
    private:
    } ;
    
    
    class _MemoryPool_base {
    public:
    	inline _Object_base * call(const string & token) {
    		// cout << "Call " << token << endl;
    		return functions[token] -> getValue();
    	}
    	inline _Object_base * getVariable(const string & token) {
    		if (variables.find(token) == variables.end()) return NULL;
    		return variables[token];
    	}
    	inline _Object_base * getFunction(const string & token) {
    		if (functions.find(token) == functions.end()) return NULL;
    		return functions[token];
    	}
    	inline void setFunction(const string & token, _Object_base * src) {
    		// cout << "MemoryPool@ SetFunction " << token << endl;
    		functions[token] = src;
    	}
    	inline void setVariable(const string & token, _Object_base * src) {
    		// cout << "MemoryPool@ SetVariable " << token << endl; // << " " << src -> isReference() << endl;
    		/*
    		if (!src -> isReference()) {
    			cerr << "Error! " << endl;
    			for (int i = 1; i <= 1000000000; ++i) ;
    		}
    		*/
    		variables[token] = src;
    	}
    	inline _Object_base* findVariable(const string & token, int lines = -1) {
    		string tk = token;
    		map<string, _Object_base*>::iterator it;
    		if (EnableDebug) cout << "findVariable " << token << endl;
    		while (true) {
    			it = variables.find(tk);
    			if (it != variables.end()) return it -> second;
    			tk = StringUtil.upFloor(tk);
    			// if (EnableDebug) {
    				if (!~StringUtil.nxtChr(tk, '@')) {
    					cout << "Find Variable Failed" << endl;
    					cout << "The Variable Name : " << NameManager.getNameByID(StringUtil.parseInt(StringUtil.getVariableName(token))) << endl;
    					if (~lines) {
    						cout << "Passege:" << endl;
    						const int RAN = 5;
    						int begin = max(0, lines - RAN), end = min(lines + RAN, StatementLine.size() - 1);
    						for (int i = begin; i <= end; ++i) cout << i << " "; cout << endl;
    						for (int i = begin; i <= end; ++i) cout << StatementLine[i].val << " "; cout << endl;
    					}
    					exit(998244353);
    				}
    		}
    	}
    private:
    	map<string, _Object_base*> variables, functions;
    } MemoryPool;
    
    class _MemoryManager_base {
    public:
    	void append(_Variable_base * src) { vl.push_back(src); }
    	void append(_Object_base * src) { vl.push_back(static_cast<_Variable_base*> (src)); }
    	~_MemoryManager_base() {
    		if (EnableDebug) {
    			cout << "Call Destruction" << endl;
    			cout << "Variable list" << endl;
    			for (vector<_Variable_base*>::iterator it = vl.begin(); it != vl.end(); ++it) cout << *it << " "; cout << endl;
    			for (vector<_Variable_base*>::iterator it = vl.begin(); it != vl.end(); ++it) cout << (*it) -> isReference() << " "; cout << endl;
    		}
    		for (vector<_Variable_base*>::iterator it = vl.begin(); it != vl.end(); ++it) {
    			if (!(*it) -> isReference()) {
    				if (EnableDebug) cout << "Erase " << *it << endl;
    				delete *it;
    				if (EnableDebug) cout << "Erase OK " << endl;
    			} else {
    				if (EnableDebug) cout << "Erase " << *it << " Failed : Have Reference" << endl;
    			}
    		}
    	}
    private:
    	vector<_Variable_base*> vl;
    } ;
    struct Node_t {
    	Node_t * pre, * nxt;
    	_Object_base * val;
    	Node_t() { pre = nxt = NULL; val = NULL; typ = 0; }
    	int typ; // 0 Variable 1 Symbol
    } ;
    
    class _Expression_base {
    public:
    
    	void setFlag(string token, void * flag) {
    		// cout << "FLAG " << token << " " << StringUtil.toReturnFlag(token) << " " << flag << endl;
    		MemoryPool.setVariable(StringUtil.toReturnFlag(token), static_cast<_Object_base*> (flag));
    	}
    
    	bool isFlagTrue(string token) {
    		// cout << "WHAT " << token << " " << StringUtil.toReturnFlag(token) << " " << static_cast<void*> (MemoryPool.getVariable(token)) << endl;
    		token = StringUtil.toReturnFlag(token);
    		return static_cast<void*> (MemoryPool.getVariable(token)) == FlagTrue;
    	}
    
    	_Object_base * getVariableBlock(string token, int begin, int end) {
    		_Object_base * var = MemoryPool.findVariable(token + NameManager.getIDs(StatementLine[begin].val), begin);
    		int now = begin + 1;
    		// EnableDebug = true;
    		// {
    		_MemoryManager_base mm;
    		while (now <= end) {
    			int rr = StatementLine.getMatch(now);
    			_Variable_base * at = static_cast<_Variable_base*> (calc(token, now + 1, rr - 1));
    			var = static_cast<_Object_base*> (static_cast<_Array_base*> (var) -> getValue(at -> value));
    			mm.append(at);
    			now = rr + 1;
    		}
    		// }
    		// EnableDebug = false;
    		return var;
    	}
    	_Object_base * runStatement(string token, int rightk, int rr) {
    		// cout << "runStatement " << token << " " << rightk << " " << rr << endl;
    		int tarr = rightk + 1;
    		int typ = SymbolTranslater.trans(StatementLine[tarr].val);
    		if (!SymbolLevelManager.isControlKeyword(typ))
    			if (SymbolTranslater.trans(StatementLine[rr].val) != endOfAStatement_s) ++tarr;
    		// if (typ == llBracket_s) ++tarr;
    		// cout << "TEST TARR " << tarr << endl;
    		return run(token, tarr, rr - 1);
    	}
    
    	_Object_base * run(string tokenpre, int begin, int end) {
    		if (EnableDebug) {
    			cout << "RUN AT (" << begin << ", " << end << ")  TOKEN = "" << tokenpre << """ << endl;
    			for (int i = begin; i <= end; ++i) cout << i << " "; cout << endl;
    			for (int i = begin; i <= end; ++i) cout << StatementLine[i].val << " "; cout << endl;
    		}
    		// Run Statement
    		// 不带括号
    		_MemoryManager_base mm;
    		int now = begin;
    		while (now <= end) {
    			// cout << "Main " << now << " " << end << endl;
    			int statement_type = SymbolTranslater.trans(StatementLine[now].val);
    			if (SymbolLevelManager.isKeyword(statement_type)) {
    				switch (statement_type) {
    					case Return_k: {
    						int r = StatementLine.findEnd(now);
    						// cout << "TEST " << r << endl;
    						//	token.subString(0, StringUtil.find(token, "@", 3) + 1)
    						setFlag(tokenpre, FlagTrue);
    						_Object_base * ret = calc(tokenpre, now + 1, r - 1);
    						_Variable_base * res = new _Variable_base;
    						res -> value = static_cast<_Variable_base*> (ret) -> value;
    						mm.append(ret);
    						return static_cast<_Object_base*> (res);
    					}
    					case If_k: {
    						int rightk = StatementLine.getMatch(now + 1), rr = StatementLine.getStatementEnd(rightk + 1);
    						_Object_base * ret = calc(tokenpre, now + 2, rightk - 1);
    						mm.append(ret);
    						bool haveElse = false; int er = 0;
    						// cout << "DEBUG " << rightk << " " << rr << " ";
    						if (rr < end) {
    							if (SymbolTranslater.trans(StatementLine[rr + 1].val) == Else_k) {
    								haveElse = true;
    								er = StatementLine.getStatementEnd(rr + 2);
    							}
    						}
    						// cout << "Get Value " << static_cast<_Variable_base*> (ret) -> value << endl;
    						if (static_cast<_Variable_base*> (ret) -> value != 0) {
    							// cout << "CASE1 " << endl;
    							_Object_base * res;
    							res = runStatement(tokenpre + "if@", rightk, rr);
    							if (isFlagTrue(tokenpre)) return res;
    							mm.append(res);
    						} else if (haveElse) {
    							// cout << "CASE2 " << rr << endl;
    							_Object_base * res;
    							res = runStatement(tokenpre + "if@", rr + 1, er);
    							if (isFlagTrue(tokenpre)) return res;
    							mm.append(res);
    						}
    						if (haveElse) now = er + 1; else now = rr + 1;
    						break;
    					}
    					case For_k: {
    						int rightk = StatementLine.getMatch(now + 1), rr = StatementLine.getStatementEnd(rightk + 1),
    							f1 = StatementLine.getStatementEnd(now + 2), f2 = StatementLine.getStatementEnd(f1 + 1);
    						// cout << "DEBUG " << rr << " " << StatementLine[rightk + 1].val << endl;
    						_Object_base * ret = run(tokenpre, now + 2, f1);
    						mm.append(ret);
    						while (true) {
    							if (f1 + 1 <= f2 - 1) {
    								ret = calc(tokenpre, f1 + 1, f2 - 1);
    								mm.append(ret);
    								if (static_cast<_Variable_base*> (ret) -> value == 0) break;
    							}
    							_Object_base * res;
    							res = runStatement(tokenpre + "for@", rightk, rr);
    							if (isFlagTrue(tokenpre)) return res;
    							mm.append(res);
    							ret = calc(tokenpre, f2 + 1, rightk - 1);
    							mm.append(ret);
    						}
    						now = rr + 1;
    						break;
    					}
    					case While_k: {
    						int rightk = StatementLine.getMatch(now + 1), rr = StatementLine.getStatementEnd(rightk + 1);
    						while (true) {
    							_Object_base * ret = calc(tokenpre, now + 2, rightk - 1);
    							mm.append(ret);
    							if (static_cast<_Variable_base*> (ret) -> value == 0) break;
    							_Object_base * res;
    							res = runStatement(tokenpre + "while@", rightk, rr);
    							if (isFlagTrue(tokenpre)) return res;
    							mm.append(res);
    						}
    						now = rr + 1;
    						break;
    					}
    					case Int_k: {
    						// cout << StatementLine[now + 2].val << endl;
    						// cout << SymbolTranslater.trans(StatementLine[now + 2].val) << endl;
    						if (SymbolTranslater.trans(StatementLine[now + 2].val) == lsBracket_s) {
    							// Function
    							int r = StatementLine.getMatch(now + 2), rr = StatementLine.getMatch(r + 1);
    							// cout << "DEBUG " << r << " " << rr << endl;
    							_Function_base * f = new _Function_base;
    							string tokent = "Global@" + NameManager.getIDs(StatementLine[now + 1].val);
    							f -> setToken(tokent);
    							f -> setRange(r + 2, rr - 1);
    							MemoryPool.setFunction(tokent, static_cast<_Object_base*> (f));
    							for (int i = now + 4; i < r; i += 3) f -> argAppend(StatementLine[i].val);
    							now = rr + 1;
    						} else {
    							// Variable and Array
    							int tnow = now, end = StatementLine.findEnd(now);
    							// cout << now << " " << end << endl;
    							while (tnow < end) {
    								int nt = StatementLine.findNxt(tnow + 1, Split_s, end);
    								// cout << "now " << tnow << " Nxt " << nt << endl;
    								if (!~nt) nt = end;
    								int vl = tnow + 1, vr = nt - 1;
    								// cout << "Var " << vl << " " << vr << endl;
    								if (vl == vr) {
    									string tokent = tokenpre + NameManager.getIDs(StatementLine[vl].val);
    									_Object_base * tx;
    									if ((tx = MemoryPool.getVariable(tokent)) != NULL)
    										static_cast<_Variable_base*> (tx) -> value = 0;
    									else {
    										_Variable_base * v = new _Variable_base;
    										v -> setReference(true);
    										v -> value = 0;
    										v -> setToken(tokent);
    										MemoryPool.setVariable(tokent, static_cast<_Object_base*> (v));
    									}
    								} else {
    									vector<int> ranArr;
    									for (int i = vl + 2; i <= vr; i += 3) ranArr.push_back(StringUtil.parseInt(StatementLine[i].val));
    									string tokent = tokenpre + NameManager.getIDs(StatementLine[vl].val);
    									_Object_base * tx;
    									if ((tx = MemoryPool.getVariable(tokent)) != NULL)
    										_Array_base::clearVariableTree(tx, ranArr.begin(), ranArr.end());
    									else {
    										_Array_base * v = static_cast<_Array_base*> (_Array_base::makeVariableTree(ranArr.begin(), ranArr.end()));
    										v -> setToken(tokent);
    										MemoryPool.setVariable(tokent, static_cast<_Object_base*> (v));
    									}
    								}
    								tnow = nt;
    							}
    							now = end + 1;
    						}
    						break;
    					}
    					case Cin_k: {
    						int r = StatementLine.findEnd(now); int tnow = now + 1;
    						// cout << "Cin " << r << endl;
    						while (true) {
    							if (SymbolTranslater.trans(StatementLine[tnow].val) == endOfAStatement_s) break;
    							int rr = StatementLine.findNxt(tnow + 1, rStream_s, r);
    							// cout << "Find " << tnow << " " << rr << endl;
    							if (!~rr) rr = r;
    							_Object_base * var = getVariableBlock(tokenpre, tnow + 1, rr - 1);
    							int tv = ReadinBuffer.nextInt();
    							static_cast<_Variable_base*> (var) -> setValue(tv);
    							// cout << "Cin " << var -> getToken() << " " << static_cast<_Variable_base*> (var) -> value << endl;
    							tnow = rr;
    						}
    						now = r + 1;
    						// cout << "JUMP " << endl;
    						break;
    					}
    					case Cout_k: {
    						int r = StatementLine.findEnd(now); int tnow = now + 1;
    						// cout << "Cout " << r << endl;
    						while (true) {
    							if (SymbolTranslater.trans(StatementLine[tnow].val) == endOfAStatement_s) break;
    							int rr = StatementLine.findNxt(tnow + 1, lStream_s, r);
    							if (!~rr) rr = r;
    							// cout << "Find " << tnow << " " << rr << endl;
    							_Object_base * rev = calc(tokenpre, tnow + 1, rr - 1);
    							if (static_cast<_Variable_base*> (rev) -> value == EndlFlag) putchar(10);
    							else printf("%d", static_cast<_Variable_base*> (rev) -> value);
    							mm.append(rev);
    							tnow = rr;
    						}
    						now = r + 1;
    						break;
    					}
    				}
    			} else if (statement_type == llBracket_s) {
    				int rr = StatementLine.getMatch(now);
    				_Object_base * res;
    				res = run(tokenpre + "bkt@", now + 1, rr - 1);
    				if (isFlagTrue(tokenpre)) return res;
    				mm.append(res);
    				now = rr + 1;
    			} else {
    				int r = StatementLine.findEnd(now);
    				_Object_base * res = calc(tokenpre, now, r - 1);
    				mm.append(res);
    				now = r + 1;
    			}
    		}
    		_Variable_base * result = new _Variable_base;
    		result -> value = 0;
    		// cout << "RUNOK " << endl;
    		return static_cast<_Object_base*> (result);
    	}
    
    	pair<_Object_base*, int> nextVariable(string tokenpre, int begin, int end) {
    		if (EnableDebug) cout << "nextVariable AT (" << begin << ", " << end << ")  TOKEN = "" << tokenpre << """ << endl;
    		int typ = -1;
    		if (SymbolTranslater.trans(StatementLine[begin].val) == lsBracket_s) { // 括号表达式
    			int rr = StatementLine.getMatch(begin);
    			return make_pair(calc(tokenpre, begin + 1, rr - 1), rr);
    		} else if (begin + 1 <= end && SymbolLevelManager.isBracket(typ = SymbolTranslater.trans(StatementLine[begin + 1].val))) {
    			_MemoryManager_base mm;
    			// cout << "WAHT " << endl;
    			if (typ == lsBracket_s) { // Function
    				// Get Nxt ,
    				int tp = 1, rr;
    				vector<int> sp_list;
    				// cout << "Call FUNCTION VAR_LIST " << endl;
    				for (int i = begin + 2; i <= end; ++i) {
    					int typ = SymbolTranslater.trans(StatementLine[i].val);
    					if (typ == llBracket_s || typ == lmBracket_s || typ == lsBracket_s) ++tp;
    					if (typ == rlBracket_s || typ == rmBracket_s || typ == rsBracket_s) --tp;
    					// cout << "DEBUG " << i << " " << typ << " " << StatementLine[i].val << " " << tp << endl;
    					if (typ == Split_s && tp == 1) sp_list.push_back(i);
    					if (tp == 0) { rr = i; break; }
    				}
    				// cout << "GET : ";
    				// for (int i = 0; i != sp_list.size(); ++i) cout << sp_list[i] << " "; cout << endl;
    				_Function_base * func = static_cast<_Function_base*> (MemoryPool.getFunction("Global@" + NameManager.getIDs(StatementLine[begin].val)));
    				string tokenprecall = func -> getToken() + "@st" + StringUtil.int_to_string(FunctionCallDep + 1) + "@";
    				// cout << "Test Token " << func -> getToken() << endl;
    				int ll = begin + 2;
    				if (func -> getArgCount()) for (int i = 0; i <= sp_list.size(); ++i) {
    					int tr;
    					if (i != sp_list.size()) tr = sp_list[i] - 1; else tr = rr - 1;
    					string tokenlike = tokenprecall + NameManager.getIDs(func -> getArg(i));
    					_Variable_base * tmp = new _Variable_base;
    					tmp -> value = static_cast<_Variable_base*> (calc(tokenpre, ll, tr)) -> value;
    					_Object_base * tx;
    					if ((tx = MemoryPool.getVariable(tokenlike)) != NULL) {
    						static_cast<_Variable_base*> (tx) -> value = tmp -> value;
    						mm.append(tmp);
    					} else {
    						tmp -> setReference(true);
    						MemoryPool.setVariable(tokenlike, static_cast<_Object_base*> (tmp));
    						// cout << "Arg " << i << " " << func -> getArg(i) << endl;
    					}
    					if (i != sp_list.size()) ll = sp_list[i] + 1;
    				}
    				// cout << "Ready for call" << endl;
    				// cout << "Test Token " << func -> getToken() << endl;
    				// _Object_base * res = func -> getValue();
    				_Object_base * res = MemoryPool.call(func -> getToken());
    				// cout << "nextVariable RETURNED with " << static_cast<_Variable_base*> (res) -> value << " " << rr << endl;
    				return make_pair(res, rr);
    			} else { // Array
    				// cout << "Array_T " << endl;
    				int now = begin;
    				while (now < end) {
    					// cout << "FIND " << now << " " << end << endl;
    					if (SymbolTranslater.trans(StatementLine[now + 1].val) != lmBracket_s) break;
    					now = StatementLine.getMatch(now + 1);
    				}
    				return make_pair(getVariableBlock(tokenpre, begin, now), now);
    			}
    		} else {
    			string t = StatementLine[begin].val;
    			if (Char_Checker.isDigit(t[0])) {
    				_Variable_base * res = new _Variable_base;
    				res -> value = StringUtil.parseInt(t);
    				return make_pair(static_cast<_Object_base*> (res), begin);
    			}
    			return make_pair(MemoryPool.findVariable(tokenpre + NameManager.getIDs(t), begin), begin);
    		}
    	}
    
    	_Object_base * calc(string tokenpre, int begin, int end) {
    		if (EnableDebug) {
    			cout << "CALC AT (" << begin << ", " << end << ")  TOKEN = "" << tokenpre << """ << endl;
    			for (int i = begin; i <= end; ++i) cout << i << " "; cout << endl;
    			for (int i = begin; i <= end; ++i) cout << StatementLine[i].val << " "; cout << endl;
    		}
    		// Calculate Expression
    		// 不带分号
    		vector<Node_t*> optli[12];
    		// 采用链表计算
    		// 单目优先处理 形式:... S S V S V ...
    		// 双目 形式 ... S V S V S ...
    		_MemoryManager_base mm;
    		Node_t * now = NULL, * fir = NULL, * bak = NULL;
    		int tnow = begin;
    		int ltyp = Fill_s;
    		while (tnow <= end) {
    			// cout << "DEBUG " << tnow << endl;
    			Node_t * x = new Node_t;
    			int typ = SymbolTranslater.trans(StatementLine[tnow].val) & SymbolMask;
    			// cout << "ORI " << typ << " " << SymbolLevelManager.isBracket(typ) << endl;
    			if (SymbolLevelManager.isBracket(typ)) typ = 0;
    			// cout << StatementLine[tnow].val << " " << typ << " " << tnow << " " << ltyp << endl;
    			x -> typ = typ;
    			x -> pre = now;
    			if (now != NULL) now -> nxt = x;
    			now = x;
    			if (ltyp && x -> typ) { // 单目, 往下读一个变量
    				// cout << "CALC CASE 1" << endl;
    				// TODO 如果(!!a)会怎么样
    				// _Object_base * var = nextVariable(tokenpre, tnow + 1, end);
    				vector<int> singlelist;
    				int tn = tnow;
    				while (true) {
    					int typ = SymbolTranslater.trans(StatementLine[tn].val);
    					if (typ != Not_s && typ != Plus_s && typ != Minus_s) { tnow = tn; break; }
    					singlelist.push_back(typ);
    					++tn;
    				}
    				pair<_Object_base*, int> res = nextVariable(tokenpre, tnow, end);
    				mm.append(res.first);
    				_Variable_base * tv = new _Variable_base;
    				tv -> value = static_cast<_Variable_base*> (res.first) -> value;
    				mm.append(tv);
    				_Object_base * var = static_cast<_Object_base*> (tv);
    				int & tx = tv -> value;
    				for (int i = singlelist.size() - 1; ~i; --i) {
    					switch (singlelist[i]) {
    						case Not_s:
    							tx = !tx;
    							break;
    						case Plus_s:
    							break;
    						case Minus_s:
    							tx = -tx;
    							break;
    					}
    				}
    				x -> typ = 0;
    				x -> val = var;
    				// cout << "TEST " << res.second << endl;
    				tnow = res.second + 1;
    			} else if (!x -> typ) { // 变量,先取值
    				// cout << "CALC CASE 2" << endl;
    				// cout << "23333" << endl;
    				pair<_Object_base*, int> res = nextVariable(tokenpre, tnow, end);
    				// cout << "23333" << endl;
    				_Object_base * var = res.first;
    				mm.append(var);
    				x -> typ = 0;
    				x -> val = var;
    				// cout << "TEST " << res.second << endl;
    				tnow = res.second + 1;
    			} else ++tnow;
    			ltyp = x -> typ;
    			if (x -> typ) {
    				optli[SymbolLevelManager.getLevel(typ)].push_back(x);
    				x -> typ = typ;
    			}
    			if (fir == NULL) fir = x;
    			bak = x;
    		}
    		if (EnableDebug) {
    			cout << "Build list OK" << endl;
    			Node_t * tl = fir; while (tl != NULL) { if (tl -> typ == 0) cout << static_cast<_Variable_base*> (tl -> val) -> value << " -> "; else cout << tl -> typ << " -> "; tl = tl -> nxt; } cout << endl; tl = fir; while (tl != NULL) { if (tl -> typ == 0) cout << tl -> val << " -> "; else cout << tl -> typ << " -> "; tl = tl -> nxt; } cout << endl; tl = fir; while (tl != NULL) { if (tl -> typ == 0) cout << tl -> val -> isReference() << " -> "; else cout << tl -> typ << " -> "; tl = tl -> nxt; } cout << endl;
    		}
    		for (int i = 11; i; --i) {
    			vector<Node_t*>::iterator itb, ite;
    			if (i == 2) reverse(optli[i].begin(), optli[i].end());
    			itb = optli[i].begin(), ite = optli[i].end();
    			for (; itb != ite; ++itb) {
    				// 消符号两边
    				_Variable_base * lhs = static_cast<_Variable_base*> ((*itb) -> pre -> val),
    							   * rhs = static_cast<_Variable_base*> ((*itb) -> nxt -> val);
    				_Variable_base * result = new _Variable_base;
    				mm.append(result); // 可能会诡异
    				switch ((*itb) -> typ) {
    					case Multi_s : result -> value = lhs -> value * rhs -> value; break;
    					case Divide_s : result -> value = lhs -> value / rhs -> value; break;
    					case Module_s : result -> value = lhs -> value % rhs -> value; break;
    					case Plus_s : result -> value = lhs -> value + rhs -> value; break;
    					case Minus_s : result -> value = lhs -> value - rhs -> value; break;
    					case lEq_s : result -> value = lhs -> value <= rhs -> value; break;
    					case rEq_s : result -> value = lhs -> value >= rhs -> value; break;
    					case Less_s : result -> value = lhs -> value < rhs -> value; break;
    					case Greater_s : result -> value = lhs -> value > rhs -> value; break;
    					case Eq_s : result -> value = lhs -> value == rhs -> value; break;
    					case nEq_s : result -> value = lhs -> value != rhs -> value; break;
    					case Xor_s : result -> value = lhs -> value ^ rhs -> value; break;
    					case And_s : result -> value = lhs -> value && rhs -> value; break;
    					case Or_s : result -> value = lhs -> value || rhs -> value; break;
    					case valueEq_s : lhs -> value = rhs -> value; break;
    				}
    				if (EnableDebug) {
    					cout << "Calc " << lhs -> value << " " << rhs -> value << " " << result -> value << " " << (*itb) -> typ << endl;
    				}
    				Node_t * remain = (*itb) -> pre;
    				if ((*itb) -> typ != valueEq_s) // lhs -> value = result -> value;
    				/* else */ (*itb) -> pre -> val = result;
    				// 留下LHS,赋值什么的都不怕
    				remain -> nxt = (*itb) -> nxt -> nxt;
    				if ((*itb) -> nxt -> nxt != NULL) (*itb) -> nxt -> nxt -> pre = remain;
    				delete (*itb) -> nxt; delete (*itb);
    			}
    			// 注意销毁链表
    		}
    		// cout << "???" << endl;
    		_Object_base * res;
    		if (fir != NULL) {
    			if (!fir -> val -> isReference()) {
    				_Variable_base * ret = new _Variable_base;
    				ret -> value = static_cast<_Variable_base*> (fir -> val) -> value;
    				res = ret;
    			} else res = fir -> val;
    			delete fir;
    		} else {
    			_Variable_base * ttt = new _Variable_base;
    			ttt -> value = 0;
    			res = static_cast<_Object_base*> (ttt);
    		}
    		if (EnableDebug) {
    			cout << "Returned With " << static_cast<_Variable_base*> (res) -> value << endl;
    		}
    		return res;
    	}
    } Expression;
    
    _Object_base * _Function_base::getValue() {
    	// Set Argument into Global@FunctionID@XX
    	// Function Variables : Global@FuntionID@st${count}@XX
    	++FunctionCallDep;
    	// Return Flag : Global@sum@stX@RetXX
    	string tokenpre = token + "@st" + StringUtil.int_to_string(FunctionCallDep) + "@MainProc@";
    	string flaglike = StringUtil.toReturnFlag(tokenpre);
    	Expression.setFlag(tokenpre, FlagFalse);
    	_Object_base * res = Expression.run(tokenpre, begin, end);
    	--FunctionCallDep;
    	return res;
    }
    
    // Builtin Functions
    class __builtin_putchar_base : public _Function_base {
    public:
    	virtual _Object_base * getValue() {
    		_Object_base * res = MemoryPool.findVariable(
    				this -> getToken() + "@st" + StringUtil.int_to_string(FunctionCallDep + 1) + "@" + NameManager.getIDs("__putch")
    													);
    		putchar(static_cast<_Variable_base*> (res) -> value);
    		return res;
    	}
    	__builtin_putchar_base() {
    		this -> setToken("Global@" + NameManager.getIDs("putchar"));
    		this -> argAppend("__putch");
    	}
    } ;
    
    class __builtin_start_debug : public _Function_base {
    public:
    	virtual _Object_base * getValue() { EnableDebug = true; _Variable_base * res = new _Variable_base; res -> value = 0; return static_cast<_Object_base*> (res); }
    	__builtin_start_debug() {
    		this -> setToken("Global@" + NameManager.getIDs("__builtin_start_debug"));
    	}
    } ;
    
    class __builtin_stop_debug : public _Function_base {
    public:
    	virtual _Object_base * getValue() { EnableDebug = false; _Variable_base * res = new _Variable_base; res -> value = 0; return static_cast<_Object_base*> (res); }
    	__builtin_stop_debug() {
    		this -> setToken("Global@" + NameManager.getIDs("__builtin_stop_debug"));
    	}
    } ;
    
    class Main {
    public:
    	Main() {
    		// Input Buff Stream
    		ReadinBuffer.init();
    		ProgramBuffer.init();
    		while (ProgramBuffer.haveNext()) StatementLine.append(ProgramBuffer.nextStatement());
    		StatementLine.init();
    		// Set Global Variables
    		_Variable_base * endlt = new _Variable_base;
    		endlt -> value = EndlFlag;
    		endlt -> setReference(true);
    		MemoryPool.setVariable("Global@" + NameManager.getIDs("endl"), endlt);
    		__builtin_putchar_base * putchar_t = new __builtin_putchar_base;
    		MemoryPool.setFunction("Global@" + NameManager.getIDs("putchar"), static_cast<_Object_base*> (putchar_t));
    		__builtin_start_debug * start_debug = new __builtin_start_debug;
    		MemoryPool.setFunction("Global@" + NameManager.getIDs("__builtin_start_debug"), static_cast<_Object_base*> (start_debug));
    		__builtin_stop_debug * stop_debug = new __builtin_stop_debug;
    		MemoryPool.setFunction("Global@" + NameManager.getIDs("__builtin_stop_debug"), static_cast<_Object_base*> (stop_debug));
    	}
    	
    	void run() {
    		Expression.run(string("Global@"), 0, StatementLine.size() - 1);
    		MemoryPool.call("Global@" + NameManager.getIDs("main"));
    	}
    } ;
    
    }
    
    int main() {
    	Mirai::Main runner;
    	runner.run();
    	return 0;
    }
    
  • 相关阅读:
    最佳实践:腾讯HTAP数据库TBase助力某省核心IT架构升级
    数据库中间件
    深入理解JVM—JVM内存模型
    【实战解析】基于HBase的大数据存储在京东的应用场景
    Only the storage referenced by ptr is modified. No other storage locations are accessed by the call.
    京东11.11:京麦服务市场交易平台备战实践
    gitignore 不起作用的解决办法 不再跟踪 让.gitignore生效,跟踪希望被跟踪的文件
    JAVA中的array是通过线性表还是链表实现的呢?
    在链表中,元素的"位序"概念淡化,结点的"位置"概念淡化
    微软开源项目提供企业级可扩展推荐系统最新实践指南
  • 原文地址:https://www.cnblogs.com/daklqw/p/9991248.html
Copyright © 2011-2022 走看看