css-parser-grammar: parse values into iterator_range via boost::spirit::x3::raw directive (no conversions) + cleanup

This commit is contained in:
Artem Pavlenko 2020-02-06 11:23:02 +00:00
parent 0d693b151d
commit 8d73767949
5 changed files with 12 additions and 39 deletions

View file

@ -25,8 +25,6 @@
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <mapnik/color.hpp>
#include <mapnik/util/variant.hpp>
#pragma GCC diagnostic push #pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp> #include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp> #include <boost/spirit/home/x3.hpp>
@ -34,7 +32,7 @@
namespace mapnik namespace mapnik
{ {
using property_value_type = mapnik::util::variant<double, mapnik::color, std::string>; using property_value_type = boost::iterator_range<char const*>;
using css_key_value = std::pair<std::string, property_value_type>; using css_key_value = std::pair<std::string, property_value_type>;
using definition_type = std::vector<css_key_value>; using definition_type = std::vector<css_key_value>;
using css_data = std::unordered_multimap<std::string, definition_type>; using css_data = std::unordered_multimap<std::string, definition_type>;
@ -72,4 +70,4 @@ css_grammar::css_grammar_type const grammar();
css_grammar::css_skipper_type const skipper(); css_grammar::css_skipper_type const skipper();
} }
#endif // MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP #endif // MAPNIK_CSS_GRAMMAR_X3_HPP

View file

