SDUT【编译原理】C - 小型Basic编译器问题

出题人真的太beibi,在第八个测试点卡了两三个小时,直到看到:

"  程序执行时会产生一个或多个输出,可以中断(即程序不会进入无限循环状态)"

恼(

思路来源:

1.编译器-符号表,操作系统-全局描述符表;

2.cpu取指令,执行过程;

3.数据/代码在内存中的组织形式。

类设计:

GVT的起名来源于全局描述符表(global  Descriptor table --- GDT)

突发奇想造了个GVT(global variable table)。。。

思路简述:

1.读取全部的样例并存入代码段(_code_section),行号对应代码段的下标;

2.将行号抽象为地址,ptr抽象为cpu,执行Run(),使得ptr从_code_section中一行一行顺序取出样例代码;

3.每取出一行样例代码即对其进行操作解析(parse_operator);

4.根据解析的操作来决定是否进行表达式解析(parse_expression);

5.解析到STOP 或者 超过10000次执行(通过interrupt_times控制程序不会进入无限循环状态)即结束程序。

具体代码:

冗余的代码较多,,,仅供参考。。。

#include <iostream>
#include <string>
#include <map>
#include <vector>

class TinyBasicParser {
private:
	int ptr;
	int len_code;
	int interrupt_times;
	std::map<char, int> GVT = {};
	std::vector<std::string> _code_section{110};

public:
	TinyBasicParser() {
		ptr = 0;
		len_code = 0;
		interrupt_times = 0;
		this->_code_section[0] = "_start";
	}

	std::string delspace_front(const std::string& _str) {
		std::string temp_str = _str;

		for (int i = 0; i < temp_str.length(); i++) {
			if (temp_str[i] == ' ')
				continue;
			temp_str.erase(0, i);
			return temp_str;
		}

		return "";
		
	}

	int insert_code(const std::string& _str) {
		this->len_code++;
		if (_str == "")
			return -1;

		std::string temp_str = _str;
		
		std::string _num = "";
		for (int i = 0; i < _str.length(); i ++) {
			if (_str[i] == ' ') {
				temp_str.erase(0, i+1);
				break;
			}
			_num += _str[i];
		}

		temp_str = this->delspace_front(temp_str);

		this->_code_section[std::stoi(_num)] = temp_str;
		return 0;
	}

	int parse_operator(const std::string& _str) {
		std::string temp_str = "";
		std::string exp_start = "";
		std::string exp_end = "";
		for (int i = 0; i < _str.length(); i ++) {
			if (_str[i] == ' ') {
				exp_start = _str.substr(i + 1, _str.length() - i);
				break;
			}
			temp_str += _str[i];

		}
		exp_start = this->delspace_front(exp_start);
		if (temp_str == "LET") {

			exp_end = exp_start.substr(2, _str.length() - 2);
			int res = parse_expression(exp_end);
			this->GVT[exp_start[0]] = res;
		}
		else if (temp_str == "PRINT") {
			exp_end = exp_start;
			int res = this->GVT[exp_end[0]];
			std::cout << exp_end << '=' << res << std::endl;
		}
		else if (temp_str == "GOTO") {
			exp_end = exp_start;
			int res = parse_expression(exp_end);
			this->ptr = res - 1;
		}
		else if (temp_str == "IF") {
			exp_end = exp_start;
			int res = parse_expression(exp_end);
			if (!res)
				this->ptr++;
		}
		else if (temp_str == "STOP") {
			return -1;
		}

		return 0;
	}

	int parse_expression(const std::string& _exp) {
		for (int i = 0; i < _exp.length(); i++) {
			if ((int)_exp[i] == 43) {
				int x = this->GVT[_exp[i - 1]];
				int y = this->GVT[_exp[i + 1]];
				return (x + y)%10001;
			}
			else if ((int)_exp[i] == 62) {
				int x = this->GVT[_exp[i - 1]];
				int y = this->GVT[_exp[i + 1]];
				return x > y;
			}
		}

		return std::stoi(_exp)%10001;

	}

	int Run() {
		while (this->ptr < this->len_code) {
			this->ptr++;
			int status = this->parse_operator(this->_code_section[ptr]);
			if (status == -1) {
				break;
			}
			this->interrupt_times++;

			if (this->interrupt_times >= 10001) {
				break;
			}

		}
		return 0;
	}

};

int main() {

	TinyBasicParser parser = TinyBasicParser();
	std::string str = "";
	while (getline(std::cin, str)) {
		if (str == "")
			break;
		int temp_status = parser.insert_code(parser.delspace_front(str));
		if (temp_status == -1)
			return 0;
	}
	int _status = parser.Run();
	return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值