path_expression_grammer - implement parser using boost::spirit::x3
This commit is contained in:
parent
b4dda3c180
commit
ca88e55264
6 changed files with 91 additions and 101 deletions
|
@ -27,11 +27,6 @@
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/home/x3.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik { namespace grammar {
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
namespace x3 = boost::spirit::x3;
|
namespace x3 = boost::spirit::x3;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Artem Pavlenko
|
* Copyright (C) 2016 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -420,7 +420,7 @@ namespace mapnik { namespace grammar {
|
||||||
primary_expression
|
primary_expression
|
||||||
);
|
);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/path_expression_grammar.hpp>
|
|
||||||
#include <mapnik/attribute.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_core.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_object.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
path_expression_grammar<Iterator>::path_expression_grammar()
|
|
||||||
: path_expression_grammar::base_type(expr)
|
|
||||||
{
|
|
||||||
standard_wide::char_type char_;
|
|
||||||
qi::_1_type _1;
|
|
||||||
qi::_val_type _val;
|
|
||||||
qi::lit_type lit;
|
|
||||||
qi::lexeme_type lexeme;
|
|
||||||
using phoenix::push_back;
|
|
||||||
using boost::phoenix::construct;
|
|
||||||
|
|
||||||
expr =
|
|
||||||
* (
|
|
||||||
str [ push_back(_val, _1)]
|
|
||||||
|
|
|
||||||
( '[' >> attr [ push_back(_val, construct<mapnik::attribute>( _1 )) ] >> ']')
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
attr %= +(char_ - ']');
|
|
||||||
str %= lexeme[+(char_ -'[')];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Artem Pavlenko
|
* Copyright (C) 2016 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -20,40 +20,25 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP
|
||||||
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/path_expression.hpp>
|
#include <mapnik/path_expression.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// stl
|
namespace mapnik { namespace grammar {
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace mapnik
|
namespace x3 = boost::spirit::x3;
|
||||||
{
|
struct path_expression_class; // top-most ID
|
||||||
|
using path_expression_grammar_type = x3::rule<path_expression_class, path_expression>;
|
||||||
|
|
||||||
using namespace boost;
|
BOOST_SPIRIT_DECLARE(path_expression_grammar_type);
|
||||||
namespace qi = boost::spirit::qi;
|
|
||||||
namespace phoenix = boost::phoenix;
|
|
||||||
namespace standard_wide = boost::spirit::standard_wide;
|
|
||||||
|
|
||||||
using standard_wide::space_type;
|
}}
|
||||||
|
|
||||||
template <typename Iterator>
|
#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP
|
||||||
struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_component>(), space_type>
|
|
||||||
{
|
|
||||||
path_expression_grammar();
|
|
||||||
qi::rule<Iterator, std::vector<path_component>() , space_type> expr;
|
|
||||||
qi::rule<Iterator, std::string() , space_type> attr;
|
|
||||||
qi::rule<Iterator, std::string() > str;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
|
63
include/mapnik/path_expression_grammar_x3_def.hpp
Normal file
63
include/mapnik/path_expression_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP
|
||||||
|
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/path_expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/attribute.hpp>
|
||||||
|
|
||||||
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
|
namespace x3 = boost::spirit::x3;
|
||||||
|
using x3::standard_wide::char_;
|
||||||
|
using x3::lexeme;
|
||||||
|
auto create_string = [](auto & ctx) { _val(ctx).push_back(_attr(ctx)); };
|
||||||
|
auto create_attribute = [](auto & ctx) { _val(ctx).push_back(mapnik::attribute(_attr(ctx))); };
|
||||||
|
// top-most rule
|
||||||
|
path_expression_grammar_type const path_expression("path_expression");
|
||||||
|
// rules
|
||||||
|
x3::rule<class attr_expression, std::string> const attr_expression("attribute");
|
||||||
|
x3::rule<class str_expression, std::string> const str_expression("string");
|
||||||
|
|
||||||
|
auto const attr_expression_def = +(char_ - ']');
|
||||||
|
auto const str_expression_def = lexeme[+(char_ -'[')];
|
||||||
|
auto const path_expression_def = *(str_expression[create_string] | '[' > attr_expression[create_attribute] > ']');
|
||||||
|
|
||||||
|
BOOST_SPIRIT_DEFINE(
|
||||||
|
path_expression,
|
||||||
|
attr_expression,
|
||||||
|
str_expression
|
||||||
|
);
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
grammar::path_expression_grammar_type path_expression_grammar()
|
||||||
|
{
|
||||||
|
return grammar::path_expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP
|
|
@ -21,26 +21,35 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/path_expression_grammar.hpp>
|
|
||||||
#include <mapnik/path_expression_grammar_impl.hpp>
|
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/attribute.hpp>
|
#include <mapnik/attribute.hpp>
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/value.hpp>
|
#include <mapnik/value.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/path_expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar_x3_def.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
|
namespace x3 = boost::spirit::x3;
|
||||||
|
using iterator_type = std::string::const_iterator;
|
||||||
|
using context_type = x3::phrase_parse_context<x3::standard_wide::space_type>::type;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_INSTANTIATE(path_expression_grammar_type, iterator_type, context_type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
path_expression_ptr parse_path(std::string const& str)
|
path_expression_ptr parse_path(std::string const& str)
|
||||||
{
|
{
|
||||||
static const path_expression_grammar<std::string::const_iterator> g;
|
namespace x3 = boost::spirit::x3;
|
||||||
auto path = std::make_shared<path_expression>();
|
auto path = std::make_shared<path_expression>();
|
||||||
boost::spirit::standard_wide::space_type space;
|
using boost::spirit::x3::standard_wide::space;
|
||||||
std::string::const_iterator itr = str.begin();
|
std::string::const_iterator itr = str.begin();
|
||||||
std::string::const_iterator end = str.end();
|
std::string::const_iterator end = str.end();
|
||||||
bool r = qi::phrase_parse(itr, end, g, space, *path);
|
bool r = x3::phrase_parse(itr, end, path_expression_grammar(), space, *path);
|
||||||
if (r && itr == end)
|
if (r && itr == end)
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
|
|
Loading…
Add table
Reference in a new issue