残念ながら(MSVCがサポートされている必要があるため)qiを使用して一般的なパーサ要素を作成しようとしていますが、X3を使用することはできません。 アイデアは、テンプレート構造体を持っていることです。qiを使用して汎用パーザを作成するにはどうすればよいですか?
私はこのように使用することができtemplate<class T> struct parse_type;
:主な目的は、簡単のためにできるようにすることです。この
template<class T,class Alloc>
struct parse_type<std::vector<T,Alloc>>
{
// Parse a vector using rule '[' >> parse_type<T> % ',' > ']';
}
よう
template<class T> T from_string(std::string const& s)
{
T res;
parse_type<T> t;
...
if (phrase_parse(...,parse_type<T>(),...,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");
}
コードがブースト/ function_template.hppライン766で失敗します。
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);
}
このコードは、ブーストのメンバ関数です::機能4 、後押し::融合を:: boost :: spirit :: unused_type const &> となり、問題はget_vtableが無効なポインタを返すことです。
私はそれほど気にしませんが、ここでの下降理由はどうなっているのでしょうか? – user3721426