- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
Michael Caisse 发表了关于 Spirit X3 的演讲:https://www.youtube.com/watch?v=xSBWklPLRvw .我试图将演示文稿转录为工作代码,但出现编译错误,包括“没有可行的重载‘=’”和“没有对‘move_to’的匹配函数调用。”我的 phrase_parse(最后一行)定义正确吗?有明显的错误吗?
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/container/stable_vector.hpp>
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <map>
namespace client { namespace ast
{
namespace x3 = boost::spirit::x3;
using string_t = std::string;
using double_t = double;
using float_t = double;
using int_t = int64_t;
using bool_t = bool;
struct null_t {};
class value;
using object_t = std::map<std::string, value>;
using object_member_t = object_t::value_type;
using array_t = boost::container::stable_vector<value>;
class value : public x3::variant<null_t, bool_t, string_t, int_t, double_t, object_t, array_t>
{
public:
using value_type = value;
using base_type::base_type;
using base_type::operator=;
value(null_t val = null_t{}) : base_type(val) {}
value(char const* val) : base_type(string_t(val)) {}
template<typename T>
value(T val, typename std::enable_if<std::is_floating_point<T>::value>::type) : base_type(double_t{val}) {}
template<typename T>
value(T val, typename std::enable_if<std::is_integral<T>::value::type>) : base_type(int_t{val}) {}
};
struct json_class;
using json_type = x3::rule<json_class, value>;
json_type const json = "json";
BOOST_SPIRIT_DECLARE(json_type);
// identifier_class id
// identifier_type type
// identifier_def rule def
// identifier the rule
struct value_class;
struct object_class;
struct member_pair_class;
struct array_class;
using value_type = x3::rule<value_class, value>;
using object_type = x3::rule<object_class, object_t>;
using member_pair_type = x3::rule<member_pair_class, object_member_t>;
using array_type = x3::rule<array_class, array_t>;
value_type const value = "value";
object_type const object = "object";
member_pair_type const member_pair = "member_pair";
array_type const array = "array";
auto const append = [](auto& ctx){ _val(ctx) += _attr(ctx); };
using uchar = unsigned char;
x3::uint_parser<uchar, 16, 4, 4> const hex4 = {};
auto push_esc = [](auto& ctx)
{
auto& utf8 = _val(ctx);
switch (_attr(ctx))
{
case '"' : utf8 += '"'; break;
case '\\': utf8 += '\\'; break;
case '/' : utf8 += '/'; break;
case 'b' : utf8 += '\b'; break;
case 'f' : utf8 += '\f'; break;
case 'n' : utf8 += '\n'; break;
case 'r' : utf8 += '\r'; break;
case 't' : utf8 += '\t'; break;
}
};
auto push_utf8 = [](auto& ctx)
{
typedef std::back_insert_iterator<std::string> insert_iter;
insert_iter out_iter(_val(ctx));
boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
*utf8_iter++ = _attr(ctx);
};
auto const escape = ('u' > hex4) [push_utf8]
| x3::char_("\"\\/bfnrt") [push_esc];
auto const char_esc = '\\' > escape;
auto const double_quoted = x3::lexeme[ '"' > *(char_esc) | (x3::char_("\x20\x21\x23-\x5b\x5d\x7e")) [append] > '"' ];
struct unicode_string_class;
using unicode_string_type = x3::rule<unicode_string_class, std::string>;
unicode_string_type const unicode_string = "unicode_string";
auto const unicode_string_def = double_quoted;
BOOST_SPIRIT_DEFINE(unicode_string);
auto const null_value = x3::lit("null") >> x3::attr(null_t{});
x3::int_parser<int64_t> const int_ = {};
x3::ascii::bool_type const bool_value = {};
auto const object_def = x3::lit('{') >> -(member_pair % ',') >> x3::lit('}');
auto const member_pair_def = unicode_string >> ':' >> value;
auto const array_def = x3::lit('[') >> -(value % ',') >> x3::lit(']');
auto const value_def = null_value | bool_value | object | array | unicode_string
| x3::lexeme[!('+' | (-x3::lit('-') >> '0' >> x3::digit)) >> x3::int_ >> !x3::char_(".eE")]
| x3::lexeme[!('+' | (-x3::lit('-') >> '0' >> x3::digit)) >> x3::double_ ];
BOOST_SPIRIT_DEFINE(value, object, member_pair, array);
}
}
int main(int argc, char **argv)
{
namespace x3 = boost::spirit::x3;
std::string storage; // We will read the contents here.
using boost::spirit::x3::ascii::space;
std::string::const_iterator iter = storage.begin();
std::string::const_iterator iter_end = storage.end();
client::ast::object_t o;
auto const grammar = client::ast::value;
bool r = phrase_parse(iter, iter_end, grammar, space, o);
}
最佳答案
好吧,我必须解决很多错误/怪癖。
我熨烫的一部分是清理我通常做的不同的事情。这是工作结果:
#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/container/stable_vector.hpp>
#include <iterator>
#include <fstream>
#include <string>
#include <map>
namespace client {
namespace x3 = boost::spirit::x3;
namespace ast
{
using string_t = std::string;
using double_t = double;
using float_t = double;
using int_t = int64_t;
using bool_t = bool;
struct null_t {};
class value;
using object_t = std::map<std::string, value>;
using object_member_t = object_t::value_type;
using member_pair_t = std::pair<object_t::key_type, object_t::mapped_type>;
using array_t = boost::container::stable_vector<value>;
class value : public x3::variant<null_t, bool_t, string_t, int_t, double_t, object_t, array_t>
{
public:
using value_type = value;
using base_type::base_type;
using base_type::operator=;
value(null_t val = null_t{}) : base_type(val) {}
value(char const* val) : base_type(string_t(val)) {}
template<typename T>
value(T val, typename std::enable_if<std::is_floating_point<T>::value>::type) : base_type(double_t{val}) {}
template<typename T>
value(T val, typename std::enable_if<std::is_integral<T>::value::type>) : base_type(int_t{val}) {}
};
}
namespace parser
{
auto const append = [](auto& ctx){ x3::_val(ctx) += x3::_attr(ctx); };
using uchar = unsigned char;
x3::uint_parser<uchar, 16, 4, 4> const hex4 = {};
auto push_esc = [](auto& ctx) {
auto& utf8 = x3::_val(ctx);
switch (x3::_attr(ctx))
{
case '"' : utf8 += '"'; break;
case '\\': utf8 += '\\'; break;
case '/' : utf8 += '/'; break;
case 'b' : utf8 += '\b'; break;
case 'f' : utf8 += '\f'; break;
case 'n' : utf8 += '\n'; break;
case 'r' : utf8 += '\r'; break;
case 't' : utf8 += '\t'; break;
}
};
auto push_utf8 = [](auto& ctx) {
typedef std::back_insert_iterator<std::string> insert_iter;
insert_iter out_iter(x3::_val(ctx));
boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
*utf8_iter++ = x3::_attr(ctx);
};
auto const escape = ('u' > hex4) [push_utf8]
| x3::char_("\"\\/bfnrt") [push_esc];
auto const char_esc = '\\' > escape;
auto const double_quoted = x3::lexeme[
'"' > *(char_esc | (x3::char_("\x20\x21\x23-\x5b\x5d-\x7e") [append])) > '"'
];
auto const unicode_string
= x3::rule<struct unicode_string_class, std::string> { "unicode_string" }
= double_quoted;
auto const null_value = x3::lit("null") >> x3::attr(ast::null_t{});
x3::ascii::bool_type const bool_value = {};
using value_type = x3::rule<struct value_class, ast::value>;
static value_type const value = "value";
auto const member_pair = x3::rule<struct member_pair_class, ast::member_pair_t> { "member_pair" }
= unicode_string >> ':' >> value;
auto const object = x3::rule<struct object_class, ast::object_t> { "object" }
= x3::lit('{') >> -(member_pair % ',') >> x3::lit('}');
auto const array = x3::rule<struct array_class, ast::array_t> { "array" }
= x3::lit('[') >> -(value % ',') >> x3::lit(']');
x3::real_parser<double, x3::strict_real_policies<double> > const double_ = {};
x3::int_parser<int64_t> const int_ = {};
auto const value_def = null_value | bool_value | object | array | unicode_string | double_ | int_ ;
BOOST_SPIRIT_DEFINE(value)
auto const json = x3::skip(x3::ascii::space) [ value ];
}
}
int main()
{
std::string storage = R"({ "check": [ 1,2,3, null, true ], "more": { "nested" : "values" } })";
client::ast::value o;
return parse(storage.begin(), storage.end(), client::parser::json, o)? 0 : 255;
}
输出:
<value>
<try>{ "check": [ 1,2,3, </try>
<object>
<try>{ "check": [ 1,2,3, </try>
<member_pair>
<try> "check": [ 1,2,3, n</try>
<unicode_string>
<try> "check": [ 1,2,3, n</try>
<success>: [ 1,2,3, null, tru</success>
<attributes>[c, h, e, c, k]</attributes>
</unicode_string>
<value>
<try> [ 1,2,3, null, true</try>
<object>
<try>[ 1,2,3, null, true </try>
<fail/>
</object>
<array>
<try>[ 1,2,3, null, true </try>
<value>
<try> 1,2,3, null, true ]</try>
<object>
<try>1,2,3, null, true ],</try>
<fail/>
</object>
<array>
<try>1,2,3, null, true ],</try>
<fail/>
</array>
<unicode_string>
<try>1,2,3, null, true ],</try>
<fail/>
</unicode_string>
<success>,2,3, null, true ], </success>
<attributes>1</attributes>
</value>
<value>
<try>2,3, null, true ], "</try>
<object>
<try>2,3, null, true ], "</try>
<fail/>
</object>
<array>
<try>2,3, null, true ], "</try>
<fail/>
</array>
<unicode_string>
<try>2,3, null, true ], "</try>
<fail/>
</unicode_string>
<success>,3, null, true ], "m</success>
<attributes>2</attributes>
</value>
<value>
<try>3, null, true ], "mo</try>
<object>
<try>3, null, true ], "mo</try>
<fail/>
</object>
<array>
<try>3, null, true ], "mo</try>
<fail/>
</array>
<unicode_string>
<try>3, null, true ], "mo</try>
<fail/>
</unicode_string>
<success>, null, true ], "mor</success>
<attributes>3</attributes>
</value>
<value>
<try> null, true ], "more</try>
<success>, true ], "more": { </success>
<attributes></attributes>
</value>
<value>
<try> true ], "more": { "</try>
<success> ], "more": { "neste</success>
<attributes>1</attributes>
</value>
<success>, "more": { "nested"</success>
<attributes>[1, 2, 3, , 1]</attributes>
</array>
<success>, "more": { "nested"</success>
<attributes>[1, 2, 3, , 1]</attributes>
</value>
<success>, "more": { "nested"</success>
<attributes>[[c, h, e, c, k], [1, 2, 3, , 1]]</attributes>
</member_pair>
<member_pair>
<try> "more": { "nested" </try>
<unicode_string>
<try> "more": { "nested" </try>
<success>: { "nested" : "valu</success>
<attributes>[m, o, r, e]</attributes>
</unicode_string>
<value>
<try> { "nested" : "value</try>
<object>
<try>{ "nested" : "values</try>
<member_pair>
<try> "nested" : "values"</try>
<unicode_string>
<try> "nested" : "values"</try>
<success> : "values" } }</success>
<attributes>[n, e, s, t, e, d]</attributes>
</unicode_string>
<value>
<try> "values" } }</try>
<object>
<try>"values" } }</try>
<fail/>
</object>
<array>
<try>"values" } }</try>
<fail/>
</array>
<unicode_string>
<try>"values" } }</try>
<success> } }</success>
<attributes>[v, a, l, u, e, s]</attributes>
</unicode_string>
<success> } }</success>
<attributes>[v, a, l, u, e, s]</attributes>
</value>
<success> } }</success>
<attributes>[[n, e, s, t, e, d], [v, a, l, u, e, s]]</attributes>
</member_pair>
<success> }</success>
<attributes>[[[n, e, s, t, e, d], [v, a, l, u, e, s]]]</attributes>
</object>
<success> }</success>
<attributes>[[[n, e, s, t, e, d], [v, a, l, u, e, s]]]</attributes>
</value>
<success> }</success>
<attributes>[[m, o, r, e], [[[n, e, s, t, e, d], [v, a, l, u, e, s]]]]</attributes>
</member_pair>
<success></success>
<attributes>[[[c, h, e, c, k], [1, 2, 3, , 1]], [[m, o, r, e], [[[n, e, s, t, e, d], [v, a, l, u, e, s]]]]]</attributes>
</object>
<success></success>
<attributes>[[[c, h, e, c, k], [1, 2, 3, , 1]], [[m, o, r, e], [[[n, e, s, t, e, d], [v, a, l, u, e, s]]]]]</attributes>
</value>
一些注意事项:
分配失败是因为解析器规则 value
结果类型为 value
的对象, 不是 object_t
...
object_member_t
是一对 std::string
<强> const
第一个类型。哎呀。那不能分配给任何一个。所以,制作你自己的 pair-type 并使用它:
using member_pair_t = std::pair<object_t::key_type, object_t::mapped_type>;
我的 g++5 似乎无法执行 _attr
的 ADL 查找和 _val
如果不合格。我不确定这是编译器问题还是什么。我刚去了 x3::_attr
和 x3::_val
现在
规则定义中缺少大量括号,导致规则难以阅读/检查。添加了它们
unicode_string
原来是坏了(见下文)
int_parser<int64_t>
从未使用过(?呵呵)。使用它:)
数字解析未运行。同时,它看起来过于复杂。我建议使用 double_ | int_
其中 double_
使用严格的策略:
x3::real_parser<double, x3::strict_real_policies<double> > const double_ = {};
风格问题:
不要让来电者负责选择船长。毕竟,如果你使用 x3::char_("+8")
作为船长,事情要么会中断,要么无法成为 JSON?我建议一个顶级规则来介绍船长:
auto const json = x3::skip(x3::ascii::space) [ value ];
测试驱动程序可以少很多噪音:
std::string storage = R"({ "check": [ 1,2,3, null, true ], "more": { "nested" : "values" } })";
client::ast::value o;
bool r = parse(storage.begin(), storage.end(), client::parser::json, o);
我为未“外部”使用的规则删除了嘈杂的 _class/_type/_def 舞蹈(在这个简单的代码示例中,任何未递归使用的内容:value
)
使用 BOOST_SPIRIT_X3_DEBUG
看看发生了什么:)(这让我发现了 x3::char_("\x20\x21\x23-\x5b\x5d\x7e")
中的错误,看到缺少的破折号了吗?)
关于c++ - 编译错误 C++ Spirit X3 No viable overloaded =, No matching function for call to move_to,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34196845/
我正在尝试在表格中插入一个简单的行。有人可以指出这里发生了什么吗? CREATE TABLE recommendation_engine_poc.user_by_category (
我有一个任务是编写简单的解析器生成器,所以我编写了类似 ANTLR 的语法并尝试解析像“foo:bar;”这样的简单文件,但得到了以下输出: [@0,0:2='foo',,1:0] [@1,3:3='
我有一个看起来像这样的类: class MemberListEntry { public: int id; short port; long heartbeat; lo
我一直在尝试获取SLF4J处理的所有ANTLR错误消息,以便它们在其他消息中以适当的顺序显示,但是我没有任何运气。 按照Error Reporting and Recovery的示例,我尝试覆盖 em
这是 xcode 上的 IOS 代码块在编译时抛出错误。 “语义问题:没有可行的重载=” ... ccColor3B c_=; static dispatch_once_t onceTok
#include #include #include #include using namespace std; struct Node1 { unsigned int vertex;
这是我的一些代码: #include "pugi/pugixml.hpp" #include #include #include int main() { pugi::xml_docum
我正在尝试编写一些 Ruta 规则,以围绕日期创建时间注释。下面的测试显示了我如何尝试做到这一点。 @Test public void test__Ruta__AnnotateDate() throw
我正在尝试使用房间库的@Query 注释更新表,下面是我的代码(在 Dao 接口(interface)中): @Query("UPDATE table_name SET table_name.col1
我正在使用可用的 Objective C 语法 here ,并尝试解析这段代码: int main() { int k=0; } 这是一个客观的 C 代码,它应该被解析,但是当我调用函数
所以,似乎每次我尝试编译时,我都遇到了一个涉及的问题 “错误:没有匹配函数来调用‘search_and_report’” while(name!="!") { label =
我正在尝试按如下方式从 C++ STL 实现映射: #include #include #include using namespace std; #include "assembler.h"
我试图将一个 CUDA 项目移植到 ROCm 平台,该平台广泛使用 C++ 模板。在此过程中,出现以下编译错误 /root/warp-ctc/include/detail/gpu_ctc.h:381:
我正在尝试使用 MPI_Op_create() 创建我自己的缩减,以便我可以为函数 MPI_Allreduce() 传递自定义结构类型。例如,请参见链接:http://www.netlib.org/u
我正在 Qt 框架内学习 SQLite 和 C++。作为一个学习项目,我正在做一个简单的图像查看器,它使用户能够使用关键字、类别、评论和 ROI(用于稍后的 OpenCV 功能)来标记图像。这是一个非
我正在为我的一门类(class)做一个项目,我很确定我几乎完成了这个项目。基本上我必须输入 2 人的票,我必须找到最高价和最低价。我需要重载 * 和/运算符来解决该项目的问题。此外,根据老师的指示,f
VB6 和.NET 之间的互操作是一种可行的开发策略吗? 我正在开发一个与一些 .NET 程序集互操作的 VB6 应用程序,但“冷启动”和其他内聚问题的组合导致了不平滑的结果。 最佳答案 编辑 - 缩
在 Athena 中创建表时;它给了我以下异常: no viable alternative at input 最佳答案 表名中不允许使用连字符..(虽然向导允许).. 只需删除连字符,它就像一个魅力
此功能的目的是将.txt文件的各行放入不大于20的数组中。但是,如果不将循环中的每一行分配给该数组,我不知道如何进行处理。 int read_file(string file_name, person
我试图将 vector 作为参数/参数传递给函数,以便打印/返回 list/array/vector #include using namespace std; int printVector(ve
我是一名优秀的程序员,十分优秀!