| // Copyright 2017-2020 The Verible Authors. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include <vector> | |
| #include "common/analysis/matcher/bound_symbol_manager.h" | |
| #include "common/analysis/matcher/matcher.h" | |
| #include "common/text/symbol.h" | |
| #include "common/util/logging.h" | |
| namespace verible { | |
| namespace matcher { | |
| bool InnerMatchAll(const Symbol& symbol, | |
| const std::vector<Matcher>& inner_matchers, | |
| BoundSymbolManager* manager) { | |
| BoundSymbolManager backtrack_checkpoint(*manager); | |
| for (const auto& matcher : inner_matchers) { | |
| if (!matcher.Matches(symbol, manager)) { | |
| *manager = backtrack_checkpoint; | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| bool InnerMatchAny(const Symbol& symbol, | |
| const std::vector<Matcher>& inner_matchers, | |
| BoundSymbolManager* manager) { | |
| for (const auto& matcher : inner_matchers) { | |
| BoundSymbolManager lookahead(*manager); | |
| if (matcher.Matches(symbol, &lookahead)) { | |
| *manager = lookahead; | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| bool InnerMatchEachOf(const Symbol& symbol, | |
| const std::vector<Matcher>& inner_matchers, | |
| BoundSymbolManager* manager) { | |
| bool some_inner_matched_passed = false; | |
| for (const auto& matcher : inner_matchers) { | |
| BoundSymbolManager backup(*manager); | |
| if (matcher.Matches(symbol, manager)) { | |
| // If matcher passes, remember that we found a passing inner matcher | |
| some_inner_matched_passed = true; | |
| } else { | |
| // If failed to match, revert manager to backup. | |
| *manager = backup; | |
| } | |
| } | |
| return some_inner_matched_passed; | |
| } | |
| bool InnerMatchUnless(const Symbol& symbol, | |
| const std::vector<Matcher>& inner_matchers, | |
| BoundSymbolManager* manager) { | |
| CHECK_EQ(inner_matchers.size(), 1); | |
| const auto& matcher = inner_matchers[0]; | |
| // We don't need to keep track of what inner matcher matches because any | |
| // binds will be discarded if it matches. | |
| BoundSymbolManager dummy_manager; | |
| return !matcher.Matches(symbol, &dummy_manager); | |
| } | |
| } // namespace matcher | |
| } // namespace verible |