2016-07-27 11 views
2

Ich versuche, durch Komma getrennte Token zu analysieren, die Bindestriche enthalten. Aber lexeme ignoriert alle Bindestriche. Teil des Programms ist wie folgt.boost :: spirit :: qi :: lexeme erfasst kein vollständiges Token

#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

Antwort

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

Dies entspricht einen oder mehrere Reihe von alphanumerischen Zeichen, getrennt durch '-'. Das ist es, nach den Dokumenten. Daher sollten Sie nicht erwarten, dass der Hype ein Teil davon ist.

Verwenden

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

statt. Oder

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

oder in Zusammenhang sogar:

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'; 
} 

Drucke

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

Mit debug aktiviert:

<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

viel Fettabsaugung mit Spirit X3 geben, wenn Sie C++ 14 verwenden können: ** [Live On Coliru] (http://coliru.stacked-crooked.com/a/b1539818a9062a78) ** – sehe

+0

Ich habe nur C++ 11 mit GCC 4.7.3 – gjha

+0

Problem mit dem obigen Vorschlag ist, dass ich eine Zeichenfolge wie 'abc - xyz' nicht akzeptieren will, dh' doppelter Bindestrich' ist nicht erlaubt . – gjha

Verwandte Themen