2012-05-02 19 views
7

我在努力學習boost::spirit。作爲一個例子,我試圖將一系列的單詞解析成一個vector<string>。我嘗試這樣做:如何使用boost :: spirit將一個單詞序列解析成一個向量?

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

namespace qi = boost::spirit::qi; 

int main() { 

    std::vector<std::string> words; 
    std::string input = "this is a test"; 

    bool result = qi::phrase_parse(
     input.begin(), input.end(), 
     +(+qi::char_), 
     qi::space, 
     words); 

    BOOST_FOREACH(std::string str, words) { 
    std::cout << "'" << str << "'" << std::endl; 
    } 
} 

,給了我這樣的輸出:

'thisisatest' 

,但我想下面的輸出,其中每個字分別匹配:

'this' 
'is' 
'a' 
'test' 

如果可能的話,我d喜歡避免爲這個簡單情況定義我自己的qi::grammar子類。

回答

13

你從根本上誤解的(或至少濫用)跳過解析器– qi::space,作爲跳讀分析器的目的,是使你的解析器不可知的空白,使得在a bab之間沒有什麼區別。

在你的情況下,空格重要的,因爲你希望它分隔單詞。因此,你不應該跳過空格,並要使用qi::parse,而不是qi::phrase_parse

#include <vector> 
#include <string> 
#include <iostream> 
#include <boost/foreach.hpp> 
#include <boost/spirit/include/qi.hpp> 

int main() 
{ 
    namespace qi = boost::spirit::qi; 

    std::string const input = "this is a test"; 

    std::vector<std::string> words; 
    bool const result = qi::parse(
     input.begin(), input.end(), 
     +qi::alnum % +qi::space, 
     words 
    ); 

    BOOST_FOREACH(std::string const& str, words) 
    { 
     std::cout << '\'' << str << "'\n"; 
    } 
} 

(現在用G. Civardi的修復更新。)

+0

很好解釋,+1 – sehe

2

我相信這是最低版本。 qi :: omit應用於qi列表解析器分隔符是不必要的 - 它不會生成任何輸出屬性。詳情請參閱:http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/list.html

#include <string> 
#include <iostream> 
#include <boost/foreach.hpp> 
#include <boost/spirit/include/qi.hpp> 

int main() 
{ 
    namespace qi = boost::spirit::qi; 

    std::string const input = "this is a test"; 

    std::vector<std::string> words; 
    bool const result = qi::parse(
     input.begin(), input.end(), 
     +qi::alnum % +qi::space, 
     words 
); 

    BOOST_FOREACH(std::string const& str, words) 
    { 
     std::cout << '\'' << str << "'\n"; 
    } 
} 
1

以防萬一別人遇到我的領先空間問題。

我一直在使用ildjarn的解決方案,直到遇到以某些空格開頭的字符串。

std::string const input = " this is a test"; 

我花了一段時間才發現領先空間導致函數qi :: parse(...)失敗。解決的辦法是在調用qi :: parse()之前修剪輸入的前導空格。

相關問題