2014-04-24 8 views
2

부스트 직원 예제를 기반으로 BOOST_FUSION_ADAPT_STRUCT를 사용하여 구조체를 내 보내려는 qi :: rule <을 얻으려고합니다.BOOST_FUSION_ADAPT_STRUCT에서 boost :: qi :: rule을 사용하는 올바른 방법은 무엇입니까?

I가 다음과 같은 구조체 및 관련 융합 매크로 :

struct LineOnCommand 
{ 
    int lineNum; 
    std::vector<char> humpType; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    LineOnCommand, 
    (int, lineNum) 
    (std::vector<char>, humpType) 
) 

연관된 구문 분석 규칙은 다음과 같습니다

qi::rule<Iterator, std::vector<char> ascii::space_type> humpIdentifer = qi::lit("BH") | qi::lit("DH"); 

qi::rule<Iterator, LineOnCommand(), ascii::space_type> Cmd_LNON = qi::int_ >> -humpIdentifier >> qi::lit("LNON"); 

내가 다음있는 다른 모든 (이 간단한을 포함한 복합 규칙을 가지고

qi::rule<Iterator, qi::unused_type, ascii::space_type> commands = 
    +(/* other rules | */ Cmd_LNON /*| other rules */); 

bool success = qi::phrase_parse(StartIterator, EndIterator, commands, ascii::space); 

문제 : 테스트 케이스) 파서로 전달하는 부분이다

<boostsource>/spirit/home/qi/detail/assign_to.hpp(152): error: no suitable constructor exists to convert form "const int" to "LineOnCommand" 
    attr = static_cast<Attribute>(val); 

은 분명히 내가 뭔가를 잘못하고 있어요,하지만 난 모르겠어요 : 나는 컴파일을 시도, 나는 오류를 얻을 때 온다. spirit이 작동하는 방식을 이해한다면 규칙의 템플릿에 대한 두 번째 인수는 속성 (즉, 규칙에 의해 생성 된 데이터 유형)을 나타내며 BOOST_FUSION_ADAPT_STRUCT 매크로는 내 구조체를 적용하여 부스트가 "int, std :: vector".

여기서 내가하는 일과 부스트 직원 예제의 유일한 차이점은 구문 분석을 위해 명시 적 문법을 사용하지 않는다는 것입니다. 내 이해가 필요하지 않습니다, 그리고 그 자체로 규칙으로 충분합니다.

내가 뭘 잘못하고 있니?

+0

그것은 당신의 질문은 본질적으로 관련이없는 경우 별도의 질문을 게시하는 것이 일반적으로보다 더 낫다입니다. 이 경우 그들은 그렇습니다. – sehe

+1

예제를 자체 포함 시키십시오. 이것은 사람들이 쉽게 도울 수있게 해줍니다. (저는 이것을 스피릿에 잘 익숙하게 사용하는 사람들이이 코드를 작업 코드로 만들 수있을만큼 손의 손가락으로 계산할 수 있다고 생각합니다). – sehe

답변

2

잘 모르겠습니다. 나는 그 문제를 놓치고 있다고 생각한다. 아마도, 샘플이 자체 포함되지 않았기 때문에 나는 "자연스럽게"문제를 회피합니다.

그래서, 여기에 필자의 :

  • 내가 뭔가를 제안
  • 규칙 선언에 명백한 오타를 수정 : 단지 물건을 비교하는 당신이 도움이 희망, Live On Coliru 그것을 참조 qi::unused_type 이외; 속성이 없다면 그것을 기술 할 필요가 없습니다. 반복자 유형을 벗어나 qi::ruleqi::grammar의 템플릿 인수는 위치가 적절하지 않습니다.. 따라서

    qi::rule<It, qi::unused_type(), ascii::space_type> r; 
    qi::rule<It, ascii::space_type, qi::unused_type()> r; 
    qi::rule<It, ascii::space_type> r; 
    

    은 모두/논리적으로 동일합니다.

전체 목록 :

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

namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

struct LineOnCommand 
{ 
    int lineNum; 
    std::vector<char> humpType; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    LineOnCommand, 
    (int, lineNum) 
    (std::vector<char>, humpType) 
) 

template <typename It, typename Skipper = ascii::space_type> 
struct parser : qi::grammar<It, std::vector<LineOnCommand>(), Skipper> 
{ 
    parser() : parser::base_type(commands) 
    { 
     using namespace qi; 
     humpIdentifier = string("BH") | string("DH"); 
     Cmd_LNON  = int_ >> -humpIdentifier >> "LNON"; 

     commands  = +(/* other rules | */ Cmd_LNON /*| other rules */); 
    } 
    private: 
    qi::rule<It, std::vector<char>(),   Skipper> humpIdentifier; 
    qi::rule<It, LineOnCommand(),    Skipper> Cmd_LNON; 
    qi::rule<It, std::vector<LineOnCommand>(), Skipper> commands; 
}; 

int main() 
{ 
    typedef std::string::const_iterator Iterator; 
    parser<Iterator> p; 

    std::string const input = 
     "123 BH LNON\n" 
     "124 LNON\t\t\t" 
     "125 DH LNON\n" 
     "126 INVALID LNON"; 

    auto f(input.begin()), l(input.end()); 

    std::vector<LineOnCommand> data; 
    bool success = qi::phrase_parse(f, l, p, ascii::space, data); 

    std::cout << "success:" << std::boolalpha << success << ", " 
       << "elements: " << data.size() << "\n"; 

    if (success) 
    { 
     for (auto& el : data) 
     { 
      std::cout << "Item: " << el.lineNum << ", humpType '" << std::string(el.humpType.begin(), el.humpType.end()) << "'\n"; 
     } 
    } 

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

    return success? 0 : 1; 
} 

출력 :

success:true, elements: 3 
Item: 123, humpType 'BH' 
Item: 124, humpType '' 
Item: 125, humpType 'DH' 
Trailing unparsed: '126 INVALID LNON' 
+0

이 답장을 보내 주셔서 감사합니다. 내가 갇혀 있던 곳에서 나를 확실히 옮겨 놓았습니다.그러나, LineOnCommand 구조체의 혹등 변수가 채워지지 않고 있음을 알게되었습니다 (빈 벡터 일뿐입니다). 복합 규칙이 작동하는 방식을 이해한다면 귀하의 예에서는 'DH', 'BH'또는 'INVALID'로 채워야합니다. 이 올바른지? – stix

+3

@stix Ah. 미안하지만, 나는 그것을 놓쳤다. 'lit'는 속성을 노출하지 않습니다. 대신에'string'을 사용하십시오 : ** [Live On Coliru] (http://coliru.stacked-crooked.com/a/79b4d8dabefc980c) ** – sehe