calc2_ast_vm.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 225 行
HPP
225 行
/*============================================================================= Copyright (c) 2001-2008 Joel de Guzman Copyright (c) 2001-2008 Hartmut Kaiser 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)=============================================================================*//////////////////////////////////////////////////////////////////////////////////// A Calculator example demonstrating generation of AST which gets dumped into// a human readable format afterwards.//// [ JDG April 28, 2008 ]// [ HK April 28, 2008 ]/////////////////////////////////////////////////////////////////////////////////#if !defined(SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM)#define SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM#include <boost/variant/recursive_variant.hpp>#include <boost/spirit/include/phoenix_operator.hpp>#include <boost/spirit/include/phoenix_function.hpp>#include <boost/spirit/include/phoenix_statement.hpp>///////////////////////////////////////////////////////////////////////////////// Our AST///////////////////////////////////////////////////////////////////////////////struct binary_op;struct unary_op;struct nil {};struct expression_ast{ typedef boost::variant< nil // can't happen! , int , boost::recursive_wrapper<binary_op> , boost::recursive_wrapper<unary_op> > type; // expose variant types typedef type::types types; // expose variant functionality int which() const { return expr.which(); } // constructors expression_ast() : expr(nil()) {} expression_ast(unary_op const& expr) : expr(expr) {} expression_ast(binary_op const& expr) : expr(expr) {} expression_ast(unsigned int expr) : expr(expr) {} expression_ast(type const& expr) : expr(expr) {} expression_ast& operator+=(expression_ast const& rhs); expression_ast& operator-=(expression_ast const& rhs); expression_ast& operator*=(expression_ast const& rhs); expression_ast& operator/=(expression_ast const& rhs); type expr;};// expose variant functionalitytemplate <typename T>inline T get(expression_ast const& expr){ return boost::get<T>(expr.expr);}enum byte_code{ op_neg = 1, // negate the top stack entry op_pos, // essentially a no-op (unary plus) 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_int, // push constant integer into the stack};///////////////////////////////////////////////////////////////////////////////struct binary_op{ binary_op() {} binary_op( int op , expression_ast const& left , expression_ast const& right) : op(op), left(left), right(right) {} int op; expression_ast left; expression_ast right;};struct unary_op{ unary_op( int op , expression_ast const& right) : op(op), right(right) {} int op; expression_ast right;};inline expression_ast& expression_ast::operator+=(expression_ast const& rhs){ expr = binary_op(op_add, expr, rhs); return *this;}inline expression_ast& expression_ast::operator-=(expression_ast const& rhs){ expr = binary_op(op_sub, expr, rhs); return *this;}inline expression_ast& expression_ast::operator*=(expression_ast const& rhs){ expr = binary_op(op_mul, expr, rhs); return *this;}inline expression_ast& expression_ast::operator/=(expression_ast const& rhs){ expr = binary_op(op_div, expr, rhs); return *this;}// We should be using expression_ast::operator-. There's a bug// in phoenix type deduction mechanism that prevents us from// doing so. Phoenix will be switching to BOOST_TYPEOF. In the// meantime, we will use a phoenix::function below:template <char Op>struct unary_expr{ template <typename T> struct result { typedef T type; }; expression_ast operator()(expression_ast const& expr) const { return unary_op(Op, expr); }};boost::phoenix::function<unary_expr<op_pos> > pos;boost::phoenix::function<unary_expr<op_neg> > neg;///////////////////////////////////////////////////////////////////////////////// A couple of phoenix functions helping to access the elements of the // generated AST///////////////////////////////////////////////////////////////////////////////template <typename T>struct get_element{ template <typename T1> struct result { typedef T const& type; }; T const& operator()(expression_ast const& expr) const { return boost::get<T>(expr.expr); }};boost::phoenix::function<get_element<int> > _int;boost::phoenix::function<get_element<binary_op> > _bin_op;boost::phoenix::function<get_element<unary_op> > _unary_op;///////////////////////////////////////////////////////////////////////////////struct get_left{ template <typename T1> struct result { typedef expression_ast const& type; }; expression_ast const& operator()(binary_op const& bin_op) const { return bin_op.left; }};boost::phoenix::function<get_left> _left;struct get_right{ template <typename T1> struct result { typedef expression_ast const& type; }; template <typename Node> expression_ast const& operator()(Node const& op) const { return op.right; }};boost::phoenix::function<get_right> _right;struct get_op{ template <typename T1> struct result { typedef int type; }; template <typename Node> int operator()(Node const& bin_op) const { return bin_op.op; }};boost::phoenix::function<get_op> _op;#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?