2016-07-27 42 views
2

我想解析包含連字符的逗號分隔的標記。但lexeme忽略所有的連字符。部分程序如下。boost :: spirit :: qi :: lexeme沒有捕獲完整的令牌

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

namespace qi = boost::spirit::qi; 
namespace bs = boost::spirit; 

template<typename Iterator> 
struct my_grammar : public qi::grammar<Iterator,bs::utree(),bs::ascii::space_type> 
{ 
    my_grammar() : my_grammar::base_type(start,"MY") 
    { 
     start = token % ','; 
     token = qi::lexeme[ +qi::alnum % qi::char_('-') ]; 
    } 

    qi::rule<Iterator,bs::utree(),bs::ascii::space_type> start; 
    qi::rule<Iterator,std::string()> token; 
}; 

template<typename Iterator> 
bool parse(Iterator & begin,Iterator end,my_grammar<Iterator> const & grammar) 
{ 
    bs::utree a; 
    auto r = qi::phrase_parse(begin,end,grammar,bs::ascii::space,a); 
    std::cout<<a<<'\n'; 
    return r; 
} 

int main() 
{ 
    std::string input = "i-j-k,l-m-n,p3-14 ,5jhjj-kkk"; 

    auto it = input.begin(); 
    my_grammar<decltype(it)> g; 

    if(::parse(it,input.end(),g)) 
    { 
     std::cout<<"parse success\n"; 
    } 
    else 
    { 
     std::cout<<"parse failed\n"; 
    } 
    std::cout<<"Unparsed input => "<< std::string{it,input.end()}<<'\n'; 
} 

Coliru Link

回答

2
+qi::alnum % qi::char_('-') 

這一個或多個串聯的字母數字字符,分隔匹配 ' - '。每個文檔都是這樣。因此,你不應該期望這些炒作成爲其中的一部分。

使用

+(qi::alnum | char_('-')) 

代替。或

+qi::char_("-A-Za-z0-9") 

或在上下文中,即使是:

token = qi::raw[ qi::lexeme[+(qi::alnum | '-')] ]; 

Live On Coliru

#define BOOST_SPIRIT_DEBUG 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/support_utree.hpp> 

namespace qi = boost::spirit::qi; 
namespace bs = boost::spirit; 

template <typename Iterator, typename Result = std::vector<std::string> > struct my_grammar : public qi::grammar<Iterator, Result(), bs::ascii::space_type> { 
    my_grammar() : my_grammar::base_type(start, "MY") { 
     start = token % ','; 
     token = qi::raw[ qi::lexeme[+(qi::alnum | '-')] ]; 
     BOOST_SPIRIT_DEBUG_NODES((start)(token)) 
    } 

    qi::rule<Iterator, Result(), bs::ascii::space_type> start; 
    qi::rule<Iterator, std::string()> token; 
}; 

template <typename Iterator> bool parse(Iterator &begin, Iterator end, my_grammar<Iterator> const &grammar) { 
    std::vector<std::string> parsed; 
    auto r = qi::phrase_parse(begin, end, grammar, bs::ascii::space, parsed); 
    for (auto& el : parsed) 
     std::cout << el << " "; 
    std::cout << '\n'; 
    return r; 
} 

int main() { 
    std::string input = "i-j-k,l-m-n,p3-14 ,5jhjj-kkk"; 

    auto it = input.begin(); 
    my_grammar<decltype(it)> g; 

    if (::parse(it, input.end(), g)) { 
     std::cout << "parse success\n"; 
    } else { 
     std::cout << "parse failed\n"; 
    } 
    std::cout << "Unparsed input => " << std::string{ it, input.end() } << '\n'; 
} 

打印

i-j-k l-m-n p3-14 5jhjj-kkk 
parse success 
Unparsed input => 

使用調試啓用:

<start> 
    <try>i-j-k,l-m-n,p3-14 ,5</try> 
    <token> 
    <try>i-j-k,l-m-n,p3-14 ,5</try> 
    <success>,l-m-n,p3-14 ,5jhjj-</success> 
    <attributes>[[i, -, j, -, k]]</attributes> 
    </token> 
    <token> 
    <try>l-m-n,p3-14 ,5jhjj-k</try> 
    <success>,p3-14 ,5jhjj-kkk</success> 
    <attributes>[[l, -, m, -, n]]</attributes> 
    </token> 
    <token> 
    <try>p3-14 ,5jhjj-kkk</try> 
    <success> ,5jhjj-kkk</success> 
    <attributes>[[p, 3, -, 1, 4]]</attributes> 
    </token> 
    <token> 
    <try>5jhjj-kkk</try> 
    <success></success> 
    <attributes>[[5, j, h, j, j, -, k, k, k]]</attributes> 
    </token> 
    <success></success> 
    <attributes>[[[i, -, j, -, k], [l, -, m, -, n], [p, 3, -, 1, 4], [5, j, h, j, j, -, k, k, k]]]</attributes> 
</start> 
+0

給很多吸脂與精神X3,如果你可以使用C++ 14:** [住在Coliru(http://coliru.stacked-crooked.com/a/b1539818a9062a78)** – sehe

+0

我只有C++ 11和GCC 4.7.3 – gjha

+0

以上建議的問題是我不想接受像'abc - xyz'這樣的字符串,即不允許使用'double hyphen' 。 – gjha

相關問題