You can configure Boost Spirit Rules

In my Boost Spirit grammar, I would like to have a rule that does the following:

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

but for a custom keyword so that I can do this:

... → noCaseLit ("SomeSpecialKeyword") → ... → noCaseLit ("OtherSpecialKeyword1")

Is this possible with Boost Spirit rules, and if so, how?

PS I use the case-insensitive thing as an example, what I do is parameterize the rules in general.

edits: Through the link provided by "sehe" in the comments, I was able to get closer to what I wanted, but I'm not quite there yet.

/* Defining the noCaseLit rule */ rule<Iterator, string(string)> noCaseLit = no_case[lit(_r1)]; /* Using the noCaseLit rule */ rule<...> someRule = ... >> noCaseLit(phx::val("SomeSpecialKeyword")) >> ... 

I have not figured out a way to automatically convert a literal string to a Phoenix value so that I can use the rule as follows:

 rule<...> someRule = ... >> noCaseLit("SomeSpecialKeyword") >> ... 
+3
source share
1 answer

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

 #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; } 
+4
source

Source: https://habr.com/ru/post/1489105/


All Articles