簡體   English   中英

解析成類(不是結構)

[英]parsing into classes (not structs)

下面我展示了一個未編譯的精神雇員示例。 我要解決的問題是解析為類而不是結構。 我知道,除了公共/私人之外,其他情況都差不多。 但是在將類/結構存儲到向量中之前,我需要有一個構造函數來工作。 如何更改BOOST_FUSION_ADAPT_STRUCT?

我怎樣才能運行它?

// STD HEADER
#include <iostream>
#include <string>
#include <complex>

// BOOST HEADER
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>

namespace client
{
    namespace qi = boost::spirit::qi;

    namespace ascii = boost::spirit::ascii;

    class employee
    {
    public:
        employee (
            int _age
          , std::string _surname
          , std::string _forename
          , double _salary
        );

    private:
        int age_;
        std::string surname_;
        std::string forename_;
        double salary_;
    };

    employee::employee (
        int _age
      , std::string _surname
      , std::string _forename
      , double _salary
    ) : age_(_age)
      , surnemae_(_surename)
      , forename_(_forename)
      , double salary_
    {
        // do some important stuff
    }

}

// WHAT TO DO HERE?
BOOST_FUSION_ADAPT_STRUCT(
    client::employee
)

namespace client
{
    template <typename Iterator>
    struct employee_parser
      : qi::grammar<Iterator, employee(), ascii::space_type>
    {
        employee_parser() : employee_parser::base_type(start)
        {
            using qi::int_;
            using qi::lit;
            using qi::double_;
            using qi::lexeme;
            using ascii::char_;

            quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];

            start %=
                lit("employee")
                >> '{'
                >>  int_ >> ','
                >>  quoted_string >> ','
                >>  quoted_string >> ','
                >>  double_
                >>  '}'
                ;
        }

        qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
        qi::rule<Iterator, employee(), ascii::space_type> start;
    };
}

int main()
{
    std::cout << "/////////////////////////////////////////////////////////\n\n";
    std::cout << "\t\tAn employee parser for Spirit...\n\n";
    std::cout << "/////////////////////////////////////////////////////////\n\n";

    std::cout
        << "Give me an employee of the form :"
        << "employee{age, \"surname\", \"forename\", salary } \n";
    std::cout << "Type [q or Q] to quit\n\n";

    using boost::spirit::ascii::space;
    typedef std::string::const_iterator iterator_type;
    typedef client::employee_parser<iterator_type> employee_parser;

    employee_parser g;
    std::string str;
    while (getline(std::cin, str))
    {
        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
            break;

        client::employee emp;
        std::string::const_iterator iter = str.begin();
        std::string::const_iterator end = str.end();
        bool r = phrase_parse(iter, end, g, space, emp);

        if (r && iter == end)
        {
            std::cout << boost::fusion::tuple_open('[');
            std::cout << boost::fusion::tuple_close(']');
            std::cout << boost::fusion::tuple_delimiter(", ");

            std::cout << "-------------------------\n";
            std::cout << "Parsing succeeded\n";
            std::cout << "got: " << boost::fusion::as_vector(emp) << std::endl;
            std::cout << "\n-------------------------\n";
        }
        else
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing failed\n";
            std::cout << "-------------------------\n";
        }
    }

    std::cout << "Bye... :-) \n\n";
    return 0;
}

您可以

1.適應ADT

通過添加獲取器/設置器。 其他答案將其鏈接為解決方案: http : //www.boost.org/doc/libs/release/libs/fusion/doc/html/fusion/adapted/adapt_adt.html

2.使用語義動作:

在Coliru上實時觀看

變化:

  1. 使類默認為可構造
  2. 從規則的語義動作中顯式調用構造函數:

      start = lit("employee") >> ('{' >> int_ >> ',' >> quoted_string >> ',' >> quoted_string >> ',' >> double_ >> '}' ) [ qi::_val = boost::phoenix::construct<employee>(qi::_1, qi::_2, qi::_3, qi::_4) ] ; 
  3. 可選重載operator<<因此您仍然可以打印類進行調試

3.提供定制點

參見http://www.boost.org/doc/libs/1_56_0/libs/spirit/doc/html/spirit/advanced/customize/assign_to.html

Boost.Fusion提供了宏BOOST_FUSION_ADAPT_STRUCT_ADT ,該宏在您的用例中使用了setter和getter函數。 有關更多信息,請訪問: http : //www.boost.org/doc/libs/1_50_0/libs/fusion/doc/html/fusion/adapted/adapt_adt.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM