문제

나는 ASCII 기반 프로토콜을 구문 분석하기 위해 Boost :: Spirit에 뛰어 들고 있습니다. 나는 다음과 같은 규칙을 사용하여 라인에서 값을 추출하기 위해 마네닝했습니다.

rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_a(buffer.speed)];

또한이 규칙을 의미있는 방식으로 연결하는 데 성공합니다. 완벽한 날에 누락 된 것은 다음과 같습니다. 데이터 값은 고정 변환 계수 (일반적으로 10의 전력)를 사용하여 부동 소수점 값으로 변환 해야하는 정수입니다.

내가 지금하는 일은 구문 분석 후 이러한 스케일링 요소를 임명하는 것입니다. 그러나 필드의 규칙 정의 내부에 스케일링 계수를 포함하도록 정말로 승인 할 것입니다. 나는 다음과 같은 것을 상상합니다.

rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_a(buffer.speed,100)];

제안이 있습니까?

미리 감사드립니다

도움이 되었습니까?

해결책

이를 수행하는 한 가지 방법은 사용하는 것입니다 boost.phoenix. 이 헤더 포함 :

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp> // For static_cast_
#include <boost/spirit/include/phoenix_operator.hpp> // For multiplication

그런 다음 다음과 같은 것을 사용하십시오.

using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;

rule<> Speed = uint_parser<unsigned int,10,3,3>()[
    ref(buffer.speed) = static_cast_<double>(arg1) * 100
];

그러나 나는 피닉스가 사용하기가 조금 까다 롭고 일반적으로 내 자신의 행동을 쓰십시오:

struct assign_scaled
{
    double& result;
    double scale;

    assign_with_scale(double& r, double scale) : result(r), scale(scale) {}

    void operator()(unsigned int x) const
    {
        result = static_cast<double>(x) * scale;
    }
};

다음과 같이 사용하십시오.

    rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_scaled(buffer.speed, 100)];

이것은 더 장점 일 수 있지만 유지하기가 더 쉽다는 것을 알게됩니다.

다른 팁

spirit.qi와 함께 사용할 수 있습니다 [ref(buffer.speed) = _1 * 100]

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top