@ -25,8 +25,6 @@
#define MAPNIK_CSS_GRAMMAR_X3_DEF_HPP #define MAPNIK_CSS_GRAMMAR_X3_DEF_HPP
#include <mapnik/css/css_grammar_x3.hpp> #include <mapnik/css/css_grammar_x3.hpp>
#include <mapnik/css/css_unit_value.hpp>
#include <mapnik/css/css_color_grammar_x3.hpp>
#include <mapnik/json/unicode_string_grammar_x3.hpp> #include <mapnik/json/unicode_string_grammar_x3.hpp>
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -150,24 +148,18 @@ namespace x3 = boost::spirit::x3;
namespace css_grammar { namespace css_grammar {
using x3::lit; using x3::lit;
using x3::int_;
using x3::uint_parser;
using x3::hex;
using x3::symbols;
using x3::omit;
using x3::attr; using x3::attr;
using x3::double_;
using x3::no_case; using x3::no_case;
using x3::no_skip; using x3::no_skip;
using x3::lexeme; using x3::lexeme;
using x3::alpha; using x3::alpha;
using x3::alnum; using x3::alnum;
using x3::char_; using x3::char_;
using x3::raw;
using x3::standard::space; using x3::standard::space;
// import unicode string rule // import unicode string rule
namespace { auto const& css_string = mapnik::json::grammar::unicode_string; } namespace { auto const& css_string = mapnik::json::grammar::unicode_string; }
namespace { auto const& css_color = mapnik::css_color_grammar::css_color; }
auto assign_def = [] (auto const& ctx) auto assign_def = [] (auto const& ctx)
{ {
@ -183,16 +175,11 @@ auto assign_key = [] (auto const& ctx)
}; };
auto assign_value = [] (auto const& ctx) {_val(ctx).second = std::move(_attr(ctx));}; auto assign_value = [] (auto const& ctx) {_val(ctx).second = std::move(_attr(ctx));};
auto apply_value = [](auto const& ctx) { _val(ctx) = _attr(ctx); };
auto apply_units = [](auto const& ctx) { _val(ctx) *= _attr(ctx);};
// units
const mapnik::css_unit_value unit_value;
// rules // rules
x3::rule<class simple_selector_tag, std::string> const simple_selector {"Simple selector"}; x3::rule<class simple_selector_tag, std::string> const simple_selector {"Simple selector"};
x3::rule<class selector_tag, std::vector<std::string>> const selector {"Selector"}; x3::rule<class selector_tag, std::vector<std::string>> const selector {"Selector"};
x3::rule<class number_tag, double> const number{"number"}; x3::rule<class value_tag, property_value_type> const value {"Value"};
x3::rule<class value_tag, property_value_type> const value {"value"};
x3::rule<class key_value_tag, css_key_value> const key_value {"CSS Key/Value"}; x3::rule<class key_value_tag, css_key_value> const key_value {"CSS Key/Value"};
x3::rule<class definition_tag, std::pair<std::vector<std::string>, definition_type>> const definition {"CSS Definition"}; x3::rule<class definition_tag, std::pair<std::vector<std::string>, definition_type>> const definition {"CSS Definition"};
@ -202,8 +189,7 @@ auto const simple_selector_def = lexeme[ident >> -((char_('.') | char_('#') | ch
| lexeme[char_('.') >> ident >> -(char_(':') >> ident)]; | lexeme[char_('.') >> ident >> -(char_(':') >> ident)];
auto const selector_def = simple_selector % lit(','); auto const selector_def = simple_selector % lit(',');
auto const number_def = lexeme[double_[apply_value] > -unit_value[apply_units]]; auto const value_def = raw[lexeme[+~char_(";}")]];
auto const value_def = number | css_color | lexeme[+~char_(";}")];
auto const key_value_def = lexeme[ident][assign_key] >> lit(':') >> value[assign_value] >> -lit(';'); auto const key_value_def = lexeme[ident][assign_key] >> lit(':') >> value[assign_value] >> -lit(';');
auto const definition_def = selector >> lit('{') >> *key_value >> lit('}'); auto const definition_def = selector >> lit('{') >> *key_value >> lit('}');
@ -219,7 +205,6 @@ BOOST_SPIRIT_DEFINE(
css_classes, css_classes,
simple_selector, simple_selector,
selector, selector,
number,
value, value,
key_value, key_value,
definition, definition,

View file

@ -20,7 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
#include <mapnik/css/css_grammar_x3.hpp>
#include <mapnik/css/css_color_grammar_x3_def.hpp> #include <mapnik/css/css_color_grammar_x3_def.hpp>
#if BOOST_VERSION < 107000 #if BOOST_VERSION < 107000
#include <mapnik/image_filter_types.hpp> #include <mapnik/image_filter_types.hpp>
@ -29,13 +28,9 @@ namespace mapnik { namespace css_color_grammar {
namespace x3 = boost::spirit::x3; namespace x3 = boost::spirit::x3;
using iterator_type = std::string::const_iterator; using iterator_type = std::string::const_iterator;
using iterator_css_type = char const*;
using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type; using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
using context_css_type = x3::phrase_parse_context<css_grammar::css_skipper_type>::type;
BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type); BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type);
BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_css_type, context_css_type);
#if BOOST_VERSION < 107000 #if BOOST_VERSION < 107000
template bool parse_rule<iterator_type, context_type, mapnik::filter::color_to_alpha> template bool parse_rule<iterator_type, context_type, mapnik::filter::color_to_alpha>

View file

@ -21,7 +21,6 @@
*****************************************************************************/ *****************************************************************************/
#include <mapnik/css/css_grammar_x3_def.hpp> #include <mapnik/css/css_grammar_x3_def.hpp>
#include <mapnik/css/css_color_grammar_x3.hpp>
namespace mapnik { namespace css_grammar { namespace mapnik { namespace css_grammar {

View file

@ -66,10 +66,9 @@ void print_css(mapnik::css_data & data)
std::cerr << std::get<0>(kv) << " {" << std::endl; std::cerr << std::get<0>(kv) << " {" << std::endl;
for (auto const& def : std::get<1>(kv)) for (auto const& def : std::get<1>(kv))
{ {
std::cerr << " " << std::get<0>(def) << ":"; auto const& r = std::get<1>(def);
mapnik::util::apply_visitor([](auto const& val){ std::cerr << " " << std::get<0>(def) << ":"
std::cerr << val << std::endl; << std::string(r.begin(), r.end());
}, std::get<1>(def));
} }
std::cerr << "}" << std::endl; std::cerr << "}" << std::endl;
} }
@ -464,12 +463,10 @@ void process_css(svg_parser & parser, rapidxml::xml_node<char> const* node)
std::ostringstream ss; std::ostringstream ss;
for (auto const& def : style) for (auto const& def : style)
{ {
std::ostringstream ss; auto const& r = std::get<1>(def);
mapnik::util::apply_visitor([&](auto const& val) { std::string val{r.begin(), r.end()};
ss << val; //std::cerr << "PARSE ATTR:" << std::get<0>(def) << ":" << val << std::endl;
}, std::get<1>(def)); parse_attr(parser, std::get<0>(def).c_str(), val.c_str());
//std::cerr << "PARSE ATTR:" << std::get<0>(def) << ":" << ss.str() << std::endl;
parse_attr(parser, std::get<0>(def).c_str(), ss.str().c_str());
} }
} }
} }
@ -565,7 +562,6 @@ void traverse_tree(svg_parser & parser, rapidxml::xml_node<char> const* node)
auto const skipper = mapnik::skipper(); auto const skipper = mapnik::skipper();
char const* first = child->value(); char const* first = child->value();
char const* last = first + child->value_size(); char const* last = first + child->value_size();
std::vector<std::string> classes;
bool result = boost::spirit::x3::phrase_parse(first, last, grammar, skipper, parser.css_data_); bool result = boost::spirit::x3::phrase_parse(first, last, grammar, skipper, parser.css_data_);
if (result && first == last && !parser.css_data_.empty()) if (result && first == last && !parser.css_data_.empty())
{ {