60pts求助
查看原帖
60pts求助
871004
Manki23333333楼主2024/7/4 00:12
#include <bits/stdc++.h>

#define LANG_NAME CYaRon
#define VAR_COMMAND "var"
#define PRINT_COMMAND "yosoro"
#define SET_COMMAND "set"
#define IF_COMMAND "ihu"
#define FOR_COMMAND "hor"
#define WHILE_COMMAND "while"

using namespace std;

string line;

typedef unsigned int uint;

struct StackNode {
	int sta;
	int line;
	string for_var;
	string from;
	string to;
};

class CTool {
	public:
		static vector <string> splitby (string str, const char *a) {
			int last = -1;
			vector <string> ret;
			
			int len = strlen (a);
			
			for (uint i = 0 ; i < str. size () ; i ++) {
				for (int j = 0 ; j < len ; j ++) {
					if (str [i] == a [j] || i == str. size () - 1) {
//						if (i - last - (last == -1) != 0)
						auto temp = str. substr (last + 1, i - last - 1 + (i == str. size () - 1));
//						if (temp. size () > 0) {
							ret. push_back (temp);
							last = i;
//						}

						break;
					}
				}
			}
			
			return ret;
		}
		
		static int string_to_int (string str) {
			int ret = 0;
			int p = 1;
			
			for (int i = str. size () - 1 ; i >= 0 ; i --) {
				if (str [i] == '-') {
					ret *= -1;
					break;
				} 
				
				ret += (str [i] - '0') * p;
				p *= 10;
			}
			
//			cout << ret;
			
			return ret;
		}
};

enum {
	IDIE = 0,
	VAR,
	IF,
	IF_SKIP,
	FOR, 
	FOR_SKIP,
	WHILE,
	WHILE_SKIP
};

class LANG_NAME {
	public:
		enum Types {
			UNDEFINED = 0,
			INT,
			ARR,
		};
				
		map <string, Types> string2type; // 将字符串映射为Type
		
		map <string, Types> vars_type; // 变量类型
		map <string, int> vars_v; // 整形变量值,如果是数组表示从几开始
		map <string, vector <int> > vars_a; // 整形数组值
		
		LANG_NAME () {
			string2type ["int"] = INT;
			string2type ["array"] = ARR;
		}
		
		// 最开始以为类型还有字符串!!!!!气死我了!!!!
		
		bool Bools (string str) { // 做判断
			auto splited = CTool :: splitby (str, ",");
			vector <string> split2;
			for (int i = 0 ; i < splited. size () ; i ++) {
				if (!splited [i]. empty ()) {
					split2. push_back (splited [i]);
//					cout << splited [i] << " ";
				}
			}
			
//			cout << split2. size ();

			int a = CTool :: string_to_int (SolveExp (split2 [1]));
			int b = CTool :: string_to_int (SolveExp (split2 [2]));
			
			string op = "";
			for (int i = 0 ; i < split2 [0]. size () ; i ++) {
				if (split2 [0] [i] != ' ') {
					op += split2 [0] [i];
				}
			}
			
//			cout << (op == "le");
//			cout << a << " " << b;
			
			if (op == "eq")
				return a == b;
			if (op == "neq")
				return a != b;
			if (op == "lt")
				return a < b;
			if (op == "gt")
				return a > b;
			if (op == "le")
				return a <= b;
			if (op == "ge")
				return a >= b;
			
			return false;
		}
		
		string SolveExp (string str) {
//			return str;

//			cout << "Solve: " << str << ": \n";

			int ret = 0; // 返回值
			int f = 1; // 符号
			int constnow = 0; // 现在的常数
			
			bool in_arr = false;
			
			string var;
			string atmp; // 给数组用的
			
			for (uint i = 0 ; i < str. size () ; i ++) {
				char c = str [i];
				
				if (c == ' ')
					continue;
					
				if (in_arr && c != ']') {
					atmp += c;
					continue;
				}
				
				if (c == '-') {
					if (!var. empty ()) {
						constnow = vars_v [var];
						var = "";
					}
					
					ret += f * constnow;
					f = -1;
					constnow = 0;
					continue;
				}
			
				if (c == '+') {
					if (!var. empty ()) {
						constnow = vars_v [var];
						var = "";
					}
					ret += f * constnow;
					f = 1;
					constnow = 0;
					continue;
				}
				
				if ('0' <= c && c <= '9') {
					constnow *= 10;
					constnow += (c - '0');
					continue;
				}
				
				if ('a' <= c <= 'z') {
//					cout << "!" << c << "!";
					if (c == '[' || c == ']' || in_arr)
						{}
					else var += c;
				}
				
				if (c == '[') {
					in_arr = true;
				}
				
				if (c == ']') {
					in_arr = false;
					
					int index = CTool :: string_to_int (SolveExp (atmp));
					
//					cout << vars_a [var]. size () << " ";
					int value = vars_a [var] [index - vars_v [var]];
					
					var = "";
					atmp = "";
					
					constnow = value;
				}
			}
			
			if (!var. empty ()) {
//				cout << 1; 
				constnow = vars_v [var];
			}	
			
//			cout << f << " " << constnow << " " << ret << " ";
			ret += f * constnow;
			
//			cout << str << " ans = "  << ret << endl;
			
			return to_string (ret);
		}
		
