[ create a new paste ] login | about

Link: http://codepad.org/wufmFufE    [ raw code | fork ]

C++, pasted on May 22:
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/variant.hpp>
#include <iostream>
#include <string>
#include <exception>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;

namespace client { namespace ast {

    struct literal_t;
    struct binop_t;

    typedef boost::variant<
        boost::recursive_wrapper<literal_t>
      , boost::recursive_wrapper<binop_t>
    > expression_t;

    struct literal_t
    {
        double value;
    };

    struct binop_t
    {
        expression_t lhs, rhs;
    };
}} // ns

BOOST_FUSION_ADAPT_STRUCT
(
    client::ast::literal_t,
    (double, value)
)

BOOST_FUSION_ADAPT_STRUCT
(
    client::ast::binop_t,
    (client::ast::expression_t, lhs)
    (client::ast::expression_t, rhs)
)

namespace client {
    template <typename Iterator>
    struct grammar_t : qi::grammar<Iterator, ast::expression_t(), ascii::space_type>
    {
        qi::rule<Iterator, ast::literal_t(), ascii::space_type> literal;
        qi::rule<Iterator, ast::binop_t(), ascii::space_type> binop;
        qi::rule<Iterator, ast::expression_t(), ascii::space_type> primary_expr;
        qi::rule<Iterator, ast::expression_t(), ascii::space_type> expr;

        grammar_t() : grammar_t::base_type(expr)
        {
            expr = binop.alias();

            binop = primary_expr >> qi::lit('+') >> (binop | primary_expr);

            primary_expr = (qi::lit('(') >> expr >> qi::lit(')'))
                         | literal;

            literal = qi::double_;

            expr.name("expr");
            binop.name("binop");
            literal.name("literal");
            qi::debug(expr);
            qi::debug(binop);
            qi::debug(literal);
        }
    };
} // ns

int main()
{
    try
    {
        std::string input = "0.1 + 1.2 + 2.3 + (3.4 + 4.5) + 5.6";
        std::string::const_iterator begin = input.begin();
        std::string::const_iterator end = input.end();

        typedef std::string::const_iterator iterator_type;
        client::grammar_t<iterator_type> g;

        client::ast::expression_t ast;

        bool status;
        status = qi::phrase_parse(begin, end, g, ascii::space, ast);
        // EXPECT_TRUE(status);
        // EXPECT_TRUE(begin == end);
    } catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}


Create a new paste based on this one


Comments: