Я свел свою проблему к (возможно, не самому маленькому) примеру приложения ниже. Образец представляет собой универсальный синтаксический анализатор JSON. Тем не менее, он демонстрирует две проблемы. 1. Когда ни одна из других опций не проходит, она всегда выводит true или false, если bool_ является устройством вывода в списке вариантов. Если это не последний, все, что после него, фактически не используется. Я не могу понять, почему. 2. Когда вход представляет собой строку, обработчик строки никогда не запускается из варианта. При использовании вне варианта срабатывает.
Код примера имеет строковый вывод, упрощенный до просто karma::string, и по-прежнему показывает ошибку. Когда я возьму то, что узнал здесь, и вернусь к реальному приложению, вывод строки будет экранированной строкой в стиле C, поэтому что-то, что работает только с karma::string, не поможет.
Я уже прочитал (и перечитал) Вывод типа boost::variant с использованием boost ::spirit::karma и boost::spirit::karma вывод строки в кавычках и либо не может правильно применить ее к моему случаю (т.е. я все-таки не понимаю ответа), либо не работает в более сложном примере. И я также знаком с примером кода mini_xml.
Любые предложения о том, что я делаю неправильно? И почему то, что я делаю, неправильно, а исправление правильно?
Вся помощь действительно ценится.
#include <boost/variant/recursive_variant.hpp>
#include <string>
#include <vector>
namespace lloyd
{
namespace json
{
struct null
{
bool operator==(const null& cmp) {return true; }
};
struct element;
typedef boost::make_recursive_variant<null, bool, long, double, std::string, std::vector<element>, std::vector<boost::recursive_variant_> >::type value;
struct element
{
std::string name;
json::value value;
inline element(const element& src): name(src.name), value(src.value) {}
inline element(const std::string& name, const json::value& value): name(name), value(value) {}
inline element() {}
};
typedef std::vector<element> object;
}
}
#include <boost/fusion/adapted.hpp>
BOOST_FUSION_ADAPT_STRUCT(
lloyd::json::element,
(std::string, name)
(lloyd::json::value, value)
)
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/karma_auto.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace lloyd { namespace json { namespace karma {
template <typename OutputIterator>
struct json_object_out_generator
: boost::spirit::karma::grammar<OutputIterator, json::object(bool, unsigned, unsigned) >
{
// JSON Output Grammars
boost::spirit::karma::rule<OutputIterator, std::vector<json::value>(bool, unsigned, unsigned) > array_rule;
boost::spirit::karma::rule<OutputIterator, json::null(bool, unsigned, unsigned) > null_rule;
boost::spirit::karma::rule<OutputIterator, json::value(bool, unsigned, unsigned) > value_rule;
boost::spirit::karma::rule<OutputIterator, json::element(bool, unsigned, unsigned) > elem_rule;
boost::spirit::karma::rule<OutputIterator, json::object(bool, unsigned, unsigned) > obj_rule;
json_object_out_generator() : json_object_out_generator::base_type(obj_rule)
{
using boost::spirit::lit;
using boost::spirit::_r1;
using boost::spirit::_r2;
using boost::spirit::_r3;
namespace karma=boost::spirit::karma;
null_rule %= karma::eps << boost::spirit::karma::lit("null");
array_rule %= lit("[") << -(value_rule(_r1, _r2, _r3) % lit(",") ) << "]";
value_rule %= ( null_rule(_r1, _r2, _r3) | karma::string | karma::long_ | karma::double_ | obj_rule(_r1, _r2, _r3) | array_rule(_r1, _r2, _r3) | karma::bool_);
elem_rule %= boost::spirit::karma::string << ":" << -value_rule(_r1, _r2+1, _r3);
obj_rule %= boost::spirit::lit("{")
<< -boost::spirit::buffer[( elem_rule(_r1, _r2+1, _r3) % ',' ) ]
<< "}";
}
};
}}}
#include <vector>
#include <sstream>
#include <iomanip>
#include <boost/assign/list_of.hpp>
#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
int main(int argc, const char* argv[])
{
using lloyd::json::value;
using lloyd::json::element;
using lloyd::json::null;
lloyd::json::object obj;
lloyd::json::object sobj;
std::vector<value> t5;
t5 += null(), true, false, value("Testing"), sobj;
obj += element("T1", null()), element("T2", true), element("T3", false);
obj += element("T4", "Testing 4"), element("T5", t5), element("T6", sobj);
obj += element("NT0", (long)50), element("NT1", 50.5), element("NT2", 50.0);
std::stringstream s;
typedef boost::spirit::karma::ostream_iterator<char> out_itr;
out_itr so(s);
lloyd::json::karma::json_object_out_generator<out_itr> json_object_out; // Our grammar definition
boost::spirit::karma::generate(so, json_object_out(true, 0, 1), obj);
std::cout << "Result:\n";
std::cout << s.str() << std::endl;
return 0;
}
Отредактировано, чтобы изменить заголовок, чтобы охватить фактическую отображаемую проблему. Отредактировано, чтобы исправить промах загрузки в примере кода.
<spirit_json/karma_json_char.hpp>
? Это часть какой-то сторонней библиотеки? - person Igor R.   schedule 15.08.2013#define BOOST_SPIRIT_USE_PHOENIX_V3
). - person llonesmiz   schedule 15.08.2013