		void SolveCommand (string str) {
			auto splited = CTool :: splitby (str, ", ");
			
			if (splited [0] == PRINT_COMMAND) {
				cout << SolveExp (str. substr (strlen (PRINT_COMMAND) + 1)) << " ";
			}
			
			if (splited [0] == SET_COMMAND) {
				auto arg = str. substr (strlen (SET_COMMAND) + 1);
				
				string var = "";
				string newvar = "";
				
				for (uint i = 0 ; i < arg. size () ; i ++) {
					if (arg [i] == ',') {
						var = arg. substr (0, i);
//						cout << arg. substr (i + 1);
						newvar = SolveExp (arg. substr (i + 1));
						break;
					}
				}
				
//				cout << newvar;
				
				if (var. find ("[") == string :: npos) {
//					cout << 1 << " ";
					vars_v [var] = CTool :: string_to_int (newvar);
//					cout << vars_v [var] << " ";
				} else {
					auto arr_name = var. substr (0, var. find ("["));
					auto tmp1 = 
							var. substr (
								var. find ("[") + 1 // "[" 后面的一个
							) // "*INDEX*]"
							;
					auto tmp2 = tmp1. substr (0, tmp1. size () - 1);
					int index = CTool :: string_to_int (SolveExp (tmp2));
					
					vars_a [arr_name] [index - vars_v [arr_name]] = CTool :: string_to_int (newvar);
//					cout << index - vars_v [arr_name];
				}
			}
		}
		
		void CreateVar (string str) {
			for (uint i = 0 ; i < str. size () ; i ++) {
				if (str [i] != ' ') {
//					cout << i;
					str = str. substr (i);
					break;
				}
			}
			
//			cout << str;
			
			const char c_table [] = ":,][";
			auto splited = CTool :: splitby (str, c_table);
//			cout << splited. size ();
			
			string name = splited [0];
			string type = splited [1];
			
			Types t = string2type [type];
			vars_type [name] = t;
			
//			cout << t;
			
			if (splited. size () > 2) { // 是数组
				vars_a [name]. clear ();
 
// 				cout << splited [3] << " ";
				
				int left = 0, right = 0;
				bool flag = false;
				for (uint i = 0 ; i < splited [3]. size () ; i ++) {
					if (splited [3] [i] == ' ' || splited [3] [i] == ']')
						continue;
					if (splited [3] [i] == '.') {
						flag = true;
						continue;
					}
//					if (!isdigit (splited [3] [i] - '0')) {
//						continue;
//					}
					
					if (!flag) {
						left *= 10;
						left += (splited [3] [i] - '0');
					} else {
//						cout << right << " ";
						right *= 10;
						right += (splited [3] [i] - '0');
					}
				}
				
//				cout << left << " " << right;
				
				for (int i = 0 ; i <= right ; i ++) {
					vars_a [name]. push_back (0);
//					cout << i;
				}
				
//				int right = CTool :: string_to_int (range [1]);
				
//				cout << range [1];

				vars_v [name] = left;
			} else {
				vars_v [name] = 0;
			}
			
//			cout << "Debug: Create " << type << " 's " << name << endl;
		}
		
		StackNode SolveForInfomation (string str, int line) {
			StackNode ret = {FOR_SKIP, line, "", "", ""};
			
			string str2 = str. substr (str. find (FOR_COMMAND) + strlen (FOR_COMMAND));
			
			auto splited1 = CTool :: splitby (str2, ", ");
			vector <string> splited;
			
			for (auto s : splited1) {
				if (!s. empty ()) {
					splited. push_back (s);
				}
			}
			
			ret. for_var = splited [0];
			ret. from = splited [1];
			ret. to = splited [2];
			
//			cout << splited [2];
			
			return ret;
		}
};

