2012-09-02 2 views
1

documentation은 A와 B를 모두 사용하는 경우 두 합성 된 규칙 (>> >> b)의 속성이 튜플이어야한다고 말합니다.부스트 :: 스피릿에서 속성 구성이 작동하지 않음

이것을 가정하면 이러한 튜플의 첫 번째 특성을 읽으려고했습니다. 그러나 실패 :
은 (나는에 구문 분석 된 정수를 저장하려고 'I')

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 
#include <boost/spirit/include/phoenix_object.hpp> 

template <typename ForwardIterator> class TestGrammar 
: public boost::spirit::qi::grammar<ForwardIterator, boost::spirit::ascii::space_type> 
{ 
    boost::spirit::qi::rule<ForwardIterator, boost::spirit::ascii::space_type> foo_; 
public: 
    TestGrammar(void) : TestGrammar::base_type(foo_) 
    { 
     int i; 
     foo_ = ((boost::spirit::qi::int_ >> boost::spirit::qi::float_) 
         [boost::phoenix::ref(i) = boost::phoenix::at_c<0>(boost::spirit::_1)]); 
    } 
}; 

int main(void) 
{ 
    TestGrammar<std::string::iterator> g; 

    return 0; 
} 

쓰기 :

foo_ = ((boost::spirit::qi::int_ >> boost::spirit::qi::float_) 
        [boost::phoenix::ref(i) = boost::spirit::_1]); 

항상 작동 한 A는 int이며으로하지만.
형식을 앞뒤로 바꾸고 사용자 지정 규칙을 작성하면 B가 무엇인지에 관계없이 (a >> b)의 특성이 항상 A로 나타납니다.

에도

답변

2

나는 당신이하고 싶었던 것 같아요 : 당신이 정말로 순서를 사용하고자하는 경우

int i; 
float f; 
foo_ = (boost::spirit::qi::int_ >> boost::spirit::qi::float_) 
      [ boost::phoenix::ref(i) = boost::spirit::_1, 
       boost::phoenix::ref(f) = boost::spirit::_2 ]; 

을 시도 :

foo_ = qi::attr_cast<>(qi::int_ >> qi::float_) 
       [ boost::phoenix::ref(i) = phx::at_c<0>(qi::_1), 
        boost::phoenix::ref(f) = phx::at_c<1>(qi::_1) ] 

또는 도우미 규칙 :

helper = qi::int_ >> qi::float_; 
foo_ = helper 
       [ boost::phoenix::ref(i) = phx::at_c<0>(qi::_1), 
        boost::phoenix::ref(f) = phx::at_c<1>(qi::_1) ] 
    ; 

세 가지 버전 모두 http://liveworkspace.org/code/518f2bd03e1fed7ed734d62071a88eab

+0

감사합니다! :) 그거야. – iolo

1

이 컴파일 할 경우

1>e:\work\test\spiritprob\spiritprob\spiritprob.cpp(14) : error C2065: 'bar' : undeclared identifier 
1>  e:\boost\boost_1_44_0\boost_1_44_0\boost\spirit\home\support\action_dispatch.hpp(29) : see reference to function template instantiation 'void TestDelegate::operator()<Attribute,Context,bool>(const T &,const U &,const V &) const' being compiled 
1>  with 
1>  [ 
1>   Attribute=boost::fusion::vector2<int,float>, 
1>   Context=boost::spirit::context<boost::fusion::cons<boost::fusion::unused_type &,boost::fusion::nil>,boost::fusion::vector0<>>, 
1>   T=boost::fusion::vector2<int,float>, 
1>   U=boost::spirit::context<boost::fusion::cons<boost::fusion::unused_type &,boost::fusion::nil>,boost::fusion::vector0<>>, 
1>   V=bool 
1>  ] 

(비주얼 스튜디오 2008에서 컴파일 :

struct TestDelegate 
{ 
    template <typename T, typename U, typename V> 
    void operator()(T const& t, U const& u, V const& v) const { 
     bar; 
    } 
}; 

template <typename ForwardIterator> class TestGrammar 
: public boost::spirit::qi::grammar<ForwardIterator, boost::spirit::ascii::space_type> 
{ 
    boost::spirit::qi::rule<ForwardIterator, boost::spirit::ascii::space_type> foo_; 
public: 
    TestGrammar(void) : TestGrammar::base_type(foo_) 
    { 
     //int i; 
     TestDelegate test_delegate; 
     //foo_ = ((boost::spirit::qi::int_ >> boost::spirit::qi::float_) 
     //    [boost::phoenix::ref(i) = boost::phoenix::at_c<0>(boost::spirit::_1)]); 
     foo_ = ((boost::spirit::qi::int_ >> boost::spirit::qi::float_) 
         [test_delegate]); 
    } 
}; 

int main(void) 
{ 
    TestGrammar<std::string::iterator> g; 

    return 0; 
} 

당신은 속성 유형은 튜플이라는 결과 오류 에세이에서 볼 수를)

직접적으로 우리의 문제를 해결하지는 못하지만 적어도 c 오메 밖으로 fusion::vector<int,float>

+0

비록 'bar'표현식을 변경해야만 제 컴파일러가 올바른 유형을 인쇄 할 수 있습니다. 하지만 '_1'대신에 문제가있는 것 같습니다. 조사해 보겠습니다. – iolo

+0

여러분의 문제는 at_c의 인스턴스 시점에서 형식이 자리 표시 자 '_1'의 형식이며 시퀀스가 ​​아니라는 점이라고 생각합니다. 어쩌면 그것을 처리 할 함수 객체를 작성할 수도 있습니다. – Pete

+0

나는 3 가지 대안을 제시했다. 또한 관련 : [성령의 의미 론적 행동으로 매개 변수 유형을 감지] (http://stackoverflow.com/questions/9404189/detecting-the-parameter-types-in-a-spirit-semantic-action) – sehe

관련 문제