2012-11-28 40 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