diff --git a/include/mapnik/json/generic_json_grammar_x3.hpp b/include/mapnik/json/generic_json_grammar_x3.hpp new file mode 100644 index 000000000..4d633cf9e --- /dev/null +++ b/include/mapnik/json/generic_json_grammar_x3.hpp @@ -0,0 +1,82 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2015 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP +#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP + +#include +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +#include + +namespace mapnik { namespace json { + +namespace x3 = boost::spirit::x3; + +struct json_value; + +using json_array = std::vector; +using json_object_element = std::pair; +using json_object = std::vector; +using json_value_base = mapnik::util::variant; +struct json_value : json_value_base +{ +#if __cpp_inheriting_constructors >= 200802 + + using json_value_base::json_value_base; + +#else + + json_value() = default; + + template + json_value(T && val) + : json_value_base(std::forward(val)) {} + +#endif +}; + +namespace grammar { + +using generic_json_grammar_type = x3::rule; +using generic_json_key_value_type = x3::rule; +BOOST_SPIRIT_DECLARE(generic_json_grammar_type); +BOOST_SPIRIT_DECLARE(generic_json_key_value_type); +} + +grammar::generic_json_grammar_type const& generic_json_grammar(); +grammar::generic_json_key_value_type const& generic_json_key_value(); + +}} + +#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/generic_json_grammar_x3_def.hpp b/include/mapnik/json/generic_json_grammar_x3_def.hpp new file mode 100644 index 000000000..390c2251e --- /dev/null +++ b/include/mapnik/json/generic_json_grammar_x3_def.hpp @@ -0,0 +1,133 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +auto make_null = [] (auto const& ctx) +{ + _val(ctx) = mapnik::value_null{}; +}; + +auto make_true = [] (auto const& ctx) +{ + _val(ctx) = true; +}; + +auto make_false = [] (auto const& ctx) +{ + _val(ctx) = false; +}; + +auto assign = [](auto const& ctx) +{ + _val(ctx) = _attr(ctx); +}; + +auto assign_key = [](auto const& ctx) +{ + std::get<0>(_val(ctx)) = _attr(ctx); +}; + +auto assign_value = [](auto const& ctx) +{ + std::get<1>(_val(ctx)) = _attr(ctx); +}; + + +using x3::lit; +using x3::string; +// exported rules +// start +generic_json_grammar_type const value("JSON Value"); +generic_json_key_value_type const key_value("JSON Object element"); +// rules +x3::rule object("JSON Object"); +x3::rule array("JSON Array"); +x3::rule number("JSON Number"); + +auto const json_double = x3::real_parser>(); +auto const json_integer = x3::int_parser(); + +// import unicode string rule +namespace { auto const& json_string = mapnik::json::unicode_string_grammar(); } + // generic json types +auto const value_def = object | array | json_string | number + ; + +auto const key_value_def = json_string[assign_key] > lit(':') > value[assign_value] + ; + +auto const object_def = lit('{') + > -(key_value % lit(',')) + > lit('}') + ; + +auto const array_def = lit('[') + > -(value % lit(',')) + > lit(']') + ; + +auto const number_def = json_double[assign] + | json_integer[assign] + | lit("true") [make_true] + | lit ("false") [make_false] + | lit("null")[make_null] + ; + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + value, + object, + key_value, + array, + number + ); + +#pragma GCC diagnostic pop + +}}} + +namespace mapnik { namespace json { + +grammar::generic_json_grammar_type const& generic_json_grammar() +{ + return grammar::value; +} +grammar::generic_json_key_value_type const& generic_json_key_value() +{ + return grammar::key_value; +} + +}} + +#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP