From f3b6955533c875631f835fd08247f6290080687f Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 9 Dec 2015 11:53:57 +0000 Subject: [PATCH] transform expressions - split grammar into *.hpp *_def.hpp and *.cpp --- include/mapnik/expression_grammar_x3.hpp | 2 +- include/mapnik/expression_grammar_x3_def.hpp | 10 +- .../transform_expression_grammar_x3.hpp | 51 +++++++ .../transform_expression_grammar_x3_def.hpp | 131 ++++++++++-------- src/build.py | 1 + src/parse_transform.cpp | 21 ++- src/transform_expression_grammar_x3.cpp | 30 ++++ 7 files changed, 176 insertions(+), 70 deletions(-) create mode 100644 include/mapnik/transform_expression_grammar_x3.hpp create mode 100644 src/transform_expression_grammar_x3.cpp diff --git a/include/mapnik/expression_grammar_x3.hpp b/include/mapnik/expression_grammar_x3.hpp index c9fa0363a..d25692c4e 100644 --- a/include/mapnik/expression_grammar_x3.hpp +++ b/include/mapnik/expression_grammar_x3.hpp @@ -49,7 +49,7 @@ BOOST_SPIRIT_DECLARE(expression_grammar_type); namespace mapnik { - grammar::expression_grammar_type expression_grammar(); +grammar::expression_grammar_type expression_grammar(); } diff --git a/include/mapnik/expression_grammar_x3_def.hpp b/include/mapnik/expression_grammar_x3_def.hpp index 8894d4154..285786379 100644 --- a/include/mapnik/expression_grammar_x3_def.hpp +++ b/include/mapnik/expression_grammar_x3_def.hpp @@ -304,7 +304,7 @@ namespace mapnik { namespace grammar { auto const ustring = x3::rule {} = no_skip[alpha > *alnum]; // start - auto const expression_def = logical_expression; + auto const expression_def = logical_expression; auto const logical_expression_def = conditional_expression[do_assign] > *(((lit("and") | lit("&&")) > conditional_expression[do_and]) @@ -416,10 +416,10 @@ namespace mapnik { namespace grammar { namespace mapnik { - grammar::expression_grammar_type expression_grammar() - { - return grammar::expression; - } +grammar::expression_grammar_type expression_grammar() +{ + return grammar::expression; +} } #endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/transform_expression_grammar_x3.hpp b/include/mapnik/transform_expression_grammar_x3.hpp new file mode 100644 index 000000000..ccf480c22 --- /dev/null +++ b/include/mapnik/transform_expression_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * 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_TRANSFORM_GRAMMAR_X3_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace grammar { + +struct transform_expression_class; // top-most ID +using transform_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(transform_expression_grammar_type); + +}} // ns + +namespace mapnik +{ +grammar::transform_expression_grammar_type transform_expression_grammar(); +} + +#endif diff --git a/include/mapnik/transform_expression_grammar_x3_def.hpp b/include/mapnik/transform_expression_grammar_x3_def.hpp index 25d72bbaa..88e055fe6 100644 --- a/include/mapnik/transform_expression_grammar_x3_def.hpp +++ b/include/mapnik/transform_expression_grammar_x3_def.hpp @@ -24,6 +24,7 @@ #define MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP #include +#include #include #pragma GCC diagnostic push @@ -67,78 +68,92 @@ BOOST_FUSION_ADAPT_STRUCT(mapnik::skewY_node, namespace mapnik { namespace grammar { -namespace x3 = boost::spirit::x3; -namespace ascii = boost::spirit::x3::ascii; + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; -// [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] + // [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] -// The value of the ‘transform’ attribute is a , which -// is defined as a list of transform definitions, which are applied in -// the order provided. The individual transform definitions are -// separated by whitespace and/or a comma. + // The value of the ‘transform’ attribute is a , which + // is defined as a list of transform definitions, which are applied in + // the order provided. The individual transform definitions are + // separated by whitespace and/or a comma. -using x3::double_; -using x3::no_skip; -using x3::no_case; -using x3::lit; -using x3::char_; + using x3::double_; + using x3::no_skip; + using x3::no_case; + using x3::lit; + using x3::char_; -x3::rule transform_list_rule("transform list"); -x3::rule transform_node_rule("transform node"); -x3::rule matrix("matrix node"); -x3::rule translate("translate node"); -x3::rule scale("scale node"); -x3::rule rotate("rotate node"); -x3::rule skewX("skew X node"); -x3::rule skewY("skew Y node"); + // starting rule + transform_expression_grammar_type const transform("transform"); + // rules + x3::rule transform_list_rule("transform list"); + x3::rule transform_node_rule("transform node"); + x3::rule matrix("matrix node"); + x3::rule translate("translate node"); + x3::rule scale("scale node"); + x3::rule rotate("rotate node"); + x3::rule skewX("skew X node"); + x3::rule skewY("skew Y node"); -// Import the expression rule -namespace { auto const& expr = expression_grammar(); } + // Import the expression rule + namespace { auto const& expr = expression_grammar(); } -auto const transform_list_rule_def = transform_node_rule % no_skip[char_(", ")]; + // start + auto const transform_def = transform_list_rule; -auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; + auto const transform_list_rule_def = transform_node_rule % no_skip[char_(", ")]; -// matrix( ) -auto const matrix_def = no_case[lit("matrix")] - > '(' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ')' - ; + auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; -// translate( []) -auto const translate_def = no_case[lit("translate")] - > '(' > expr > -(',' > expr ) > ')' - ; + // matrix( ) + auto const matrix_def = no_case[lit("matrix")] + > '(' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ')' + ; -// scale( []) -auto const scale_def = no_case[lit("scale")] - > '(' > expr > -(',' > expr ) > ')' - ; + // translate( []) + auto const translate_def = no_case[lit("translate")] + > '(' > expr > -(',' > expr ) > ')' + ; -// rotate( [ ]) -auto const rotate_def = no_case[lit("rotate")] - > '(' > expr > -(',' > expr > ',' > expr) > ')' - ; + // scale( []) + auto const scale_def = no_case[lit("scale")] + > '(' > expr > -(',' > expr ) > ')' + ; -// skewX() -auto const skewX_def = no_case[lit("skewX")] - > '(' > expr > ')'; + // rotate( [ ]) + auto const rotate_def = no_case[lit("rotate")] + > '(' > expr > -(',' > expr > ',' > expr) > ')' + ; -// skewY() -auto const skewY_def = no_case[lit("skewY")] - > '(' > expr > ')'; + // skewX() + auto const skewX_def = no_case[lit("skewX")] + > '(' > expr > ')'; + + // skewY() + auto const skewY_def = no_case[lit("skewY")] + > '(' > expr > ')'; -BOOST_SPIRIT_DEFINE ( - transform_list_rule, - transform_node_rule, - matrix, - translate, - scale, - rotate, - skewX, - skewY - ); + BOOST_SPIRIT_DEFINE ( + transform, + transform_list_rule, + transform_node_rule, + matrix, + translate, + scale, + rotate, + skewX, + skewY); -}} // +}} // ns -#endif // ns +namespace mapnik +{ +grammar::transform_expression_grammar_type transform_expression_grammar() +{ + return grammar::transform; +} +} + +#endif diff --git a/src/build.py b/src/build.py index 1aa7418f3..75bef48bf 100644 --- a/src/build.py +++ b/src/build.py @@ -169,6 +169,7 @@ source = Split( expression_string.cpp expression.cpp transform_expression.cpp + transform_expression_grammar_x3.cpp feature_kv_iterator.cpp feature_style_processor.cpp feature_type_style.cpp diff --git a/src/parse_transform.cpp b/src/parse_transform.cpp index 1a74d60c2..06b189f35 100644 --- a/src/parse_transform.cpp +++ b/src/parse_transform.cpp @@ -21,8 +21,9 @@ *****************************************************************************/ #include -#include - +#include +#include // transcoder_tag +#include // stl #include #include @@ -38,11 +39,19 @@ transform_list_ptr parse_transform(std::string const& str, std::string const& en mapnik::transcoder const tr(encoding); auto const parser = boost::spirit::x3::with(std::ref(tr)) [ - mapnik::grammar::transform_list_rule + mapnik::transform_expression_grammar() ]; - // FIXME : try/catch! - bool r = boost::spirit::x3::phrase_parse(itr, end, parser, space, *trans_list); - if (r && itr == end) + bool status = false; + try + { + status = boost::spirit::x3::phrase_parse(itr, end, parser, space, *trans_list); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw config_error("Failed to parse transform expression: \"" + str + "\""); + } + + if (status && itr == end) { return trans_list; } diff --git a/src/transform_expression_grammar_x3.cpp b/src/transform_expression_grammar_x3.cpp new file mode 100644 index 000000000..ab3d6a77b --- /dev/null +++ b/src/transform_expression_grammar_x3.cpp @@ -0,0 +1,30 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#include +#include + +namespace mapnik { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(transform_expression_grammar_type, iterator_type, context_type); + +}}