Buon giorno,我必須決議以下內容:
foo: 123
"bar": 456
如果它們在這里,應該洗掉引號。我試過了:
(( x3::alnum) | ('"' >> ( x3::alnum) >> '"'))
但是對此的決議器操作是型別variant<string, string>;有沒有辦法讓決議器理解這兩者是等價的,并且我的動作std::string在它的呼叫中只得到一個作為引數?
編輯:最小復制(生活在 Godbolt 上:https ://gcc.godbolt.org/z/GcE8Pj4r5 ):
#include <boost/spirit/home/x3.hpp>
using namespace boost::spirit;
// action handlers
struct handlers {
void create_member(const std::string& str) { }
};
// rules
static const x3::rule<struct id_obj_mem> obj_mem = "obj_mem";
#define EVENT(e) ([](auto& ctx) { x3::get<handlers>(ctx).e(x3::_attr(ctx)); })
static const auto obj_mem_def = ((
(( x3::alnum) | ('"' >> ( x3::alnum) >> '"'))
>> ':' >> x3::lit("123"))[EVENT(create_member)] % ',');
BOOST_SPIRIT_DEFINE(obj_mem)
// execution
int main()
{
handlers r;
std::string str = "foo: 123";
auto first = str.begin();
auto last = str.end();
bool res = phrase_parse(
first,
last,
boost::spirit::x3::with<handlers>(r)[obj_mem_def],
boost::spirit::x3::ascii::space);
}
uj5u.com熱心網友回復:
我也認為這是一種缺陷。X3 在綜合屬性型別方面肯定不那么“友好”。我想這只是更加面向核心語言的默認副作用,其中屬性分配通過默認的“訪問者”操作有效地完成。
盡管我理解將魔法保持在最低限度并接近“純 C ”的價值,但我非常喜歡 Qi 在這里合成屬性的方式。我相信它已被證明是一個很難解決的問題,因為這個問題在 X3 的某些迭代中已經出現/出現。
我早就決定用這個成語的變體基本上自己修復它:
template <typename T> struct as_type {
auto operator()(auto p) const { return x3::rule<struct Tag, T>{} = p; }
};
static constexpr as_type<std::string> as_string{};
現在我把它寫成:
auto quoted = '"' >> x3::alnum >> '"';
auto name = as_string( x3::alnum | quoted);
auto prop = (name >> ':' >> "123")[EVENT(create_member)] % ',';
這將編譯沒有問題:
住在科利魯
#include <boost/spirit/home/x3.hpp>
#include <iomanip>
#include <iostream>
namespace x3 = boost::spirit::x3;
struct handlers {
void create_member(std::string const& str) {
std::cerr << __FUNCTION__ << " " << std::quoted(str) << "\n";
}
};
namespace Parser {
#define EVENT(e) ([](auto& ctx) { get<handlers>(ctx).e(_attr(ctx)); })
template <typename T> struct as_type {
auto operator()(auto p) const { return x3::rule<struct Tag, T>{} = p; }
};
static constexpr as_type<std::string> as_string{};
auto quoted = '"' >> x3::alnum >> '"';
auto name = as_string( x3::alnum | quoted);
auto prop = (name >> ':' >> "123")[EVENT(create_member)] % ',';
auto grammar = x3::skip(x3::space)[prop];
} // namespace Parser
int main() {
handlers r;
std::string const str = "foo: 123";
auto first = str.begin(), last = str.end();
bool res = parse(first, last, x3::with<handlers>(r)[Parser::grammar]);
return res ? 1 : 0;
}
印刷
create_member "foo"
有趣的鏈接
- Spirit X3,如何獲取屬性型別以匹配規則型別?
- 在運行時組合規則并回傳規則
- Spirit x3 無法傳播 optional<vector> 型別的屬性
等等
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/513851.html
