calc2_ast.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 214 行

HPP
214
字号
/*=============================================================================    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);}///////////////////////////////////////////////////////////////////////////////struct binary_op{    binary_op() {}        binary_op(        char op      , expression_ast const& left      , expression_ast const& right)      : op(op), left(left), right(right) {}    char op;    expression_ast left;    expression_ast right;};struct unary_op{    unary_op(        char op      , expression_ast const& right)    : op(op), right(right) {}    char op;    expression_ast right;};inline expression_ast& expression_ast::operator+=(expression_ast const& rhs){    expr = binary_op('+', expr, rhs);    return *this;}inline expression_ast& expression_ast::operator-=(expression_ast const& rhs){    expr = binary_op('-', expr, rhs);    return *this;}inline expression_ast& expression_ast::operator*=(expression_ast const& rhs){    expr = binary_op('*', expr, rhs);    return *this;}inline expression_ast& expression_ast::operator/=(expression_ast const& rhs){    expr = binary_op('/', 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<'+'> > pos;boost::phoenix::function<unary_expr<'-'> > 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 char type; };    template <typename Node>    char operator()(Node const& bin_op) const    {        return bin_op.op;    }};boost::phoenix::function<get_op> _op;#endif

⌨️ 快捷键说明

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