2017-04-11 10 views
3

저는 qi를 처음 사용하면서 어려움에 처했습니다. 문자열 두 벡터로부스트를 사용하여 두 개의 문자열 벡터 분석 : qi

X + Y + Z, A + B

: I처럼 입력을 분석하고자.

문법이 단일 문자를 구문 분석 할 때만 코드에서이 작업을 수행합니다. 이상적으로, 다음의 라인이 판독되어야한다 :

사이 + 예 + Zou는, ㅡ + 비스무트 등 elem = +(char_ - '+') % '+' 파싱 실패 간단한 교체를 사용

, 제 1 ELEM에 ''를 소비하기 때문에, 그러나 나는 이것에 대한 간단한 방법을 발견하지 못했다. 여기

참조 용 내 단일 문자 코드 :

#include <bits/stdc++.h> 

#define BOOST_SPIRIT_DEBUG 
#include <boost/fusion/adapted.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

namespace qi = boost::spirit::qi; 
namespace phx = boost::phoenix; 

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

struct reaction_t 
{ 
    element_array reactants; 
    element_array products; 
}; 

BOOST_FUSION_ADAPT_STRUCT(reaction_t, (element_array, reactants)(element_array, products)) 

template<typename Iterator> 
struct reaction_parser : qi::grammar<Iterator,reaction_t(),qi::blank_type> 
{ 
    reaction_parser() : reaction_parser::base_type(reaction) 
    { 
     using namespace qi; 

    elem = char_ % '+'; 
    reaction = elem >> ',' >> elem; 

    BOOST_SPIRIT_DEBUG_NODES((reaction)(elem)); 
    } 
    qi::rule<Iterator, reaction_t(), qi::blank_type> reaction; 
    qi::rule<Iterator, element_array(), qi::blank_type> elem; 
}; 
int main() 
{ 

    const std::string input = "X + Y + Z, A + B"; 
    auto f = begin(input), l = end(input); 

    reaction_parser<std::string::const_iterator> p; 
    reaction_t data; 

    bool ok = qi::phrase_parse(f, l, p, qi::blank, data); 

    if (ok) std::cout << "success\n"; 
    else std::cout << "failed\n"; 

    if (f!=l) 
     std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n"; 
} 

답변

3

같은 ELEM 같이 = + (char_ - '+') 간단한 교체 사용 %를 '+'파싱 실패, 그 때문에 첫 번째 요소에서 ','를 소비하지만,이 문제를 해결할 수있는 간단한 방법을 찾지 못했습니다.

음, 전체 (뇌사) 간단한 해결책 +(char_ - '+' - ',') 또는 +~char_("+,")을 사용하는 것입니다.

elem  = qi::lexeme [ +alpha ] % '+'; 

어휘에 대한 Boost spirit skipper issues 및 선장

Live On Coliru

를 참조하십시오

정말하지만, 나는 element 더 구체적인 예에 ​​대한 규칙을 만들 것

#include <boost/fusion/adapted.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

namespace qi = boost::spirit::qi; 
namespace phx = boost::phoenix; 

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

struct reaction_t 
{ 
    element_array reactants; 
    element_array products; 
}; 

BOOST_FUSION_ADAPT_STRUCT(reaction_t, (element_array, reactants)(element_array, products)) 

template<typename Iterator> 
struct reaction_parser : qi::grammar<Iterator,reaction_t(),qi::blank_type> 
{ 
    reaction_parser() : reaction_parser::base_type(reaction) { 
     using namespace qi; 

     elem  = qi::lexeme [ +alpha ] % '+'; 
     reaction = elem >> ',' >> elem; 

     BOOST_SPIRIT_DEBUG_NODES((reaction)(elem)); 
    } 
    qi::rule<Iterator, reaction_t(), qi::blank_type> reaction; 
    qi::rule<Iterator, element_array(), qi::blank_type> elem; 
}; 

int main() 
{ 
    reaction_parser<std::string::const_iterator> p; 

    for (std::string const input : { 
      "X + Y + Z, A + B", 
      "Xi + Ye + Zou , Ao + Bi", 
      }) 
    { 
     std::cout << "----- " << input << "\n"; 
     auto f = begin(input), l = end(input); 

     reaction_t data; 

     bool ok = qi::phrase_parse(f, l, p, qi::blank, data); 

     if (ok) { 
      std::cout << "success\n"; 
      for (auto r : data.reactants) { std::cout << "reactant: " << r << "\n"; } 
      for (auto p : data.products) { std::cout << "product: " << p << "\n"; } 
     } 
     else 
      std::cout << "failed\n"; 

     if (f != l) 
      std::cout << "Remaining unparsed: '" << std::string(f, l) << "'\n"; 
    } 
} 

인쇄 :

----- X + Y + Z, A + B 
success 
reactant: X 
reactant: Y 
reactant: Z 
product: A 
product: B 
----- Xi + Ye + Zou , Ao + Bi 
success 
reactant: Xi 
reactant: Ye 
reactant: Zou 
product: Ao 
product: Bi