2011-03-29 3 views
1

내 규칙의 spirit lex example 4토큰 파서 세만 틱 액션

하나에 표시된 코드를 기반으로 작업 토큰 파서를 쓴이 잘 작동이

set_name 
     = ( tok.set_ >> tok.name_ >> tok.identifier) 
      [ 
       std::cout << val("set name statement to: ") << _3 << "\n" 
      ] 
     ; 

것 같습니다.

지금은 클래스에있는 이름을, 유용한 무언가를 저장할

XYZ :

SET NAME xyz 

되게 때 내가

세트 이름 문을 예상대로 출력합니다. parser semantic examples에서 근무 나는이

 
1>C:\Program Files\boost\boost_1_44\boost/bind/bind.hpp(318) : error C2664: 'R boost::_mfi::cmf1::operator()(const U &,A1) const' : cannot convert parameter 2 from 'bool' to 'const std::basic_string ' 
1>  with 
1>  [ 
1>   R=void, 
1>   T=eCrew::rule::writer, 
1>   A1=const std::string &, 
1>   U=eCrew::rule::writer * 
1>  ] 
1>  and 
1>  [ 
1>   _Elem=char, 
1>   _Traits=std::char_traits, 
1>   _Ax=std::allocator 
1>  ] 
1>  Reason: cannot convert from 'bool' to 'const std::string' 
1>  No constructor could take the source type, or constructor overload resolution was ambiguous 

를 컴파일되지 않습니다

class writer 
    { 
    public: 
     void print(string const& s) const 
     { 
      std::cout << s << std::endl; 
     } 
    }; 

    writer w; 

    ... 

    set_name 
     = ( tok.set_ >> tok.name_ >> tok.identifier) 
      [ 
       boost::bind(&writer::print, &w, ::_3) 
      ] 
     ; 

이 코드는 왜 컴파일러는 문자열 부울로 변환하려고에 대해 불평 쓰기? 내가 볼 수있는 bool이 없습니다.

std::cout << val("set name statement to: ") << _3 << "\n" 

+0

은 부울로 다시 선언되고 승입니까? 작가에게 더 독특한 변수 이름을 사용하면 어떻게됩니까? –

+0

@jon이 "the_writer"로 "w"변경되었습니다. 같은 결과. – ravenspoint

답변

3

틀은 boost.phoenix v2로 자리이다 boost::spirit::_3을 말한다. 자리 표시자는

boost::bind(&writer::print, &w, ::_3) 

은 boost.bind 자리 표시 자 (자연스럽게)입니다.

이러한 자리 표시자는 이 아니며은 동일한 동작을 공유하거나 동일한 데이터를 참조합니다. 형태의 피닉스 자리 _ N, 파서의 N 번째 하위 속성을 참조 바인드 자리는 다른 의미있는 동안 :

  • _1는 전체
  • _2 같은 파서의 속성을 참조를 파서의 상황을 말한다
  • _3는

귀하의 경우 가장 쉬운 솔루션을 계속 할 수 있도록, boost::bind 대신 boost::phoenix::bind를 사용하는 것입니다 bool& '히트'매개 변수를 의미 _3을 사용하여 파서의 세 번째 하위 특성을 참조하는 대신 writer::print 내부에서 수동으로 선택해야합니다.

또는 만 예상대로 tok.identifier에 의미 조치가 그래서 boost.bind의 ::_1 작품을 첨부 :에 ...

set_name 
    = tok.set_ 
    >> tok.name_ 
    >> tok.identifier[boost::bind(&writer::print, &w, ::_1)] 
; 
+0

이것은 좋은 생각 인 것 같습니다. 나는 그것을 시도하고 다시 당신에게 돌아갈 것입니다. – ravenspoint

+0

@ravenspoint : 다른 대안을 보여주기 위해 편집 됨. – ildjarn