⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 script.h

📁 一个脚本语言的解释器
💻 H
📖 第 1 页 / 共 2 页
字号:
#include <string>
#include "filebuffer.h"
#include "cpptoken.h"
#include "except.h"
#include "scripttreedef.h"

__SCRIPT_NAMESPACE__

using std::string;
using std::vector;

class script_file
{
	typedef CppToken<FileBuffer::iterator> token_t;
	_default_handler _handler;
public:
	script_file()
	{
		_df = new debug_files();
	}

	script_file(exception_handler_base * handler) : _handler(handler)
	{
		_df = new debug_files();
	}

	~script_file()
	{
		DEREF(_df);
	}

	bool read_file(const string &filename)
	{
		std::string lastfile = CurrentFile::Get();
		CurrentFile::Set(filename.c_str());
		FileBuffer fb;
		bool succeed = false;
		_df->add_filename(filename);
		if(GetFileBuffer(filename, fb))
		{
			succeed = read_file(fb);
		}
		else
		{
			_handler(EFileNotExist(filename.c_str()));
		}
		CurrentFile::Set(lastfile.c_str());
		return succeed;
	}

	bool read_file(FileBuffer &fb)
	{
		fb << "\n\n\n";
		token_t token(fb.begin(), fb.end());
		return read_file(token);
	}

	bool read_file(token_t token)
	{
		bool haserror = false;
		while(true)
		{
			try
			{
				token_t tok(token);
				++tok;
				read_function(token);
				LAUNCH(S_BATCH);
			}
			catch(EReachEndOfFile /*e*/)
			{
				break;
			}
			catch(CompileBaseException &e)
			{
				haserror = true;
				_handler(e);
				try
				{
					while(token != "function") ++token;
				}
				catch(EReachEndOfFile /*e*/)
				{
					break;
				}
			}
			catch(EBatchExceptions &be)
			{
				be.for_each(_handler);
				CLEAR(S_BATCH);
				functions.remove(functions[functions.count()-1]);
				try
				{
					while(token != "function") ++token;
				}
				catch(EReachEndOfFile /*e*/)
				{
					break;
				}
			}
		}
		return !haserror;
	}
	
	ref_list<script_function_tree> functions;

private:
	bool is_identifier(const std::string & id)
	{
		return CppLex::IsLegal(id.begin(), id.end());
	}
	void read_function(token_t &token)
	{
		if(token != "function"  && token != "object")
		{
			ERROR_TOK(UnexpectedToken, "non function declaration is not permitted.", token);
			return;
		}
		token++;
		script_function_tree * func = new script_function_tree(token.ToString());
		token++;
		id_list * param = read_parameter(token);
		func->set_param_list(param);
		statement * s = read_compound_statement(token);
		func->set_body(s);
		functions.add(func);
		DEREF(param);
		DEREF(s);
		DEREF(func);
	}

private:

	id_list * read_parameter(token_t &token)
	{
		if(token != '(')
		{
			ERROR_TOK(UnexpectedToken, "list should be start with '('.", token);
			return 0;
		}
		++token; // skip '('
		id_list * il = read_id_list(token);
		if(token != ')')
			ERROR_TOK(UnexpectedToken, "parameter list should be terminated with ')'", token);
		else
			++token; // skip ')'
		return il;
	}

	id_list * read_id_list(token_t &token)
	{
		id_list * il = new id_list();
		if(is_identifier(token.ToString()))
		{
			il->add_id(token.ToString());
			++token;
		}
		while(token == ',')
		{
			++token; // skip ','
			if(is_identifier(token.ToString()))
				il->add_id(token.ToString());
			else
				ERROR_TOK(IllegalIdentifier, "list item should be identifier", token);
			++token; // skip id
		}
		return il;
	}

	compound_statement * read_compound_statement(token_t &token)
	{
		if(token != '{') 
		{
			ERROR_TOK(UnexpectedToken, "compund statement should start with '{'.", token);
			return 0;
		}
		++token; // skip '{'
		compound_statement * cs = new compound_statement();
		while(token != '}')
		{
			statement *s = read_statement(token);
			cs->childs.add(s);
			DEREF(s);
		}
		try
		{
			++token; // skip '}'
		}
		catch(EReachEndOfFile){}
		return cs;
	}

	statement * read_statement(token_t &token)
	{
		if(token == '{')
			return read_compound_statement(token);
		if(token == "if")
			return read_if_statement(token);
		else if(token == "do")
			return read_do_statement(token);
		else if(token == "while")
			return read_while_statement(token);
		else if(token == "for")
			return read_for_statement(token);
		else if(token == "break" || token == "continue" || token == "return")
			return read_jump_statement(token);
		else
			return read_expression_statement(token);
	}

