Assign default value to variable using boost spirit

后端 未结 2 1983
故里飘歌
故里飘歌 2021-01-22 03:22

Suppose I have the following string to parse:

\"1.2, 2.0, 3.9\"

and when I apply the following parser for it:

struct DataStruct
{
    dou         


        
相关标签:
2条回答
  • 2021-01-22 03:35

    You might use the following code:

    #include <boost/fusion/include/adapt_struct.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <boost/spirit/include/phoenix_operator.hpp>
    struct DataStruct
    {
        double n1, n2, n3;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(DataStruct, (double, n1)(double, n2)(double, n3))
    
    int main() {
        using namespace boost::spirit;
    
        using Iterator = typename std::string::iterator;
    
        qi::rule<Iterator, double()> reader_ = (qi::double_[_val = _1] | (lexeme["null"])[_val = 0.]);
    
        qi::rule<Iterator, DataStruct()> data_ = reader_ >> ',' >> reader_ >> ',' >> reader_;
    
        try {
            DataStruct res;
            auto str = std::string("1.2,null,3.9");
            auto start = str.begin();
            auto end = str.end();
    
            bool ok = qi::parse(start, end, data_, res);
            if (ok) {
                std::cout << "parse completed" << std::endl;
            }
            else {
                std::cout << "parse failed" << std::endl;
            }
        }
        catch (const qi::expectation_failure<std::string::iterator>& except) {
            std::cout << except.what();
        }
    
        std::cout << std::endl;
    }
    
    0 讨论(0)
  • 2021-01-22 03:57

    The usual trick is to use an alternative with qi::attr:

    rule_def = parser_expression | qi::attr(default_value);
    

    In your case, perhaps:

    reader_ = qi::double_ | qi::lit("null") >> qi::attr(0);
    

    Demo

    Live On Coliru

    #include <boost/spirit/include/qi.hpp>
    #include <boost/fusion/include/adapt_struct.hpp>
    struct DataStruct { double n1, n2, n3; };
    
    BOOST_FUSION_ADAPT_STRUCT(DataStruct, n1, n2, n3)
    
    namespace qi = boost::spirit::qi;
    
    int main() {
        using Iterator = typename std::string::const_iterator;
    
        qi::rule<Iterator, double()> reader_   = qi::double_ | qi::lit("null") >> qi::attr(0);
        qi::rule<Iterator, DataStruct()> data_ = reader_ >> ',' >> reader_ >> ',' >> reader_;
    
        DataStruct res;
        auto const str = std::string("1.2,null,3.9");
        Iterator start = str.begin(), end = str.end();
    
        if (qi::parse(start, end, data_ >> qi::eoi, res)) {
            std::cout << "parsed: " << boost::fusion::as_vector(res) << "\n";
        }
        else {
            std::cout << "parse failed\n";
        }
    }
    

    Prints

    parsed: (1.2 0 3.9)
    

    Note the review changes (don't using namespace, check for eoi).

    0 讨论(0)
提交回复
热议问题