code: def parse_email(self):
          
          email = []
          # Match from current char until a non lower cased alpha
          name = self.match_string_pattern(spat.alphal)
          if not name:
              raise PartpyError(self, 'Expected a valid name')
  
          email.append(name)  # Store the name
          self.eat_string(name)  # Eat the name
  
          nextchar = self.get_char()
          if not nextchar == '@':
              raise PartpyError(self, 'Expecting @, found: ' + nextchar)
  
          email.append(nextchar)
          self.eat_length(1)  # Eat the '@' symbol
  
          # Use string pattern matching to match all lower cased alphas or '.'s.
          site = self.match_string_pattern(spat.alphal + '.')
          if not site:
              raise PartpyError(self, 'Expecting a site, found: ' + site)
  
          email.append(site)
          self.eat_string(site)  # Eat the site
          return ''.join(email)
docs: Email address parsing is done in several stages.
          First the name of the email use is determined.
          Then it looks for a '@' as a delimiter between the name and the site.
          Lastly the email site is matched.
  
          Each part's string is stored, combined and returned.