【集训队互测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 == '\n' || x == '\r' || x == '\t'; }
    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 == '\n') *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;
}

猜你喜欢

转载自www.cnblogs.com/daklqw/p/9991248.html