可以将Boost Spirit规则参数化 [英] Can Boost Spirit Rules be parameterized

查看:97
本文介绍了可以将Boost Spirit规则参数化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Boost Spirit语法中,我希望有一条规则可以做到这一点:

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

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

但要使用自定义关键字,以便我可以这样做:

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

... >> noCaseLit("SomeSpecialKeyword")>> ... >> noCaseLit("OtherSpecialKeyword1")

Boost Spirit规则有可能吗?如果可以,怎么办?

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

P.S.我以不区分大小写的内容为例,我所追求的通常是规则参数化.

P.S. I use the case insensitive thing as an example, what I'm after is rule parameterization in general.

修改: 通过"sehe"在评论中提供的链接,我可以接近我想要的内容,但我还没有到位.

Edits: Through the link provided by 'sehe' in the comments I was able to come close 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")) >> ...

我还没有找到一种将文字字符串自动转换为Phoenix值的方法,因此我可以使用如下规则:

I haven't yet figured out a way to automatically convert the literal string to the Phoenix value so that I can use the rule like this:

rule<...> someRule = ... >> noCaseLit("SomeSpecialKeyword") >> ...

推荐答案

最简单的方法是简单地创建一个返回规则/解析器的函数.在此页面末尾的示例中您可以找到一种方法来声明函数的返回值. (在注释示例中,此处).

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;
}

这篇关于可以将Boost Spirit规则参数化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