2014-07-21 2 views
1

나는 여전히 부스트 스피릿을 처음 접했습니다.앞뒤 공백 문자로 구문 분석 문자열 늘리기

나는 가능한 납과 후행 공백 및 중간 공백이있는 문자열을 구문 분석하려합니다. 나는 문자열

  1. (가)의 사이에 단어의 공백이 하나 개의 공백 예를 들어

"( my test1 ) (my test2)" 

가져 후행 선도 공백

  • 제한을 제거하여 다음을 수행 할

    "my test1" 
    "my test2" 
    
    - 두 용어로서 구문 분석 그 사이에 공간을 유지 수 있지만 516,

    난 다음 논리

    using boost::spirit::qi; 
    struct Parser : grammar<Iterator, attribType(), space_type> 
    { 
        public: 
        Parser() : Parser::base_type(term) 
        { 
         group %= '(' >> (group | names) >> ')'; 
         names %= no_skip[alnum][_val=_1]; 
        } 
    
        private: 
        typedef boost::spirit::qi::rule<Iterator, attribType(), space_type> Rule; 
        Rule group; 
        Rule names 
    } 
    

    을 사용했다. 불행하게도, 공백과 공백을 연속적으로 유지합니다. 나는 더 나은 논리를 찾고 싶다.

    나는 부스트 :: 정신을 사용자 정의 선장을 사용하는 자료를 참조하십시오 : 제나라 온라인으로 건너 ::했다,하지만 난 공간에 대한 유용한 예를 건너하지 않았습니다. 다른 사람도 그 경험이 있습니까?

  • +0

    'lexeme','skip','no_skip', 함축적 인 skippers와'raw'에 대한 배경은 다음과 같습니다 : http://stackoverflow.com/questions/17072987/boost-spirit-skipper-issues/17073965#1707396 5 – sehe

    답변

    2

    나는 (안 중) 구문 분석 후 트리밍/정상화 을하는 게 좋을 것. 말했다

    ,이 같은 해킹 수 :

    Parse success 
    Term: 'my test1' 
    Term: 'my test2' 
    

    가 난 단지 가독성을 위해 name 규칙을 소개 :

    name %= lexeme [ +alnum ]; 
    names %= +(name >> (&lit(')') | attr(' '))); 
    group %= '(' >> (group | names) >> ')'; 
    

    그것이 Live On Coliru

    출력을 참조하십시오. (&lit(')') | attr(' '))가 말하는 멋진 방법입니다 참고 : 그렇지 않으면, 합성 속성 ' '을 추가, 다음 문자 ')'는 아무것도하지 않고 일치하는 경우

    전체 코드 :

    #define BOOST_SPIRIT_DEBUG 
    #include <boost/spirit/include/qi.hpp> 
    #include <boost/spirit/include/phoenix.hpp> 
    
    namespace qi = boost::spirit::qi; 
    namespace phx = boost::phoenix; 
    
    using Iterator = std::string::const_iterator; 
    
    using attribType = std::string; 
    
    struct Parser : qi::grammar<Iterator, attribType(), qi::space_type> 
    { 
        public: 
        Parser() : Parser::base_type(group) 
        { 
         using namespace qi; 
    
         name %= lexeme [ +alnum ]; 
         names %= +(name >> (&lit(')') | eps [ phx::push_back(_val, ' ') ])); 
         group %= '(' >> (group | names) >> ')'; 
    
         BOOST_SPIRIT_DEBUG_NODES((name)(names)(group)) 
        } 
    
        private: 
        typedef boost::spirit::qi::rule<Iterator, attribType(), qi::space_type> Rule; 
        Rule group, names, name; 
    }; 
    
    
    int main() 
    { 
        std::string const input = "( my test1 ) (my test2)"; 
    
        auto f(input.begin()), l(input.end()); 
    
        Parser p; 
    
        std::vector<attribType> data; 
        bool ok = qi::phrase_parse(f, l, *p, qi::space, data); 
    
        if (ok) 
        { 
         std::cout << "Parse success\n"; 
         for(auto const& term : data) 
          std::cout << "Term: '" << term << "'\n"; 
        } 
        else 
        { 
         std::cout << "Parse failed\n"; 
        } 
    
        if (f!=l) 
         std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n"; 
    } 
    
    +0

    좋은 해결책. ('coliru.stacked-crooked.com/a/9c1c5df7f85e8eab)도 사용할 수 있습니까? [name % = + (name >> (& lit (')') | attr (''))); 아니면 내가 이해하지 못하는 문제를 제시하겠습니까? – llonesmiz

    +0

    음. 그것은 내 마음을 십자가에 못 박았습니다. 왜 내가 그것을 해산 시켰는지 모르겠습니다. 네, 물론 더 간단합니다. 내가 할게요 :) – sehe