나는 Boost.Spirit이 어떻게 작동하는지 배우려고합니다. 불행히도, 문서는 나에게 너무 간결하며 실제로 작동하는 방법을 알 수 없습니다.Boost.Spirit에 double_과 비슷한 파서를 만드는 법?
그럼, 제 문제로 옮기십시오. 나는 std::complex
타입의 파서를 작성하려고하는데, 그것은 내장 파서와 같은 방식으로 작동 할 것이다. int_
또는 double_
. 1.2+2i
, 3-i*4
, 5*i
등과 같이 다른 형식으로 복소수를 파싱하고 싶습니다. 솔직히 말해서 나는 무엇을 해야할지 몰랐습니다. 이 방법을 시도했습니다 :
typedef std::complex<double> Complex;
struct complex_parser : qi::grammar<Iterator, Complex(), ascii::space_type>
{
complex_parser() : complex_parser::base_type(value)
{
real = (
double_[_val = _1]
);
imaginary = (
(double_[_val = Complex(0.0, _1)] >> -(lit('*')) >> 'i')
| ('i' >> -(lit('*')) >> double_[_val = Complex(0.0, _1)])
);
value = (
imaginary[_val = _1]
| real[_val = _1] >> -('+' >> imaginary[_val += _1])
| real[_val = _1] >> -('-' >> imaginary[_val -= _1])
);
}
qi::rule<Iterator, Complex(), ascii::space_type> value;
qi::rule<Iterator, double(), ascii::space_type> real;
qi::rule<Iterator, double(), ascii::space_type> imaginary;
};
하지만 작동하지 않습니다. 6 과부하 아무도 [모든 인수 형식을 변환 할 수 없었다 :
오류 C2665 : '표준 : 복잡한 :: 복잡'구문 분석 할 때
imaginary
, 자리_1
이double
타입이 아니기 때문에 심지어 컴파일되지 않습니다 ...] 인수 목록 '(double, const boost :: spirit :: _ 1_type)과 일치 시키려고 시도하는 중'
왜 그런가? 나는 Complex()
대신 imaginary
규칙 (물론 real
) double()
매개 변수를주었습니다. 자리 표시자를 double
- 동일 유형으로 지정하면 안됩니까? 그렇지 않다면 왜 규칙에 유형을 설정해야합니까? 어떻게 그들을 제대로 사용 하는가?
그럼 내가 올바르게 이해하자. 게으른 평가에 관한 것입니다. 맞습니까? 즉,'phoenix :: construct'에 의한 게으른 평가가 없다면, 컴파일러는'_1' 자리 표시자가 어떤 타입인지 알지 못합니다. – Archie
_1은 특수 값 및 유형입니다. _1은 모든 유형의 값을 대체합니다. _1은 대상 유형에 대해 아무것도 모릅니다. (죄송합니다, 영어가 나쁩니다.) –
부스트 :: 스피릿과 부스트 :: 피닉스의 내부에 대해 잘 이해하려면이 훌륭한 시리즈를 살펴보십시오. http://cpp-next.com/archive/2010/08/expressive-c-introduction/ – mark