Adapts all grammars to use expectation parsers without backtracking.
Sequence parsers using `>>` allow for backtracking, expectation parsers `>` do not. This allows us to properly report the position where parsing failed, by catching the expectation_failure exception and adapting the iterator ourselves. References: - https://github.com/Project-OSRM/osrm-backend/pull/2188 - https://github.com/Project-OSRM/osrm-backend/issues/2168 - http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/qi/reference/operator/expect.html
This commit is contained in:
committed by
Patrick Niklaus
parent
def89ac079
commit
8a2bd09fd0
@@ -1,11 +1,13 @@
|
||||
#include "server/api/parameters_parser.hpp"
|
||||
|
||||
#include "server/api/match_parameter_grammar.hpp"
|
||||
#include "server/api/nearest_parameter_grammar.hpp"
|
||||
#include "server/api/route_parameters_grammar.hpp"
|
||||
#include "server/api/table_parameter_grammar.hpp"
|
||||
#include "server/api/nearest_parameter_grammar.hpp"
|
||||
#include "server/api/trip_parameter_grammar.hpp"
|
||||
#include "server/api/match_parameter_grammar.hpp"
|
||||
#include "server/api/tile_parameter_grammar.hpp"
|
||||
#include "server/api/trip_parameter_grammar.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -25,16 +27,29 @@ template <typename ParameterT,
|
||||
typename GrammarT,
|
||||
typename std::enable_if<detail::is_parameter_t<ParameterT>::value, int>::type = 0,
|
||||
typename std::enable_if<detail::is_grammar_t<GrammarT>::value, int>::type = 0>
|
||||
boost::optional<ParameterT> parseParameters(std::string::iterator &iter, const std::string::iterator end)
|
||||
boost::optional<ParameterT> parseParameters(std::string::iterator &iter,
|
||||
const std::string::iterator end)
|
||||
{
|
||||
using It = std::decay<decltype(iter)>::type;
|
||||
|
||||
GrammarT grammar;
|
||||
const auto result = boost::spirit::qi::parse(iter, end, grammar);
|
||||
|
||||
boost::optional<ParameterT> parameters;
|
||||
if (result && iter == end)
|
||||
parameters = std::move(grammar.parameters);
|
||||
try
|
||||
{
|
||||
const auto ok = boost::spirit::qi::parse(iter, end, grammar);
|
||||
|
||||
return parameters;
|
||||
// return move(a.b) is needed to move b out of a and then return the rvalue by implicit move
|
||||
if (ok && iter == end)
|
||||
return std::move(grammar.parameters);
|
||||
}
|
||||
catch (const qi::expectation_failure<It> &failure)
|
||||
{
|
||||
// The grammar above using expectation parsers ">" does not automatically increment the
|
||||
// iterator to the failing position. Extract the position from the exception ourselves.
|
||||
iter = failure.first;
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
} // ns detail
|
||||
|
||||
|
||||
Reference in New Issue
Block a user