일부 출력은 입력 값의 중요한 속성에 의존하는 boost :: spirit :: karma 생성기를 작성하려고합니다.boost :: spirit :: karma 입력 속성에 기반한 대체 선택
실제 문제는 더 큰 문법의 일부이지만,이 예제는 다른 번거로운 규칙 중 일부와 동일한 속성을 가지며 실제로 문제를 일으키는 문법 규칙 중 하나입니다.
나는 거의 내가 원하는 것부터 시작해서 거기서 일할 것이다.
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/home/phoenix.hpp>
#include <boost/fusion/adapted.hpp>
#include <string>
#include <vector>
template<typename OutputIterator_T>
struct Test_Grammar :
boost::spirit::karma::grammar<OutputIterator_T, std::vector<double>()>
{
Test_Grammar() : Test_Grammar::base_type(start), start(), value()
{
namespace karma = boost::spirit::karma;
start
= *(value % karma::lit(", "))
;
value
= (karma::double_)
;
}
boost::spirit::karma::rule<OutputIterator_T, std::vector<double>()> start;
boost::spirit::karma::rule<OutputIterator_T, double()> value;
};
template <typename OutputIterator_T>
bool generate_output(OutputIterator_T& sink, std::vector<double> const& data)
{
Test_Grammar<OutputIterator_T> grammar;
return (boost::spirit::karma::generate(sink, grammar, data));
}
int main (int, char**)
{
std::string generated;
std::back_insert_iterator<std::string> sink(generated);
std::vector<double> data{1.5, 0.0, -2.5,
std::numeric_limits<float>::quiet_NaN(),
std::numeric_limits<float>::infinity()};
generate_output(sink, data);
std::cout << generated << std::endl;
return 0;
}
은, 상기 코드는 상기 테스트 데이터가 공급되면, 출력 단 1.5, 0.0, -2.5, nan, inf
를 생성하는 문법 제가
1.5, 0.0, -2.5, special, special
문법의 일부인 value
을
value
= (&karma::double_(std::numeric_limits<double>::quiet_NaN()) <<
karma::lit("special"))
| (&karma::double_(std::numeric_limits<double>::infinity()) <<
karma::lit("special"))
| (karma::double_)
;
무한대에 대해 원하는 동작을 얻습니다. 그러나 NaN은 비교에서 (NaN! = NaN) 속성을 갖기 때문에 NaN에 대해 원하는 결과를 얻지 못합니다. 그래서 isfinite()와 같은 fpclassify 매크로/함수를 사용하는 방법이 필요합니다.
내가 그러나
value
= (karma::eps(...) << karma::lit("special"))
| (karma::double_)
;
, 함수 호출, 함수 포인터의 모든 조합 문법의 value
부분을 대체하여 내가 원하는 것을 얻을 수있을, 나는이 재판을 한 주술을 결합한다 ...
부분에서 컴파일러 오류가 발생했습니다.
도움을 주시면 감사하겠습니다.
UPDATE :
는 Sehe (나는 수락) 우수한 일반적인 솔루션을 제공 하였다. 고맙습니다!
저는 특정 사용 사례에 대해 sehe의 대답을 더 단순화 할 수 있었고 다른 사람들을 위해 여기에 문서화하려고했습니다.
<boost/spirit/home/*>
에서 <boost/spirit/include/*>
에 포함 된 모든 변경과 그 포함 전에 BOOST_SPIRIT_USE_PHOENIX_V3
를 형성 후, 다음 줄
BOOST_PHOENIX_ADAPT_FUNCTION(bool, isfinite_, std::isfinite, 1)
을 첨가하고,이
value
%= karma::double_[karma::_pass = isfinite_(karma::_1)]
| karma::lit("special")
;
우수 질문 박람회. 이런 식으로 모든 질문을 소개하는 것을 좋아합니다. 도움이 진행 중입니다! – sehe