From 91966a6917b9c2be32e5cb580874021a713a3d97 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 16 Apr 2019 21:09:59 +0900 Subject: [PATCH] perf: do not use concat_string if it is not needed At the earlier stage of the development, I thought that it is useful if lexer-combinators generate error messages, because by doing this, parser would not need to generate an error message. But now it turned out that to show an appropriate error message, parser need to generate according to the context. And almost all the messages from lexer are discarded. So I added another parameter to lexer-combinator to suppress error message generation. In the future, we may want to remove messages completely from lexers, but currently I will keep it. Removing those unused message generation makes the parsing process faster. --- toml/combinator.hpp | 91 ++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/toml/combinator.hpp b/toml/combinator.hpp index 52aaaae..36d367c 100644 --- a/toml/combinator.hpp +++ b/toml/combinator.hpp @@ -56,7 +56,8 @@ struct character static constexpr char target = C; template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); @@ -67,8 +68,12 @@ struct character const char c = *(loc.iter()); if(c != target) { - return err(concat_to_string("expected '", show_char(target), - "' but got '", show_char(c), "'.")); + if(msg) + { + return err(concat_to_string("expected '", show_char(target), + "' but got '", show_char(c), "'.")); + } + return err(""); } loc.advance(); // update location @@ -91,7 +96,8 @@ struct in_range static constexpr char lower = Low; template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); @@ -102,9 +108,13 @@ struct in_range const char c = *(loc.iter()); if(c < lower || upper < c) { - return err(concat_to_string("expected character in range " - "[", show_char(lower), ", ", show_char(upper), "] but got ", - "'", show_char(c), "'.")); + if(msg) + { + return err(concat_to_string("expected character in range " + "[", show_char(lower), ", ", show_char(upper), "] but got ", + "'", show_char(c), "'.")); + } + return err(""); } loc.advance(); @@ -125,7 +135,8 @@ template struct exclude { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); @@ -133,13 +144,16 @@ struct exclude if(loc.iter() == loc.end()) {return err("not sufficient characters");} auto first = loc.iter(); - auto rslt = Combinator::invoke(loc); + auto rslt = Combinator::invoke(loc, msg); if(rslt.is_ok()) { loc.reset(first); - return err(concat_to_string( - "invalid pattern (", Combinator::pattern(), ") appeared ", - rslt.unwrap().str())); + if(msg) + { + return err(concat_to_string("invalid pattern (", + Combinator::pattern(), ") appeared ", rslt.unwrap().str())); + } + return err(""); } loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but... return ok(region(loc, first, loc.iter())); @@ -156,12 +170,13 @@ template struct maybe { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); - const auto rslt = Combinator::invoke(loc); + const auto rslt = Combinator::invoke(loc, msg); if(rslt.is_ok()) { return rslt; @@ -182,34 +197,36 @@ template struct sequence { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); const auto first = loc.iter(); - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_err()) { loc.reset(first); return err(rslt.unwrap_err()); } - return sequence::invoke(loc, std::move(rslt.unwrap()), first); + return sequence::invoke(loc, std::move(rslt.unwrap()), first, msg); } // called from the above function only, recursively. template static result, std::string> - invoke(location& loc, region reg, Iterator first) + invoke(location& loc, region reg, Iterator first, + const bool msg = false) { - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_err()) { loc.reset(first); return err(rslt.unwrap_err()); } reg += rslt.unwrap(); // concat regions - return sequence::invoke(loc, std::move(reg), first); + return sequence::invoke(loc, std::move(reg), first, msg); } static std::string pattern() @@ -224,9 +241,10 @@ struct sequence // would be called from sequence::invoke only. template static result, std::string> - invoke(location& loc, region reg, Iterator first) + invoke(location& loc, region reg, Iterator first, + const bool msg = false) { - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_err()) { loc.reset(first); @@ -245,14 +263,15 @@ template struct either { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_ok()) {return rslt;} - return either::invoke(loc); + return either::invoke(loc, msg); } static std::string pattern() @@ -264,11 +283,12 @@ template struct either { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); - return Head::invoke(loc); + return Head::invoke(loc, msg); } static std::string pattern() { @@ -287,13 +307,14 @@ template struct repeat> { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { region retval(loc); const auto first = loc.iter(); for(std::size_t i=0; i struct repeat> { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { region retval(loc); const auto first = loc.iter(); for(std::size_t i=0; i> } while(true) { - auto rslt = T::invoke(loc); + auto rslt = T::invoke(loc, msg); if(rslt.is_err()) { return ok(std::move(retval)); @@ -348,12 +370,13 @@ template struct repeat { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { region retval(loc); while(true) { - auto rslt = T::invoke(loc); + auto rslt = T::invoke(loc, msg); if(rslt.is_err()) { return ok(std::move(retval));