diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-23 16:43:01 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-25 10:28:42 +0100 |
commit | 7ea35487a215ccd9a34c46a5a17194c61dbfb9d9 (patch) | |
tree | 2466ee1fda8728f68cada39716855edc35b66534 /gcc/rust/parse/rust-parse-impl.h | |
parent | 89ad4f21f25a2501bb9bb96338be4a6edb89bbcd (diff) | |
download | gcc-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.h | 31 |
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)); |