2013-08-09 5 views
2

이것은 몇 시간 동안 나를 괴롭 히고 있으며 어떻게 작동시키는 지 이해할 수 없습니다. 규칙을 사용할 때마다 무언가를하고 싶습니다.이 예제에서는 카운터를 늘립니다. 명시 적으로 규칙을 지정하지 않고 boost :: spirit :: karma :: generate를 호출 할 때 규칙을 사용하면 작동합니다. 그러나 모든 것을 규칙에 넣으려고하면 컴파일되지 않으며 오랜 오류 메시지로 인해 통찰력을 얻지 못합니다. 가장 우아한 부스트 :: 정신 버전을 볼 수 있지만, 람다 함수 또는 멤버 함수 같은 모든 결과를 사용하여 수 중에서도 boost :: spirit :: karma 생성자 규칙의 의미 론적 동작

#include <iostream> 
#include <string> 

#include <boost/spirit/include/karma.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 

int main() 
{ 
    using boost::spirit::karma::eps; 
    using boost::spirit::karma::int_; 
    using boost::spirit::karma::lit; 
    using boost::spirit::karma::eol; 
    using boost::phoenix::val; 
    using boost::phoenix::ref; 
    using boost::spirit::karma::generate; 
    using boost::spirit::karma::rule; 

    typedef std::back_insert_iterator<std::string> OutputIteratorType; 

    std::string s; 
    std::back_insert_iterator<std::string> sink(s); 
    int lineNum = 0; 

    generate(sink, eps[ref(lineNum) += 10] << lit("Line number ") << lit(lineNum) << lit(": ") << int_ << eol, 123); 
    generate(sink, eps[ref(lineNum) += 10] << lit("Line number ") << lit(lineNum) << lit(": ") << int_ << eol, 123); 

    // Will not compile 
    //rule<OutputIteratorType, int()> testRule = eps[ref(lineNum) += 10] << lit("Line number ") << lit(lineNum) << lit(": ") << int_ << eol; 
    //generate(sink, testRule, 123); 
    //generate(sink, testRule, 123); 

    std::cout << s; 
    return 0; 
} 

(즉, "직접 방법"은 "규칙 방법"을 작동 그렇지 않습니다.)

불행히도이 문서를 포함하는 문서 나 예제 또는 기타 리소스를 찾을 수 없으므로 참조 용으로도 매우 감사 할 것입니다.

답변

3

그건 boost :: phoenix V2의 문제입니다 (어떤 질문을하지 마십시오 ;-)). 따라서 V3를 사용하면됩니다.

또한 int 생성기에 특성을 제공하고 인쇄 할 때 lineNum을 참조해야합니다.

#include <iostream> 
#include <string> 

#define BOOST_SPIRIT_USE_PHOENIX_V3 

#include <boost/spirit/include/karma.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 

int main() { 
    using boost::spirit::karma::eps; 
    using boost::spirit::karma::int_; 
    using boost::spirit::karma::lit; 
    using boost::spirit::karma::eol; 
    using boost::spirit::karma::_1; 
    using boost::spirit::karma::_val; 
    using boost::phoenix::val; 
    using boost::phoenix::ref; 
    using boost::spirit::karma::generate; 
    using boost::spirit::karma::rule; 

    typedef std::back_insert_iterator<std::string> OutputIteratorType; 

    std::string s; 
    std::back_insert_iterator<std::string> sink(s); 
    int lineNum = 0; 

    rule<OutputIteratorType, int()> testRule = eps[ref(lineNum) += 10] 
     << lit("Line number ") << lit(ref(lineNum)) << lit(": ") 
     << int_[_1 = _val] << eol; 
    generate(sink, testRule, 123); 
    generate(sink, testRule, 123); 

    std::cout << s; 
    return 0; 
} 
+0

정신 V2로 컴파일 한 코드도 있으므로 int_ generator에 속성을 지정하는 것이 중요한 단계였습니다. (lineNum을 언급하지 못했지만 그것이 왜 필요한지 분명하지 않습니다.) int_ generator를 수정해야하는 이유를 설명해 주시겠습니까? 나는이 규칙을 따르는보다 복잡한 규칙을 가지고 있기 때문에 여전히 실제 규칙을 따르는 데 문제가 있습니다. "[_1 = _val]"은 도움이되지 않습니다. – Xoph

+1

아마도 % = 또한 위의 cv_and_he처럼 도움이됩니다. 그렇지 않으면 그냥 규칙을 배제하고'[_1 = _val]'을 덧붙이면이 요소의 유형이 방금 분해 한 규칙의 유형이됩니다. '_2, _3, _4, ... '를 통해 각 규칙에 값을 할당하고'phx :: at_c (_val)'을 제공 할 수도 있습니다. –

+0

나는 실제로 내 규칙을 지금 일할 수있다. 끝내주게, 고마워! 나는 [+]가 +보다 강하게 묶는 것을 놓쳤다. 그래서 한 쌍의 괄호가 "[_1 = _val]"마술을 만들었다. 그러나, 나는 아직도 이것이 왜 필요한지 전혀 모른다. 그리고 아마 나는 그것을 스스로 알아 내지 못할 것이다. 그래서 설명이 크게 감사하겠습니다! – Xoph