- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
问题:
软件:使用Boost 1.52 boost 灵气
平台:Windows 7(64 位)
编译器(Visual Studio 2010)
请求:
帮助找出解析器未找到所有属性的原因。
查看调试输出,我发现属性没有被放入单个 std::vector 对象中。我正在使用在 http://www.json.org/ 上找到的 JSON 语法作为引用。我希望看到“成员”的输出是单个 std::vector,其中包含为该 JSON 对象找到的所有 json_pair 对象的列表。
限制:
代码:
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/make_shared.hpp>
#include <vector>
namespace signal_processing {
namespace parsing {
struct json_object;
struct json_array;
typedef boost::variant < std::string,
double,
boost::recursive_wrapper<json_object>,
boost::recursive_wrapper<json_array>,
bool > json_value;
typedef boost::tuple < std::string, json_value> json_pair;
struct json_members
{
std::vector < json_pair > items;
};
struct json_object
{
std::vector < json_members > children;
};
struct json_array
{
std::vector < json_value > list;
};
using boost::spirit::qi::bool_;
using boost::spirit::qi::char_;
using boost::spirit::qi::double_;
using boost::spirit::qi::eol;
using boost::spirit::qi::float_;
using boost::spirit::qi::int_;
using boost::spirit::qi::lexeme;
using boost::spirit::qi::lit;
using boost::spirit::qi::space;
using boost::spirit::qi::_val;
using boost::spirit::qi::_1;
template <typename Iterator, typename Skipper>
struct json_grammar : boost::spirit::qi::grammar < Iterator, json_object(), Skipper>
{
json_grammar() : json_grammar::base_type(object)
{
object = '{' > *members > '}';
pair = string > ':' > value;
members = pair > *( ',' > members );
element_list = '[' > *elements > ']';
elements = value > *( ',' > elements );
value = string |
number |
object |
element_list |
bool_ |
lit("null");
char const* exclude = " ();\"\n\r\t";
string = '"'
> +lexeme[char_ - char_(exclude)]
> '"';
// Return: double
number = double_ |
float_ |
int_;
BOOST_SPIRIT_DEBUG_NODE(object);
BOOST_SPIRIT_DEBUG_NODE(pair);
BOOST_SPIRIT_DEBUG_NODE(members);
BOOST_SPIRIT_DEBUG_NODE(element_list);
BOOST_SPIRIT_DEBUG_NODE(elements);
BOOST_SPIRIT_DEBUG_NODE(value);
BOOST_SPIRIT_DEBUG_NODE(string);
BOOST_SPIRIT_DEBUG_NODE(number);
}
boost::spirit::qi::rule < Iterator, json_object(), Skipper > object;
boost::spirit::qi::rule < Iterator, json_pair(), Skipper > pair;
boost::spirit::qi::rule < Iterator, json_members(), Skipper > members;
boost::spirit::qi::rule < Iterator, json_array(), Skipper > element_list;
boost::spirit::qi::rule < Iterator, json_array(), Skipper > elements;
boost::spirit::qi::rule < Iterator, json_value(), Skipper > value;
boost::spirit::qi::rule < Iterator, std::string(), Skipper > string;
boost::spirit::qi::rule < Iterator, double(), Skipper > number;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(
signal_processing::parsing::json_object,
(std::vector < signal_processing::parsing::json_members >, children)
)
BOOST_FUSION_ADAPT_STRUCT(
signal_processing::parsing::json_members,
(std::vector < signal_processing::parsing::json_pair >, items)
)
BOOST_FUSION_ADAPT_STRUCT(
signal_processing::parsing::json_array,
(std::vector < signal_processing::parsing::json_value >, list)
)
void parse ( std::string const& file )
{
typedef signal_processing::parsing::json_grammar < std::string::const_iterator, boost::spirit::ascii::space_type > configuration_grammar;
configuration_grammar input; // Input grammar
signal_processing::parsing::json_object parsed_data;
std::string::const_iterator iter = file.begin();
std::string::const_iterator end = file.end();
bool r = boost::spirit::qi::phrase_parse ( iter, end, input, boost::spirit::ascii::space, parsed_data );
if ( ! r || iter != end)
{
// Report the next 30 characters
std::string::const_iterator some = iter + 30;
if ( some > end )
{
some = end;
}
std::string context(iter, some);
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "stopped at: \": " << context << "...\"\n";
std::cout << "-------------------------\n";
}
}
int main(int,char**)
{
std::string input ( "{\r\n \"Event\": {\r\n \"attribute_a\": 0.0002,\r\n \"attribute_b\": 2e-005,\r\n \"attribute_c\": 0.022\r\n }\r\n}" );
parse ( input );
return 0;
}
最佳答案
解析器
第一个问题的答案通常是,可能有几种方法可以实现您想要的。具体来说,我可以向您展示一种似乎有效的方法。
关键是为匹配给定短语或标记的一个或多个实例的规则正确设置属性类型,方法是确保您实际声明的是一个容器,而不是一个具有成员的结构是一个容器。
完成后,您需要编写规则,以便 Qi 知道您正在处理一个容器,并且它应该适本地回填。
首先查看成员规则:您将其作为规则提供:
members = pair > *( ',' > members );
我不认为这本身足以告诉 Qi 你想让它用 pair
回填一个 json_members
容器,尤其是因为 pair
和 member
没有相同的属性类型。所以我建议您将规则替换为:
members = pair > *( ',' > pair );
甚至:
members = pair % ',';
您需要确定这些规则是否等同于同一件事,但您明白了。
关于 json_members
类型:我更改了您的结构定义,使结构派生自容器,而不是将容器作为结构的属性:
struct json_members : std::vector < json_pair > {};
而且您不需要对结构进行 fusion 。
在我看来,这是您的代码的工作版本:
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/make_shared.hpp>
#include <vector>
namespace signal_processing {
namespace parsing {
struct json_object;
struct json_array;
typedef boost::variant < std::string,
double,
boost::recursive_wrapper<json_object>,
boost::recursive_wrapper<json_array>,
bool > json_value;
typedef boost::tuple < std::string, json_value> json_pair;
// struct json_members
// {
// std::vector < json_pair > items;
// };
//
// struct json_object
// {
// std::vector < json_members > children;
// };
//
// struct json_array
// {
// std::vector < json_value > list;
// };
struct json_members : std::vector < json_pair > {};
struct json_object : std::vector < json_members > {};
struct json_array : std::vector < json_value > {};
using boost::spirit::qi::bool_;
using boost::spirit::qi::char_;
using boost::spirit::qi::double_;
using boost::spirit::qi::eol;
using boost::spirit::qi::float_;
using boost::spirit::qi::int_;
using boost::spirit::qi::lexeme;
using boost::spirit::qi::lit;
using boost::spirit::qi::space;
using boost::spirit::qi::_val;
using boost::spirit::qi::_1;
template <typename Iterator, typename Skipper>
struct json_grammar : boost::spirit::qi::grammar < Iterator, json_object(), Skipper>
{
json_grammar() : json_grammar::base_type(object)
{
object = '{' > *members > '}';
pair = string > ':' > value;
members = pair > *( ',' > pair );
element_list = '[' > *elements > ']';
elements = value > *( ',' > value );
value = string |
number |
object |
element_list |
bool_ |
lit("null");
char const* exclude = " ();\"\n\r\t";
string = '"'
> +lexeme[char_ - char_(exclude)]
> '"';
// Return: double
number = double_ |
float_ |
int_;
BOOST_SPIRIT_DEBUG_NODE(object);
BOOST_SPIRIT_DEBUG_NODE(pair);
BOOST_SPIRIT_DEBUG_NODE(members);
BOOST_SPIRIT_DEBUG_NODE(element_list);
BOOST_SPIRIT_DEBUG_NODE(elements);
BOOST_SPIRIT_DEBUG_NODE(value);
BOOST_SPIRIT_DEBUG_NODE(string);
BOOST_SPIRIT_DEBUG_NODE(number);
}
boost::spirit::qi::rule < Iterator, json_object(), Skipper > object;
boost::spirit::qi::rule < Iterator, json_pair(), Skipper > pair;
boost::spirit::qi::rule < Iterator, json_members(), Skipper > members;
boost::spirit::qi::rule < Iterator, json_array(), Skipper > element_list;
boost::spirit::qi::rule < Iterator, json_array(), Skipper > elements;
boost::spirit::qi::rule < Iterator, json_value(), Skipper > value;
boost::spirit::qi::rule < Iterator, std::string(), Skipper > string;
boost::spirit::qi::rule < Iterator, double(), Skipper > number;
};
}
}
// BOOST_FUSION_ADAPT_STRUCT(
// signal_processing::parsing::json_object,
// (std::vector < signal_processing::parsing::json_members >, children)
// )
//
// BOOST_FUSION_ADAPT_STRUCT(
// signal_processing::parsing::json_members,
// (std::vector < signal_processing::parsing::json_pair >, items)
// )
//
// BOOST_FUSION_ADAPT_STRUCT(
// signal_processing::parsing::json_array,
// (std::vector < signal_processing::parsing::json_value >, list)
// )
void parse ( std::string const& file )
{
typedef signal_processing::parsing::json_grammar < std::string::const_iterator, boost::spirit::ascii::space_type > configuration_grammar;
configuration_grammar input; // Input grammar
signal_processing::parsing::json_object parsed_data;
std::string::const_iterator iter = file.begin();
std::string::const_iterator end = file.end();
bool r = boost::spirit::qi::phrase_parse ( iter, end, input, boost::spirit::ascii::space, parsed_data );
if ( ! r || iter != end)
{
// Report the next 30 characters
std::string::const_iterator some = iter + 30;
if ( some > end )
{
some = end;
}
std::string context(iter, some);
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "stopped at: \": " << context << "...\"\n";
std::cout << "-------------------------\n";
}
}
int main(int,char**)
{
std::string input ( "{\r\n \"Event\": {\r\n \"attribute_a\": 0.0002,\r\n \"attribute_b\": 2e-005,\r\n \"attribute_c\": 0.022\r\n }\r\n}" );
parse ( input );
return 0;
}
哪些输出:
localhost stov # ./stov
<object>
<try>{\r\n "Event": {</try>
<members>
<try>\r\n "Event": {\r</try>
<pair>
<try>\r\n "Event": {\r</try>
<string>
<try>\r\n "Event": {\r</try>
<success>: {\r\n </success>
<attributes>[[E, v, e, n, t]]</attributes>
</string>
<value>
<try> {\r\n </try>
<string>
<try> {\r\n </try>
<fail/>
</string>
<number>
<try> {\r\n </try>
<fail/>
</number>
<object>
<try>{\r\n "</try>
<members>
<try>\r\n "a</try>
<pair>
<try>\r\n "a</try>
<string>
<try>\r\n "a</try>
<success>: 0.0002,\r\n </success>
<attributes>[[a, t, t, r, i, b, u, t, e, _, a]]</attributes>
</string>
<value>
<try> 0.0002,\r\n </try>
<string>
<try> 0.0002,\r\n </try>
<fail/>
</string>
<number>
<try> 0.0002,\r\n </try>
<success>,\r\n "</success>
<attributes>[0.0002]</attributes>
</number>
<success>,\r\n "</success>
<attributes>[0.0002]</attributes>
</value>
<success>,\r\n "</success>
<attributes>[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002]]</attributes>
</pair>
<pair>
<try>\r\n "a</try>
<string>
<try>\r\n "a</try>
<success>: 2e-005,\r\n </success>
<attributes>[[a, t, t, r, i, b, u, t, e, _, b]]</attributes>
</string>
<value>
<try> 2e-005,\r\n </try>
<string>
<try> 2e-005,\r\n </try>
<fail/>
</string>
<number>
<try> 2e-005,\r\n </try>
<success>,\r\n "</success>
<attributes>[2e-05]</attributes>
</number>
<success>,\r\n "</success>
<attributes>[2e-05]</attributes>
</value>
<success>,\r\n "</success>
<attributes>[[[a, t, t, r, i, b, u, t, e, _, b], 2e-05]]</attributes>
</pair>
<pair>
<try>\r\n "a</try>
<string>
<try>\r\n "a</try>
<success>: 0.022\r\n }\r\n</success>
<attributes>[[a, t, t, r, i, b, u, t, e, _, c]]</attributes>
</string>
<value>
<try> 0.022\r\n }\r\n}</try>
<string>
<try> 0.022\r\n }\r\n}</try>
<fail/>
</string>
<number>
<try> 0.022\r\n }\r\n}</try>
<success>\r\n }\r\n}</success>
<attributes>[0.022]</attributes>
</number>
<success>\r\n }\r\n}</success>
<attributes>[0.022]</attributes>
</value>
<success>\r\n }\r\n}</success>
<attributes>[[[a, t, t, r, i, b, u, t, e, _, c], 0.022]]</attributes>
</pair>
<success>\r\n }\r\n}</success>
<attributes>[[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002], [[a, t, t, r, i, b, u, t, e, _, b], 2e-05], [[a, t, t, r, i, b, u, t, e, _, c], 0.022]]]</attributes>
</members>
<members>
<try>\r\n }\r\n}</try>
<pair>
<try>\r\n }\r\n}</try>
<string>
<try>\r\n }\r\n}</try>
<fail/>
</string>
<fail/>
</pair>
<fail/>
</members>
<success>\r\n}</success>
<attributes>[[[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002], [[a, t, t, r, i, b, u, t, e, _, b], 2e-05], [[a, t, t, r, i, b, u, t, e, _, c], 0.022]]]]</attributes>
</object>
<success>\r\n}</success>
<attributes>[[[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002], [[a, t, t, r, i, b, u, t, e, _, b], 2e-05], [[a, t, t, r, i, b, u, t, e, _, c], 0.022]]]]</attributes>
</value>
<success>\r\n}</success>
<attributes>[[[E, v, e, n, t], [[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002], [[a, t, t, r, i, b, u, t, e, _, b], 2e-05], [[a, t, t, r, i, b, u, t, e, _, c], 0.022]]]]]</attributes>
</pair>
<success>\r\n}</success>
<attributes>[[[[E, v, e, n, t], [[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002], [[a, t, t, r, i, b, u, t, e, _, b], 2e-05], [[a, t, t, r, i, b, u, t, e, _, c], 0.022]]]]]]</attributes>
</members>
<members>
<try>\r\n}</try>
<pair>
<try>\r\n}</try>
<string>
<try>\r\n}</try>
<fail/>
</string>
<fail/>
</pair>
<fail/>
</members>
<success></success>
<attributes>[[[[[E, v, e, n, t], [[[[a, t, t, r, i, b, u, t, e, _, a], 0.0002], [[a, t, t, r, i, b, u, t, e, _, b], 2e-05], [[a, t, t, r, i, b, u, t, e, _, c], 0.022]]]]]]]</attributes>
</object>
统一码
我知道 boost::spirit 的 SVN 构建现在支持 UTF8;尝试使用谷歌搜索 BOOST_SPIRIT_UNICODE
。您现在可以使用库中的宽字符串支持来支持“unicode”(微软称之为)。
免责声明
我在 Linux 上工作。 YMMV.
关于c++ - 找不到 Qi JSON 解析器中缺少已解析属性的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14462098/
我正在尝试在 map 上绘制一些疾病事件数据的位置。 我用它来导入数据: ByTown% addProviderTiles("CartoDB.Positron")%>% addPolygons
我有一个文件调用 find.js,我使用 node find.js 运行,我的节点是版本 10 我不知道为什么我无法使用 async await。 const axios = require("axi
我有一个项目作为引用添加到 System.Web。 但是,它似乎无法获取 HttpContext。这样做: Imports System.Web _ApplicationBase = HttpCont
在互联网上找到这段代码,出于某种原因它缺少 while 循环逻辑“while(i....)”,虽然我找到了 PigLatin* 问题的其他可行解决方案,但我真的很想了解这个正在工作。 *PigLati
我工作了一整天来运行 Xampp 并在其上安装 TYPO3。现在我登录到后端,但没有显示许多管理模块,例如模板、访问等。 - 一定是我做错了什么,但我不知道。 these are the module
你好 我有编译这个问题 \begin{equation} J = \sum_{j=1}^{C} \end{equation} 我不断收到错误 missing $ inserted 这很奇怪,因
我正在尝试使用 SQLite CLI,但无法获得 generate_series功能来工作。我可以按照文档中的建议使用递归 CTE 对其进行模拟,但我似乎无法获得该链接中的任何示例。这是我的 sess
我目前正在开发我想要的软件,而软件正在安装,它可以在后台为软件创建 native 图像。 我正在考虑使用 NGEN 并将进程优先级设置为低,因为我不希望它消耗 100% CPU。但是我发现我的计算机上
我想使用 Xcodes Instruments 进行 UI 自动化测试。但似乎缺少“自动化”。我怎样才能添加这个? 最佳答案 如果您想使用自动化仪器,请使用 Xcode 7.3。 Apple 在 Xc
我目前在 JS 开发中迈出了一小步,并编写了以下链接添加器: const button = document.getElementById('button') const listdiv = docu
此代码有什么问题: NSError *error = nil; [SFHFKeychainUtils deleteItemForUsername:@"IAPNoob01" andServiceName
出于某种原因,在安装和配置(我认为)一切之后,com.adobe.utils.AGALMiniAssembler 不见了,其他一切正常。 我认为我已尽一切努力让孵化器正常工作,但显然我错过了一步。 如
我有一个名为 new 的方法。调用 new 时,我传递了一个参数,但是当我运行应用程序时,出现没有参数或参数为空的错误。 StepReader.pm package StepReader; use s
安装 gtk 1.2(包名 gtk1)和 macports chokes 在最终的 make 中,在 libintl.h 的第 440 行。 extern locale_t libintl_newlo
我用按钮创建表格。 这是javascript代码: function layersListTable(layers) { var content =''; $.each($(layer
我在使用此 javascript 时遇到此错误,任何人都可以帮我弄清楚我做错了什么吗? $(this).prepend('Check availability »'); 它给我错误 mis
我有一个独立的工具链 NDK13b、api19、llvm 3.8 编译器、arm 32 位、带有 libcpp(llvm C++ 库) 我想避免依赖 libgcc,所以我构建了 compiler-rt
我按照一些教程使用 phonegap 的条形码扫描器插件。但是当我从现有源创建一个新的 android 项目来创建条码库时 (step 6 in this page)我收到错误:“AndroidMan
我现在尝试在 Eclipse 中打开我的布局 xml 文件。我只得到错误 No XML content. Please add a root view or layout to your docume
我的 android-sdk-windows\tools 目录中缺少层次结构查看器工具。 工具链接: http://developer.android.com/guide/developing/too
我是一名优秀的程序员,十分优秀!