mini_c.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 354 行
HPP
354 行
/*============================================================================= Copyright (c) 2001-2007 Joel de Guzman Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#if !defined(BOOST_SPIRIT_MINI_C)#define BOOST_SPIRIT_MINI_C#include <boost/config/warning_disable.hpp>#include <boost/spirit/include/qi.hpp>#include <boost/spirit/include/phoenix_core.hpp>#include <boost/spirit/include/phoenix_container.hpp>#include <boost/spirit/include/phoenix_statement.hpp>#include <boost/spirit/include/phoenix_operator.hpp>#include <boost/lexical_cast.hpp>#include <iostream>#include <fstream>#include <string>#include <vector>using namespace boost::spirit;using namespace boost::spirit::qi;using namespace boost::spirit::ascii;using namespace boost::spirit::arg_names;using boost::phoenix::function;using boost::phoenix::ref;using boost::phoenix::size;///////////////////////////////////////////////////////////////////////////////// The Virtual Machine///////////////////////////////////////////////////////////////////////////////enum byte_code{ op_neg, // negate the top stack entry op_add, // add top two stack entries op_sub, // subtract top two stack entries op_mul, // multiply top two stack entries op_div, // divide top two stack entries op_not, // boolean negate the top stack entry op_eq, // compare the top two stack entries for == op_neq, // compare the top two stack entries for != op_lt, // compare the top two stack entries for < op_lte, // compare the top two stack entries for <= op_gt, // compare the top two stack entries for > op_gte, // compare the top two stack entries for >= op_and, // logical and top two stack entries op_or, // logical or top two stack entries op_load, // load a variable op_store, // store a variable op_int, // push constant integer into the stack op_true, // push constant 0 into the stack op_false, // push constant 1 into the stack op_jump_if, // jump to an absolute position in the code if top stack // evaluates to false op_jump, // jump to an absolute position in the code op_stk_adj, // adjust the stack (for args and locals) op_call, // function call op_return // return from function};class vmachine{public: vmachine(unsigned stackSize = 4096) : stack(stackSize) { } int execute( std::vector<int> const& code // the program code , std::vector<int>::const_iterator pc // program counter , std::vector<int>::iterator frame_ptr // start of arguments and locals ); std::vector<int> stack;};///////////////////////////////////////////////////////////////////////////////// A generic compiler that compiles 1 to 3 codes///////////////////////////////////////////////////////////////////////////////struct function_info{ int arity; int address;};struct compile_op{ template <typename A, typename B = unused_type, typename C = unused_type> struct result { typedef void type; }; compile_op(std::vector<int>& code) : code(code) { } void operator()(int a) const { code.push_back(a); } void operator()(int a, int b) const { code.push_back(a); code.push_back(b); } void operator()(int a, int b, int c) const { code.push_back(a); code.push_back(b); code.push_back(c); } // special overload for function calls void operator()(function_info const& info, int got_nargs, bool& parse_result) const { if (got_nargs == info.arity) { code.push_back(op_call); code.push_back(info.arity); code.push_back(info.address); } else { parse_result = false; // fail the parse std::cerr << "wrong number of args" << std::endl; } } std::vector<int>& code;};///////////////////////////////////////////////////////////////////////////////// Our error handler///////////////////////////////////////////////////////////////////////////////struct error_handler_{ template <typename, typename, typename> struct result { typedef void type; }; template <typename Iterator> void operator()( std::string const& what , Iterator err_pos, Iterator last) const { std::cout << "Error! Expecting " << what // what failed? << " here: \"" << std::string(err_pos, last) // iterators to error-pos, end << "\"" << std::endl ; }};function<error_handler_> const error_handler = error_handler_();///////////////////////////////////////////////////////////////////////////////// A functor that adds variables to our (variables) symbol-table///////////////////////////////////////////////////////////////////////////////struct var_adder{ template <typename> struct result { typedef void type; }; var_adder(symbols<char, int>& vars, int& nvars) : vars(vars), nvars(nvars) { } void operator()(std::string const& var) const { vars.add(var.begin(), var.end(), nvars++); }; symbols<char, int>& vars; int& nvars;};///////////////////////////////////////////////////////////////////////////////// A functor that adds functions to our (function) symbol-table///////////////////////////////////////////////////////////////////////////////struct function_adder{ template <typename, typename, typename> struct result { typedef void type; }; function_adder(symbols<char, function_info>& functions) : functions(functions) { } void operator()(std::string const& function_id, int arity, int address) const { function_info info = {arity, address}; functions.add(function_id.begin(), function_id.end(), info); }; symbols<char, function_info>& functions;};///////////////////////////////////////////////////////////////////////////////// A functor that resets the function-related state variables///////////////////////////////////////////////////////////////////////////////struct function_state_reset{ template <typename> struct result { typedef void type; }; function_state_reset( std::vector<int>& code , symbols<char, int>& vars , int& nvars) : code(code) , vars(vars) , nvars(nvars) { } void operator()(int address) const { code[address+1] = nvars; nvars = 0; // reset vars.clear(); // reset }; std::vector<int>& code; symbols<char, int>& vars; int& nvars;};///////////////////////////////////////////////////////////////////////////////// White-space and comments grammar definition///////////////////////////////////////////////////////////////////////////////template <typename Iterator>struct white_space : grammar<Iterator>{ white_space() : white_space::base_type(start) { start = space // tab/space/cr/lf | "/*" >> *(char_ - "*/") >> "*/" // C-style comments ; } rule<Iterator> start;};///////////////////////////////////////////////////////////////////////////////// Our expression grammar and compiler///////////////////////////////////////////////////////////////////////////////template <typename Iterator>struct expression : grammar<Iterator, white_space<Iterator> >{ expression( std::vector<int>& code , symbols<char, int>& vars , symbols<char, function_info>& functions); typedef white_space<Iterator> white_space; rule<Iterator, white_space> expr, equality_expr, relational_expr , logical_expr, additive_expr, multiplicative_expr , unary_expr, primary_expr, variable ; rule<Iterator, locals<function_info, int>, white_space> function_call; std::vector<int>& code; symbols<char, int>& vars; symbols<char, function_info>& functions; function<compile_op> op;};///////////////////////////////////////////////////////////////////////////////// Our statement grammar and compiler///////////////////////////////////////////////////////////////////////////////template <typename Iterator>struct statement : grammar<Iterator, white_space<Iterator> >{ statement(std::vector<int>& code, symbols<char, function_info>& functions); typedef white_space<Iterator> white_space; std::vector<int>& code; symbols<char, int> vars; symbols<char, function_info>& functions; int nvars; bool has_return; expression<Iterator> expr; rule<Iterator, white_space> statement_, statement_list, var_decl, compound_statement , return_statement; rule<Iterator, locals<int>, white_space> if_statement; rule<Iterator, locals<int, int>, white_space> while_statement; rule<Iterator, std::string(), white_space> identifier; rule<Iterator, int(), white_space> var_ref; rule<Iterator, locals<int>, white_space> assignment; rule<Iterator, void(int), white_space> assignment_rhs; function<var_adder> add_var; function<compile_op> op;};///////////////////////////////////////////////////////////////////////////////// Our program grammar and compiler///////////////////////////////////////////////////////////////////////////////template <typename Iterator>struct program : grammar<Iterator, white_space<Iterator> >{ program(std::vector<int>& code); typedef white_space<Iterator> white_space; std::vector<int>& code; rule<Iterator, std::string(), white_space> identifier; rule<Iterator, white_space> start; typedef locals< std::string // function name , int // address > function_locals; symbols<char, function_info> functions; statement<Iterator> statement; rule<Iterator, function_locals, white_space> function; boost::phoenix::function<function_adder> add_function; boost::phoenix::function<function_state_reset> state_reset; boost::phoenix::function<compile_op> op;};#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?