public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] macros: Parse macro patterns properly in repetition
@ 2022-06-08 12:16 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:08b7516191a62e53819e24d08f2a413c84cf4925

commit 08b7516191a62e53819e24d08f2a413c84cf4925
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Mon Mar 7 12:27:30 2022 +0100

    macros: Parse macro patterns properly in repetition
    
    Co-authored-by: philberty <philip.herron@embecosm.com>

Diff:
---
 gcc/rust/expand/rust-macro-substitute-ctx.cc | 68 +++++++++++++++++++---------
 1 file changed, 47 insertions(+), 21 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index f9f2005b72b..61ab626f101 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -39,9 +39,6 @@ SubstituteCtx::substitute_repetition (
 {
   rust_assert (pattern_end < macro.size ());
 
-  rust_debug ("pattern start: %lu", pattern_start);
-  rust_debug ("pattern end: %lu", pattern_end);
-
   std::vector<std::unique_ptr<AST::Token>> expanded;
 
   // Find the first fragment and get the amount of repetitions that we should
@@ -154,19 +151,57 @@ SubstituteCtx::substitute_token (size_t token_idx)
 	// We need to parse up until the closing delimiter and expand this
 	// fragment->n times.
 	rust_debug ("expanding repetition");
-	std::vector<std::unique_ptr<AST::Token>> repetition_pattern;
+
+	// We're in a context where macro repetitions have already been
+	// parsed and validated: This means that
+	// 1/ There will be no delimiters as that is an error
+	// 2/ There are no fragment specifiers anymore, which prevents us
+	// from reusing parser functions.
+	//
+	// Repetition patterns are also special in that they cannot contain
+	// "rogue" delimiters: For example, this is invalid, as they are
+	// parsed as MacroMatches and must contain a correct amount of
+	// delimiters.
+	// `$($e:expr ) )`
+	//            ^ rogue closing parenthesis
+	//
+	// With all of that in mind, we can simply skip ahead from one
+	// parenthesis to the other to find the pattern to expand. Of course,
+	// pairs of delimiters, including parentheses, are allowed.
+	// `$($e:expr ( ) )`
+	// Parentheses are the sole delimiter for which we need a special
+	// behavior since they delimit the repetition pattern
+
 	size_t pattern_start = token_idx + 1;
 	size_t pattern_end = pattern_start;
-	for (; pattern_end < macro.size ()
-	       && macro.at (pattern_end)->get_id () != RIGHT_PAREN;
-	     pattern_end++)
-	  ;
+	auto parentheses_stack = 0;
+	for (size_t idx = pattern_start; idx < macro.size (); idx++)
+	  {
+	    if (macro.at (idx)->get_id () == LEFT_PAREN)
+	      {
+		parentheses_stack++;
+	      }
+	    else if (macro.at (idx)->get_id () == RIGHT_PAREN)
+	      {
+		if (parentheses_stack == 0)
+		  {
+		    pattern_end = idx;
+		    break;
+		  }
+		parentheses_stack--;
+	      }
+	  }
+
+	// Unreachable case, but let's make sure we don't ever run into it
+	rust_assert (pattern_end != pattern_start);
 
 	std::unique_ptr<AST::Token> separator_token = nullptr;
-	// FIXME: Can this go out of bounds?
-	auto &post_pattern_token = macro.at (pattern_end + 1);
-	if (!is_rep_op (post_pattern_token))
-	  separator_token = post_pattern_token->clone_token ();
+	if (pattern_end + 1 <= macro.size ())
+	  {
+	    auto &post_pattern_token = macro.at (pattern_end + 1);
+	    if (!is_rep_op (post_pattern_token))
+	      separator_token = post_pattern_token->clone_token ();
+	  }
 
 	// Amount of tokens to skip
 	auto to_skip = 0;
@@ -178,15 +213,6 @@ SubstituteCtx::substitute_token (size_t token_idx)
 	if (separator_token)
 	  to_skip += 1;
 
-	// FIXME: This skips whitespaces... Is that okay??
-	// FIXME: Is there any existing parsing function that allows us to
-	// parse a macro pattern?
-
-	// FIXME: Add error handling in the case we haven't found a matching
-	// closing delimiter
-
-	// FIXME: We need to parse the repetition token now
-
 	return {substitute_repetition (pattern_start, pattern_end,
 				       std::move (separator_token)),
 		pattern_end - pattern_start + to_skip};


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:16 [gcc/devel/rust/master] macros: Parse macro patterns properly in repetition Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).