2012-11-28 41 views
3

在我升压精神的语法我想有做这个的规则:可能促进精神规则参数

规则< ...> noCaseLit = NO_CASE [亮(“关键字”)];

但对于一个自定义的关键字,这样我可以做到这一点:

... >> noCaseLit( “SomeSpecialKeyword”)>> ... >> noCaseLit( “OtherSpecialKeyword1”)

这是可能与提升精神规则,如果是的话如何?

P.S.我用大小写不敏感的东西作为例子,我后面的一般是规则参数化。

编辑: 通过评论中'sehe'提供的链接,我能够接近我想要的东西,但我还没有完成。

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

我还没有想出一个办法自动将文本字符串转换为凤凰值,这样我可以使用这样的规则:

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

[分解出的精神规则共同份](http://stackoverflow.com/questions/13388227/factoring-out-common-parts-of-spirit-rules),用于提供 – sehe

+0

THX sehe的可能重复该链接帮助我学习了如何使用继承的属性。 – Halt

回答

4

最简单的方法就是简单地创建一个返回你的规则/解析器的函数。在this page末尾的示例中,您可以找到一种方法来声明函数的返回值。 (在一个注释的例子中,同样的here)。

#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

此解决方案的Thx。你的方向与我在“一半”解决方案中所做的不同。这工作,并做我以后的事情。 – Halt

+0

+1另一个令人惊叹的答案,显示了灵魂接口_underneith_上发生的事情的理解。 [哦,Vim'g〜iw'多了? :)] – sehe