Can Boost Spirit Rules be parameterized

后端 未结 1 662
终归单人心
终归单人心 2021-01-20 04:09

In my Boost Spirit grammar I would like to have a rule that does this:

rule<...> noCaseLit = no_case[ lit( \"KEYWORD\" ) ];

but for a cus

相关标签:
1条回答
  • 2021-01-20 04:45

    The easiest way is to simply create a function that returns your rule/parser. In the example near the end of this page you can find a way to declare the return value of your function. (The same here in a commented example).

    #include <iostream>
    #include <string>
    #include <boost/spirit/include/qi.hpp>
    
    namespace ascii = boost::spirit::ascii;
    namespace qi = boost::spirit::qi;
    
    typedef boost::proto::result_of::deep_copy<
                BOOST_TYPEOF(ascii::no_case[qi::lit(std::string())])
            >::type nocaselit_return_type;
    
    nocaselit_return_type nocaselit(const std::string& keyword)
    {
        return boost::proto::deep_copy(ascii::no_case[qi::lit(keyword)]);
    }
    
    //C++11 VERSION EASIER TO MODIFY (AND DOESN'T REQUIRE THE TYPEDEF)
    //auto nocaselit(const std::string& keyword) -> decltype(boost::proto::deep_copy(ascii::no_case[qi::lit(keyword)]))
    //{
    //  return boost::proto::deep_copy(ascii::no_case[qi::lit(keyword)]);
    //}
    
    
    int main()
    {
        std::string test1="MyKeYWoRD";
        std::string::const_iterator iter=test1.begin();
        std::string::const_iterator end=test1.end();
        if(qi::parse(iter,end,nocaselit("mYkEywOrd"))&& (iter==end))
            std::cout << "Parse 1 Successful" << std::endl;
        else
            std::cout << "Parse 2 Failed. Remaining: " << std::string(iter,end) << std::endl;
    
        qi::rule<std::string::const_iterator,ascii::space_type> myrule = 
        *(
                ( nocaselit("double") >> ':' >> qi::double_ ) 
            |   ( nocaselit("keyword") >> '-' >> *(qi::char_ - '.') >> '.')
        );
    
        std::string test2=" DOUBLE : 3.5 KEYWORD-whatever.Double  :2.5";
        iter=test2.begin();
        end=test2.end();
        if(qi::phrase_parse(iter,end,myrule,ascii::space)&& (iter==end))
            std::cout << "Parse 2 Successful" << std::endl;
        else
            std::cout << "Parse 2 Failed. Remaining: " << std::string(iter,end) << std::endl;
    
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题