code: def _process_rval_components(self):
          
          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
docs: 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