	statement * read_if_statement(token_t &token)
	{
		++token; // skip 'if'
		expression * cond = read_condition(token);
		statement_if * si = new statement_if();
		si->set_condition(cond);
		DEREF(cond);
		statement *s = read_statement(token);
		si->set_truth_statement(s);
		DEREF(s);
		if(token == "else")
		{
			++token ; // skip 'else'
			s = read_statement(token);
			si->set_false_statement(s);
			DEREF(s);
		}
		return si;
	}

	expression * read_condition(token_t &token)
	{
		if(token != '(')
		{
			ERROR_TOK(UnexpectedToken, "read_condition(): '(' is expected.", token);
			return 0;
		}
		++token;
		expression * exp = read_expression(token);
		if(token != ')')
			ERROR_TOK(UnexpectedToken, "read_condition(): ')' is expected.", token);
		else
			++token;
		return exp;
	}

	statement * read_do_statement(token_t &token)
	{
		++token; // skip 'do'
		statement_do * sd = new statement_do();
		statement *s = read_statement(token);
		sd->set_loop_statement(s);
		DEREF(s);
		if(token != "while")
		{
			ERROR_TOK(UnexpectedToken, "read_do_statment():'while' is expected.", token);
			return sd;
		}
		++token; // skip 'while'
		expression * cond = read_condition(token);
		sd->set_loop_condition(cond);
		DEREF(cond);
		if(token != ';')
			ERROR_TOK(UnexpectedToken, "read_do_statment(): ';' is expected.", token);
		else ++token; // skip ';'
		return sd;
	}

	statement * read_while_statement(token_t & token)
	{
		++token; // skip 'while'
		statement_while * sw = new statement_while();
		expression * cond = read_condition(token);
		sw->set_loop_condition(cond);
		DEREF(cond);
		statement *s = read_statement(token);
		sw->set_loop_statement(s);
		DEREF(s);
		return sw;
	}

	statement * read_for_statement(token_t &token)
	{
		++token; // skip 'for'
		//if(token == "each") return read_for_each_statement(token);
		statement_for *sf = new statement_for();
		if(token != '(')
		{
			ERROR_TOK(UnexpectedToken, "read_for_statement(): '(' is expected.", token);
			return sf;
		}
		++token; // skip ';'
		statement *s = read_expression_statement(token);
		sf->set_init_statement(s);
		DEREF(s);
		expression * exp = read_expression(token);
		sf->set_loop_condition(exp);
		DEREF(exp);
		if(token != ';')
			ERROR_TOK(UnexpectedToken, "read_for_statement(): ';' is expected.", token);
		else 
			++token; // skip ';'
		exp = read_expression(token);
		sf->set_step_expression(exp);
		DEREF(exp);
		if(token != ')')
			ERROR_TOK(UnexpectedToken, "read_for_statement(): ')' is expected.", token);
		else
			++token; // skip ')'
		s = read_statement(token);
		sf->set_loop_statement(s);
		DEREF(s);
		return sf;
	}

	/*statement * read_for_each_statement(token_t &token)
	{
		++token; // skip 'each'
		statement_for_each *sf = new statement_for_each();
		if(!is_identifier(token.ToString()))
			THROW(IllegalIdentifier, "statement_for_each(): each variable should be identifier.", token);
		sf->set_each_variable(token.ToString());
		++token;
		if(token != "in")
			THROW(UnexpectedTerminator, "statement_for_each(): 'in' is expected.", token);
		++token;
		expression *exp = read_expression(token);
		sf->set_aggaregation(exp);
		DEREF(exp);
		statement * s = read_statement(token);
		sf->set_loop_statement(s);
		DEREF(s);
		return sf;
	}*/

	statement * read_jump_statement(token_t &token)
	{
		if(token == "continue")
		{
			++token;
			if(token != ';')
				ERROR_TOK(UnexpectedToken, "read_jump_statement(): ';' is expected.", token);
			else
				++token; // skip ';'
			return new statement_continue();
		}
		else if(token == "break")
		{
			++token;
			if(token != ';')
				ERROR_TOK(UnexpectedToken, "read_jump_statement(): ';' is expected.", token);
			else
				++token; // skip ';'
			return new statement_break();
		}
		else if(token == "return")
		{
			++token;
			expression * exps = 0;
			if(token != ';')
				exps = read_list_expression(token);
			if(token != ';')
				ERROR_TOK(UnexpectedToken, "read_jump_statement(): ';' is expected.", token);
			else
				++token; // skip ';'
			statement_return *sr = new statement_return();
			sr->set_return_list(exps);
			DEREF(exps);
			return sr;
		}
		else 
		{
			ERROR_TOK(UnknownScriptError, "read_jump_statement(): unknown error", token);
			return 0;
		}
	}

	statement * read_expression_statement(token_t &token)
	{
		expression *exp = 0;
		if(token != ';')
			exp = read_expression(token);
		statement_exp * se = new statement_exp();
		se->set_expression(exp);
		DEREF(exp);
		if(token != ';')
			ERROR_TOK(UnexpectedToken, "read_expression_statement(): ';' is expected.", token);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -