불행히도 (MSVC가 지원되어야 함) X3을 사용할 수 없으므로 qi를 사용하여 일반 파서 요소를 만들려고합니다.qi를 사용하여 일반 구문 분석기를 어떻게 작성합니까?
template<class T> struct parse_type;
I는 다음과 같이 사용할 수 있습니다 : 아이디어는 템플릿 구조체 것입니다
template<class T> T from_string(std::string const& s)
{
T res;
parse_type<T> t;
...
if (phrase_parse(...,parse_type<T>(),...,t))
}
또는이
template<class T,class Alloc>
struct parse_type<std::vector<T,Alloc>>
{
// Parse a vector using rule '[' >> parse_type<T> % ',' > ']';
}
주된 목적처럼 전문 쉽지 수 있도록하는 것입니다 예를 들어 파싱 std :: tuple, boost :: optional 그리고 boost :: variant (qi의 탐욕스러운 특성 때문에 마지막 하나는 자동 일 수 없다).
어떻게 접근했는지에 대한 의견을 보내 주시면 감사하겠습니다. 현재 qi :: grammar에 기초를두고 있지만 문법은 X3에서 지원되지 않으며 MSVC가 이것을 컴파일 할 때 X3을 사용하고 싶습니다. 또한 선장에게 제공하는 데 약간 불편합니다. 대안은 parse_type에 적절한 규칙을 반환하는 정적 함수를 갖는 것입니다. 이것이 더 깨끗한 접근법이라면 나는 고려 중이다.
모든 의견을 환영합니다.
Update2 : 런타임시 오류가 발생하는 컴파일 가능한 예제로 대체 된 코드 조각.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <string>
#include <iostream>
#include <iostream>
// Support to simplify
using iter = std::string::const_iterator;
void print(std::vector<int> const& v)
{
std::cout << '[';
for (auto i: v) std::cout << i << ',';
std::cout << "]";
}
namespace qi = boost::spirit::qi;
// My rule factory - quite useless if you do not specialise
template<class T> struct ps_rule;
// An example of using the factory
template<class T>
T from_string(std::string const& s)
{
T result;
iter first { std::begin(s) };
auto rule = ps_rule<T>::get();
phrase_parse(first,std::end(s),rule,qi::space,result);
return result;
}
// Specialising rule for int
template<>
struct ps_rule<int>
{
static qi::rule<iter,int()> get() { return qi::int_; }
};
// ... and for std::vector (where the elements must have rules)
template<class T,class Alloc>
struct ps_rule<std::vector<T,Alloc>>
{
static qi::rule<iter,std::vector<T,Alloc>()> get()
{
qi::rule<iter,std::vector<T,Alloc>()> res;
res.name("Vector");
res =
qi::lit('{')
>> ps_rule<T>::get() % ','
>> '}';
return res;
}
};
int main()
{
// This one works like a charm.
std::cout << ((from_string<int>("100") == 100) ? "OK\n":"Failed\n");
std::vector<int> v {1,2,3,4,5,6};
// This one fails
std::cout << ((from_string<std::vector<int>>("{1,2,3,4,5,6}") == v) ? "OK\n":"Failed\n");
}
코드는 766 부스트/function_template.hpp 라인에 실패 : 여기에 코드이 코드는 부스트의 멤버 함수 :: function4 가
result_type operator()(BOOST_FUNCTION_PARMS) const
{
if (this->empty())
boost::throw_exception(bad_function_call());
return get_vtable()->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
}
는, 부스트 : 융합 :: vector0> & , boost :: spirit :: unused_type const &> 이며 get_vtable이 잘못된 포인터를 반환한다는 점이 문제입니다.
나는 그다지 신경 쓰지 않지만 여기에 다운 투표의 이유가 무엇인지 궁금하다. – user3721426