GeoJSON feature/geometry grammars - split (a | b | ...) % lit(',') rule to avoid creating bogus temp synthesised attribute e.g boost::variant<a,b,..> which causes clang compiler >= 3.9 to segfault. (ref #3507)

NOTE: In general many Boost.Spirit gotchas can be fixed by simplifying rules (better control what gets synthesied under the bonet)
This commit is contained in:
artemp 2016-09-22 12:18:34 +02:00
parent 34e1096788
commit 03f1e49818
4 changed files with 28 additions and 16 deletions

View file

@ -72,7 +72,8 @@ struct feature_grammar : qi::grammar<Iterator, void(FeatureType&), space_type>
generic_json<Iterator> json_;
// geoJSON
qi::rule<Iterator, void(FeatureType&),space_type> start;
qi::rule<Iterator, qi::locals<bool>, void(FeatureType&),space_type> feature;
qi::rule<Iterator, qi::locals<bool>, void(FeatureType&), space_type> feature;
qi::rule<Iterator, void(FeatureType&, bool&), space_type> feature_part;
qi::rule<Iterator, space_type> feature_type;
qi::rule<Iterator,void(FeatureType &),space_type> properties;
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes;

View file

@ -41,6 +41,7 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
qi::_4_type _4;
qi::_a_type _a;
qi::_r1_type _r1;
qi::_r2_type _r2;
qi::eps_type eps;
qi::char_type char_;
using qi::fail;
@ -55,16 +56,19 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
start = feature(_r1);
feature = eps[_a = false] > lit('{') >
(feature_type[_a = true]
|
(lit("\"geometry\"") > lit(':') > geometry_grammar_[set_geometry(_r1, _1)])
|
properties(_r1)
|
json_.key_value) % lit(',')
feature_part(_r1, _a) % lit(',')
> eps(_a) > lit('}')
;
feature_part = feature_type[_r2 = true]
|
(lit("\"geometry\"") > lit(':') > geometry_grammar_[set_geometry(_r1, _1)])
|
properties(_r1)
|
json_.key_value
;
properties = lit("\"properties\"")
> lit(':') > ((lit('{') > -attributes(_r1) > lit('}')) | lit("null"))
;

View file

@ -49,6 +49,7 @@ struct geometry_grammar :
geometry_grammar();
qi::rule<Iterator, mapnik::geometry::geometry<double>(), space_type> start;
qi::rule<Iterator, qi::locals<int, mapnik::json::coordinates>, mapnik::geometry::geometry<double>(), space_type> geometry;
qi::rule<Iterator, void(int&, mapnik::json::coordinates&, mapnik::geometry::geometry<double>&), space_type> geometry_part;
qi::rule<Iterator, mapnik::geometry::geometry_collection<double>(), space_type> geometry_collection;
qi::symbols<char, int> geometry_type_dispatch;
positions_grammar<Iterator> coordinates;

View file

@ -46,21 +46,27 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
qi::_4_type _4;
qi::_a_type _a;
qi::_b_type _b;
qi::_r1_type _r1;
qi::_r2_type _r2;
qi::_r3_type _r3;
qi::eps_type eps;
using qi::fail;
using qi::on_error;
using phoenix::push_back;
start = geometry.alias() | lit("null");
geometry = lit('{')[_a = 0]
> (((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1])
|
(lit("\"coordinates\"") > lit(':') > coordinates[_b = _1])
|
(lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[_val = _1] > lit(']'))
|
json_.key_value) % lit(',')) [create_geometry(_val,_a,_b)]
> lit('}')
> (geometry_part(_a, _b, _val) % lit(','))[create_geometry(_val, _a, _b)]
> lit('}');
geometry_part = ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_r1 = _1])
|
(lit("\"coordinates\"") > lit(':') > coordinates[_r2 = _1])
|
(lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[_r3 = _1] > lit(']'))
|
json_.key_value)
;
geometry_collection = geometry[push_back(_val, _1)] % lit(',')