문제
나는 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]
제휴하지 않습니다 StackOverflow