transform expressions - split grammar into *.hpp *_def.hpp and *.cpp

This commit is contained in:
artemp 2015-12-09 11:53:57 +00:00
parent b7a54e5166
commit f3b6955533
7 changed files with 176 additions and 70 deletions

View file

@ -49,7 +49,7 @@ BOOST_SPIRIT_DECLARE(expression_grammar_type);
namespace mapnik
{
grammar::expression_grammar_type expression_grammar();
grammar::expression_grammar_type expression_grammar();
}

View file

@ -304,7 +304,7 @@ namespace mapnik { namespace grammar {
auto const ustring = x3::rule<class ustring, std::string> {} = 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

View file

@ -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 <mapnik/transform_expression.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp>
#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<transform_expression_class, mapnik::transform_list>;
BOOST_SPIRIT_DECLARE(transform_expression_grammar_type);
}} // ns
namespace mapnik
{
grammar::transform_expression_grammar_type transform_expression_grammar();
}
#endif

View file

@ -24,6 +24,7 @@
#define MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP
#include <mapnik/transform_expression.hpp>
#include <mapnik/transform_expression_grammar_x3.hpp>
#include <mapnik/expression_grammar_x3.hpp>
#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 <transform-list>, 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 <transform-list>, 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<class transform_list_class, mapnik::transform_list> transform_list_rule("transform list");
x3::rule<class transform_node_class, mapnik::transform_node> transform_node_rule("transform node");
x3::rule<class matrix_node_class, mapnik::matrix_node> matrix("matrix node");
x3::rule<class translate_node_class, mapnik::translate_node> translate("translate node");
x3::rule<class scale_node_class, mapnik::scale_node> scale("scale node");
x3::rule<class rotate_node_class, mapnik::rotate_node> rotate("rotate node");
x3::rule<class skewX_node_class, mapnik::skewX_node> skewX("skew X node");
x3::rule<class skewY_node_class, mapnik::skewY_node> skewY("skew Y node");
// starting rule
transform_expression_grammar_type const transform("transform");
// rules
x3::rule<class transform_list_class, mapnik::transform_list> transform_list_rule("transform list");
x3::rule<class transform_node_class, mapnik::transform_node> transform_node_rule("transform node");
x3::rule<class matrix_node_class, mapnik::matrix_node> matrix("matrix node");
x3::rule<class translate_node_class, mapnik::translate_node> translate("translate node");
x3::rule<class scale_node_class, mapnik::scale_node> scale("scale node");
x3::rule<class rotate_node_class, mapnik::rotate_node> rotate("rotate node");
x3::rule<class skewX_node_class, mapnik::skewX_node> skewX("skew X node");
x3::rule<class skewY_node_class, mapnik::skewY_node> 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(<a> <b> <c> <d> <e> <f>)
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(<tx> [<ty>])
auto const translate_def = no_case[lit("translate")]
> '(' > expr > -(',' > expr ) > ')'
;
// matrix(<a> <b> <c> <d> <e> <f>)
auto const matrix_def = no_case[lit("matrix")]
> '(' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ')'
;
// scale(<sx> [<sy>])
auto const scale_def = no_case[lit("scale")]
> '(' > expr > -(',' > expr ) > ')'
;
// translate(<tx> [<ty>])
auto const translate_def = no_case[lit("translate")]
> '(' > expr > -(',' > expr ) > ')'
;
// rotate(<rotate-angle> [<cx> <cy>])
auto const rotate_def = no_case[lit("rotate")]
> '(' > expr > -(',' > expr > ',' > expr) > ')'
;
// scale(<sx> [<sy>])
auto const scale_def = no_case[lit("scale")]
> '(' > expr > -(',' > expr ) > ')'
;
// skewX(<skew-angle>)
auto const skewX_def = no_case[lit("skewX")]
> '(' > expr > ')';
// rotate(<rotate-angle> [<cx> <cy>])
auto const rotate_def = no_case[lit("rotate")]
> '(' > expr > -(',' > expr > ',' > expr) > ')'
;
// skewY(<skew-angle>)
auto const skewY_def = no_case[lit("skewY")]
> '(' > expr > ')';
// skewX(<skew-angle>)
auto const skewX_def = no_case[lit("skewX")]
> '(' > expr > ')';
// skewY(<skew-angle>)
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

View file

@ -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

View file

@ -21,8 +21,9 @@
*****************************************************************************/
#include <mapnik/parse_transform.hpp>
#include <mapnik/transform_expression_grammar_x3_def.hpp>
#include <mapnik/transform_expression_grammar_x3.hpp>
#include <mapnik/expression_grammar_x3_config.hpp> // transcoder_tag
#include <mapnik/config_error.hpp>
// stl
#include <string>
#include <stdexcept>
@ -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<mapnik::grammar::transcoder_tag>(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<std::string::const_iterator> const& ex)
{
throw config_error("Failed to parse transform expression: \"" + str + "\"");
}
if (status && itr == end)
{
return trans_list;
}

View file

@ -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 <mapnik/transform_expression_grammar_x3_def.hpp>
#include <mapnik/expression_grammar_x3_config.hpp>
namespace mapnik { namespace grammar {
BOOST_SPIRIT_INSTANTIATE(transform_expression_grammar_type, iterator_type, context_type);
}}