aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse/rust-parse-impl.h
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-03-23 16:43:01 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2022-03-25 10:28:42 +0100
commit7ea35487a215ccd9a34c46a5a17194c61dbfb9d9 (patch)
tree2466ee1fda8728f68cada39716855edc35b66534 /gcc/rust/parse/rust-parse-impl.h
parent89ad4f21f25a2501bb9bb96338be4a6edb89bbcd (diff)
downloadgcc-7ea35487a215ccd9a34c46a5a17194c61dbfb9d9.zip
gcc-7ea35487a215ccd9a34c46a5a17194c61dbfb9d9.tar.gz
gcc-7ea35487a215ccd9a34c46a5a17194c61dbfb9d9.tar.bz2
macros: Allow checking past zeroable matches for follow-set restrictions
When trying to figure out if a match can follow another, we must figure out whether or not that match is in the follow-set of the other. If that match is zeroable (i.e a repetition using the * or ? kleene operators), then we must be able to check the match after them: should our current match not be present, the match after must be part of the follow-set. This commits allows us to performs such checks properly and to "look past" zeroable matches. This is not done with any lookahead, simply by keeping a list of pointers to possible previous matches and checking all of them for ambiguities.
Diffstat (limited to 'gcc/rust/parse/rust-parse-impl.h')
-rw-r--r--gcc/rust/parse/rust-parse-impl.h31
1 files changed, 28 insertions, 3 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 7e6ab9b..bcf4eca 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -1750,6 +1750,10 @@ Parser<ManagedTokenSource>::parse_macro_matcher ()
// parse actual macro matches
std::vector<std::unique_ptr<AST::MacroMatch>> matches;
+ // Set of possible preceding macro matches to make sure follow-set
+ // restrictions are respected.
+ // TODO: Consider using std::reference_wrapper instead of raw pointers?
+ std::vector<const AST::MacroMatch *> last_matches;
t = lexer.peek_token ();
// parse token trees until the initial delimiter token is found again
@@ -1770,9 +1774,30 @@ Parser<ManagedTokenSource>::parse_macro_matcher ()
if (matches.size () > 0)
{
- auto &last_match = matches.back ();
- if (!is_match_compatible (*last_match, *match))
- return AST::MacroMatcher::create_error (match->get_match_locus ());
+ const auto *last_match = matches.back ().get ();
+
+ // We want to check if we are dealing with a zeroable repetition
+ bool zeroable = false;
+ if (last_match->get_macro_match_type ()
+ == AST::MacroMatch::MacroMatchType::Repetition)
+ {
+ auto repetition
+ = static_cast<const AST::MacroMatchRepetition *> (last_match);
+
+ if (repetition->get_op ()
+ != AST::MacroMatchRepetition::MacroRepOp::ONE_OR_MORE)
+ zeroable = true;
+ }
+
+ if (!zeroable)
+ last_matches.clear ();
+
+ last_matches.emplace_back (last_match);
+
+ for (auto last : last_matches)
+ if (!is_match_compatible (*last, *match))
+ return AST::MacroMatcher::create_error (
+ match->get_match_locus ());
}
matches.push_back (std::move (match));