<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _process_rval_components(self):
 """This is suspiciously similar to _process_macro_default_arg, probably want to figure out how to merge the two. Process the rval of an assignment statement or a do-block """

        while True:
            match = self._expect_match(
                'do block component',
                # you could have a string, though that would be weird
                STRING_PATTERN,
                # a quote or an open/close parenthesis
                NON_STRING_DO_BLOCK_MEMBER_PATTERN,
                # a tag close
                TAG_CLOSE_PATTERN
            )
            matchgroups = match.groupdict()
            self.advance(match.end())
            if matchgroups.get('string') is not None:
                continue
            elif matchgroups.get('quote') is not None:
                self.rewind()
                # now look for a string
                match = self._expect_match('any string', STRING_PATTERN)
                self.advance(match.end())
            elif matchgroups.get('open'):
                self._parenthesis_stack.append(True)
            elif matchgroups.get('close'):
                self._parenthesis_stack.pop()
            elif matchgroups.get('tag_close'):
                if self._parenthesis_stack:
                    msg = ('Found "%}", expected ")"')
                    dbt.exceptions.raise_compiler_error(msg)
                return