2012-03-17 89 views
2

我有一種情況,我將輸入解析爲向量boost :: Spirit的地圖。使用boost :: spirit解析字符串列表

它運行良好,但我遇到了一種情況,我需要在某種情況下爲用戶輸入提供一個固定的字符串,以便內部字符串被解析以代替用戶輸入。

這裏是語法的一個示例:

input_pair = 
    key(std::string("__input")) >> valid_input % ',' 
    ; 

其中:

key = 
    qi::attr(_r1) 
    ; 

和 「valid_input」 是一個簡單的規則,對特定的字符串/字符模式測試等

該語法將輸入與預定義的內部鍵配對,並將其作爲向量存儲在映射中。如果輸入包含指定的分隔符,則輸入將被適當地解析爲接收向量的單獨元素。

但是,我遇到的問題是爲「valid_input」提供預定義的字符串。

我的第一個傾向是做什麼我做與地圖鍵:

input_pair = 
    key(std::string("__input")) >> key (std::string("A, B, C")) % ',' 
    ; 

但是,當然,整個字符串被插入作爲載體的第一要素。也就是說,「A,B,C」中的逗號分隔符不被認爲是我所希望的。

因此我的問題:

給出一個boost ::精神解析器,其語法解析輸入地圖的載體,是有解析器本身中定義爲載體任何方式來解析固定字符串?

回答

2

給定的輸入 「1 1 2 3 4」,下面的規則:

將(顯然)解析的std::vector<string> { "1", "2", "3", "4" }的屬性值。

現在改變規則

rule %= qi::attr(attr_t { "aap", "noot", "mies" }) >> *qi::lexeme[+qi::char_]; 

,您會收到std::vector<string> { "aap", "noot", "mies", "1", "2", "3", "4" }。如果要硬編碼向量只有,請使用qi::omit

這是在工作中C++ 11統一初始化語法,因此,如果您不能使用,你必須提供一個載體一些其他的方式:

static const std::string hardcoded[] = { "aap", "noot", "mies" }; 
static const attr_t const_data(hardcoded, hardcoded+3); 
rule = qi::attr(const_data) >> *qi::lexeme[+qi::char_]; 

這也是稍微更有效(代價是更詳細的代碼)。


在這裏被完全工作實施例與本一些變型中(假定C++ 11編譯器爲測試主):

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/karma.hpp> 

namespace qi = boost::spirit::qi; 
namespace karma = boost::spirit::karma; 

typedef std::vector<std::string> attr_t; 

int main() 
{ 
    const std::string input = "1 2 3 4"; 
    auto f(std::begin(input)), l(std::end(input)); 

    qi::rule<decltype(f), attr_t(), qi::space_type> rule; 

    // #1: no hardcoded values 
    rule = *qi::lexeme[+qi::char_]; 

    // #2: hardcoded inline temp vector 
    rule = qi::attr(attr_t { "aap", "noot", "mies" }) >> *qi::lexeme[+qi::char_]; 

    // #3: hardcoded static vector, C++03 style 
    static const std::string hardcoded[] = { "aap", "noot", "mies" }; 
    static const attr_t const_data(hardcoded, hardcoded+3); 
    rule = qi::attr(const_data) >> *qi::lexeme[+qi::char_]; 

    try 
    { 
     attr_t data; 
     bool ok = qi::phrase_parse(f, l, rule, qi::space, data); 
     if (ok) 
     { 
      std::cout << "parse success\n"; 
      std::cout << "data: " << karma::format_delimited(karma::auto_, ' ', data) << "\n"; 
     } 
     else std::cerr << "parse failed: '" << std::string(f,l) << "'\n"; 

     if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n"; 

     return ok? 0 : 255; 
    } catch(const qi::expectation_failure<decltype(f)>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cerr << e.what() << "'" << frag << "'\n"; 
     return 255; 
    } 

} 

它打印

parse success 
data: 1 2 3 4 
+0

這是一個很好的方法。由於向量是硬編碼的,我可以將它指定爲多個字符串的列表,而不是一個字符串中包含的整個列表(當然,這是我被迫接受用戶輸入的方式)。感謝您的教訓! – 2012-03-21 22:28:40

相關問題