2014-09-15 2 views
1

하나의 정신 규칙으로 벡터를 작성하고 거기에 값을 추가하고 싶습니다. 가능한가? 나는 아래와 같은 것을 시도했지만 성공하지 못했다. 자세한 내용은 코드 주석을 읽으십시오. 감사.즉시 작성하여 벡터에 작성

typedef std::vector<double> number_array; 
typedef std::vector<std::string> string_array; 

typedef boost::variant<number_array, string_array> node 

template<typename Iterator> 
struct parser 
     : qi::grammar<Iterator, node(), ascii::space_type> { 

    parser(parser_impl* p) 
      : parser::base_type(expr_, ""), 
       error_handler(ErrorHandler(p)) { 

     // Here I want to create vector on the fly 
     // and append values to newly created vector. 
     // but this doesn't compile, specifically phoenix::push_back(...) 
     number_array_ = qi::lit('n[')[qi::_val = construct<number_array>()] >> 
         -(qi::double_ % ',')[phoenix::push_back(phoenix::ref(qi::_val), qi::_1)] >> ']'; 

     // this doesn't compile too 
     string_array_ = qi::lit('s[')[qi::_val = construct<string_array>()] >> 
         -(quoted_string % ',')[phoenix::push_back(phoenix::ref(qi::_val), qi::_1)] >> ']';      

     quoted_string %= "'" > qi::lexeme[*(qi::char_ - "'")] > "'"; 

     expr_ = number_array_[qi::_val = qi::_1] | string_array_[[qi::_val = qi::_1]]; 
    } 
    qi::rule<Iterator, number_array(), ascii::space_type> number_array_; 
    qi::rule<Iterator, string_array(), ascii::space_type> string_array_; 
    qi::rule<Iterator, std::string(), ascii::space_type> quoted_string; 
    qi::rule<Iterator, node(), ascii::space_type> expr_;  
}; 
+1

예를 참조하십시오. % 연산자를 사용하기 때문에 작동하지 않는 것 같습니다. 문서를 보면 (a % b) 벡터 이므로 벡터에서 벡터를 푸시하려고합니다 (_1은 해당 벡터를 참조 함). – Kiroxas

+0

아니요 _1은 해당 벡터를 참조하지 않습니다. 하지만 그게 당신이 의미하는 것입니다 – sehe

답변

2

여기서 가장 중요한 점은 모든 의미 작업을 수행하지 않고도 수행 할 수 있습니다.

기본 속성 규칙이 이미 수행하는 작업 (스칼라 속성의 경우 _val = _1, 기본적으로 conainer 속성의 경우 insert(_val, end(_val), _1)) 만 수행합니다.

이 당신이 단지

number_array_ = "n[" >> -(qi::double_ % ',') >> ']'; 
    string_array_ = "s[" >> -(quoted_string % ',') >> ']'; 

    quoted_string = "'" > qi::lexeme[*(qi::char_ - "'")] > "'"; 

    expr_   = number_array_ | string_array_; 

로 전체 오두막을 쓸 수있는 수단이 작동합니다. 멀티 바이트 리터럴 'n[''s[n'을 수정했습니다.

완전히 가난한 코멘트 죄송합니다, 그것에 대해 잊고, 또한 Boost Spirit: "Semantic actions are evil"?

+0

+1, 깨끗하고 간결한 코드 – Kiroxas

+0

그리고 라이브 ** [Coliru에 데모] (http://coliru.stacked-crooked.com/a/a6e0796c19b0828e) ** – sehe