LANG_NAME lang;

string codes [1005];
int nowcode = 1;
int allcode = 0;

int main () {
//	freopen ("P3659_2.in", "r", stdin);
	
//	cout << 1;
	
	int lefts = 0;
	int rights = 0;
	
	stack <StackNode> sta; // 状态和行数
	sta. push ({IDIE, 0});
	
	while (true) {
//		cout  << "\n" << allcode << "-" << nowcode << " ";
		
		if (nowcode > allcode) { // 如果现在是最新的代码
			if (!getline (cin, line)) { // getline读入
				break;
			}
			codes [++ allcode] = line;
			nowcode ++;
		} else {
			line = codes [nowcode ++];
//			cout << 1;
//			cout << "USE_OLD_CODES " << line;
//			cout << sta. top (). sta;
		}
		
		for (uint i = 0 ; i < line. size () ; i ++) {
			if (line [i] != ' ') {
				line = line. substr (i);
				break;
			}
		}
		
		auto top = sta. top ();
		
		if (line [0] == '#') // 注释掉了
			continue;
		
		if (line [0] == '{')
			lefts ++;

		if (line [0] == '}') {
			rights ++;
			
//			cout << "RG";
			if (top. sta == IF) {
				sta. pop ();
				continue;
			}

			if (top. sta == FOR_SKIP || top. sta == FOR) {
				char buf [255];
				sprintf (buf, "lt, %s, %s", top. for_var. data (), top. to. data ());
//				cout << lang. vars_v ["i"] << "-";
//				cout << buf << " ";
				if (lang. Bools ((string) buf)) {
					nowcode = top. line;
//					cout << nowcode;
//					allcode ++;
//					cout << top. for_var;
					sprintf (buf, "set %s, %s+1", top. for_var. data (), top. for_var. data ());
					lang. SolveCommand (buf);
					
//					cout << lang. vars_v ["i"] << " ";
//					cout << nowcode << "Repeat";
					auto tmp = top;
					tmp. sta = FOR;
					sta. pop ();
					sta. push (tmp);
				} else {
					sta. pop ();
//					sta. push ({, nowcode});
				}
			} else if (top. sta == WHILE) {
				nowcode = top. line - 1;
			} else {
//				cout << 7;
				sta. pop ();
			}
		}
		
		if (top. sta == IF_SKIP || top. sta == FOR_SKIP || top. sta == WHILE_SKIP)
			continue;
			
		if (line. find (VAR_COMMAND) != string :: npos) {
			sta. push ({VAR, nowcode});
			continue;
		}
		
		if (line. find (IF_COMMAND) != string :: npos) {
			if (!lang. Bools (line. substr (line. find (IF_COMMAND) + strlen (IF_COMMAND) + 1))) {
				sta. push ({IF_SKIP, nowcode});
				continue;
			}
			sta. push ({IF, nowcode});
			continue;
//			cout << flag3;
		}
		
		if (line. find (FOR_COMMAND) != string :: npos) {
			auto t = lang. SolveForInfomation (line, nowcode);
			sta. push (t);
			char buf [255];
			sprintf (buf, "%s:int", t. for_var. data ());
			lang. CreateVar (buf);
			sprintf (buf, "set %s, %s-1", t. for_var. data (), t. from. data ());
			lang. SolveCommand (buf);
			continue;
		}
		
		if (top. sta == VAR) {
			if (line. size () > 2)
				lang. CreateVar (line);
		}

		if (line. find (WHILE_COMMAND) != string :: npos) {
			int pos = line. find (WHILE_COMMAND) + strlen (WHILE_COMMAND);
			string rule = line. substr (pos);
//			cout << lang. Bools (rule) << " ";
			if (lang. Bools (rule)) {
				if (top. sta != WHILE || (top. sta == WHILE && top. line != nowcode)) {
					sta. push ({WHILE, nowcode, rule});
				}
			} else {
				if (top. sta == WHILE) 
					sta. pop ();
				sta. push ({WHILE_SKIP, nowcode, rule});
			}
			continue;
		}
		
		if (line [0] == ':') {
//			cout << 1;
//			cout << top;
			lang. SolveCommand (line. substr (1));
		}
		
//		cout << top. sta;
	}
	return 0; 
}
2024/7/4 00:12
加载中...