offlineimap rev 496

"Automatic Subversion Change Mailer" <[email protected]> Wed, 16 Jul 2003 13:58:49 -0500 (CDT)
Newsgroups gmane.mail.imap.offlineimap.subversion
Message-ID <[email protected]>
You are receiving this message because
all commits get sent to this address.

Author: jgoerzen
Date: 2003-07-16 13:58:20 -0500 (Wed, 16 Jul 2003)
New Revision: 496

Modified:
  imaplib/head/imap2/parser/imap.g
  imaplib/head/imap2/parser/imap.py
  imaplib/head/imap2/parser/yappsrt.py

Log:
Update imap.g
Add imap.py (generated from imap.g) since this will be part of the distro
Added yappsrt.py since this will be part of the distro


Diff:
Modified: imaplib/head/imap2/parser/imap.g
==============================================================================
--- imaplib/head/imap2/parser/imap.g	2003-07-16 18:38:03 UTC (rev 495)
+++ imaplib/head/imap2/parser/imap.g	2003-07-16 18:58:20 UTC (rev 496)
@@ -18,8 +18,8 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 # END OF COPYRIGHT #
+%%
 
-
 parser IMAP:
     token END: "$"
     

Added: imaplib/head/imap2/parser/imap.py
==============================================================================
--- imaplib/head/imap2/parser/imap.py	2003-07-16 18:38:03 UTC (rev 495)
+++ imaplib/head/imap2/parser/imap.py	2003-07-16 18:58:20 UTC (rev 496)
@@ -0,0 +1,1288 @@
+# Implementation of grammar from RFC3501
+# $Id: imap.g 494 2003-07-16 18:38:03Z jgoerzen $
+
+# COPYRIGHT #
+# Copyright (C) 2002 John Goerzen
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# END OF COPYRIGHT #
+
+from string import *
+import re
+from yappsrt import *
+
+class IMAPScanner(Scanner):
+    patterns = [
+        ('":"', re.compile(':')),
+        ("r'(?i)MIME'", re.compile('(?i)MIME')),
+        ("r'(?i)UNSEEN'", re.compile('(?i)UNSEEN')),
+        ("r'(?i)UIDVALIDITY'", re.compile('(?i)UIDVALIDITY')),
+        ("r'(?i)UIDNEXT'", re.compile('(?i)UIDNEXT')),
+        ("r'(?i)TRYCREATE'", re.compile('(?i)TRYCREATE')),
+        ("r'(?i)READ-WRITE'", re.compile('(?i)READ-WRITE')),
+        ("r'(?i)READ-ONLY'", re.compile('(?i)READ-ONLY')),
+        ("r'(?i)PERMANENTFLAGS'", re.compile('(?i)PERMANENTFLAGS')),
+        ("r'(?i)PARSE'", re.compile('(?i)PARSE')),
+        ("r'(?i)BADCHARSET'", re.compile('(?i)BADCHARSET')),
+        ("r'(?i)ALERT'", re.compile('(?i)ALERT')),
+        ("r'(?i)BYE'", re.compile('(?i)BYE')),
+        ('"\\\\\\\\"', re.compile('\\\\')),
+        ('"\\""', re.compile('"')),
+        ("r'(?i)NIL'", re.compile('(?i)NIL')),
+        ("r'(?i)UID'", re.compile('(?i)UID')),
+        ("r'(?i)BODY'", re.compile('(?i)BODY')),
+        ("r'(?i)RFC822\\.SIZE'", re.compile('(?i)RFC822\\.SIZE')),
+        ("r'(?i)INTERNALDATE'", re.compile('(?i)INTERNALDATE')),
+        ("r'(?i)ENVELOPE'", re.compile('(?i)ENVELOPE')),
+        ("r'(?i)FLAGS'", re.compile('(?i)FLAGS')),
+        ("r'(?i)FETCH'", re.compile('(?i)FETCH')),
+        ("r'(?i)EXPUNGE'", re.compile('(?i)EXPUNGE')),
+        ("r'(?i)TEXT'", re.compile('(?i)TEXT')),
+        ('"(?i)STATUS"', re.compile('(?i)STATUS')),
+        ('"(?i)SEARCH"', re.compile('(?i)SEARCH')),
+        ('"(?i)(LIST|LSUB)"', re.compile('(?i)(LIST|LSUB)')),
+        ('"(?i)FLAGS"', re.compile('(?i)FLAGS')),
+        ('"INBOX"', re.compile('INBOX')),
+        ("r'\\}'", re.compile('\\}')),
+        ("r'\\{'", re.compile('\\{')),
+        ("r'(?i)\\\\Recent'", re.compile('(?i)\\\\Recent')),
+        ('"(?i)IMAP4rev1"', re.compile('(?i)IMAP4rev1')),
+        ('"(?i)CAPABILITY"', re.compile('(?i)CAPABILITY')),
+        ('"(?i)AUTH="', re.compile('(?i)AUTH=')),
+        ('"="', re.compile('=')),
+        ('"=="', re.compile('==')),
+        ('"(?i)AUTHENTICATE"', re.compile('(?i)AUTHENTICATE')),
+        ('END', re.compile('$')),
+        ('LPAREN', re.compile('\\(')),
+        ('RPAREN', re.compile('\\)')),
+        ('PLUS', re.compile('\\+')),
+        ('DASH', re.compile('-')),
+        ('BACKSLASH', re.compile('\\\\')),
+        ('ASTERISK', re.compile('\\*')),
+        ('LBRACKET', re.compile('\\[')),
+        ('RBRACKET', re.compile('\\]')),
+        ('PERIOD', re.compile('\\.')),
+        ('PLUSMINUS', re.compile('[+-]')),
+        ('LT', re.compile('<')),
+        ('GT', re.compile('>')),
+        ('ALPHA', re.compile('[a-zA-Z]')),
+        ('DQUOTE', re.compile('"')),
+        ('DIGIT', re.compile('[0-9]')),
+        ('DIGITx2', re.compile('[0-9]{2}')),
+        ('DIGITx4', re.compile('[0-9]{4}')),
+        ('SP', re.compile('\\ ')),
+        ('CRLF', re.compile('\\r\\n')),
+        ('CTL', re.compile('[\\x00-\\x1f\\x7f]')),
+        ('ATOM_CHAR', re.compile('(?![(){ \\x00-\\x1f\\x7f%*"\\\\\\]])[\\x01-\\x7f]')),
+        ('atom_specials_tok', re.compile('[()}')),
+        ('base64_char', re.compile('[a-zA-Z0-9+/]')),
+        ('base64_char_x2', re.compile('[a-zA-Z0-9+/]{2}')),
+        ('base64_char_x3', re.compile('[a-zA-Z0-9+/]{3}')),
+        ('base64_char_x4', re.compile('[a-zA-Z0-9+/]{4}')),
+        ('CHAR8', re.compile('[\\x01-\\xff]')),
+        ('date_day', re.compile('[0-9]{1,2}')),
+        ('date_day_fixed', re.compile('[ 0-9][0-9]')),
+        ('date_month', re.compile('(?i)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)')),
+        ('date_year', re.compile('[0-9]{4}')),
+        ('digit_nz', re.compile('[1-9]')),
+        ('flag_custom_base', re.compile('(?i)\\\\(Answered|Flagged|Deleted|Seen|Draft)')),
+        ('list_wildcards', re.compile('[%*]')),
+        ('mailbox_data_tok', re.compile('(?i)(EXISTS|RECENT)')),
+        ('mbx_list_sflag', re.compile('(?i)\\\\(Noselect|Marked|Unmarked)')),
+        ('media_basic_tok', re.compile('(?i)(APPLICATION|AUDIO|IMAGE|MESSAGE|VIDEO')),
+        ('media_message', re.compile('(?i)"MESSAGE" "RFC822"')),
+        ('msg_att_static_tok', re.compile('(?i)RFC822(\\.HEADER|\\.TEXT){0,1}')),
+        ('msg_att_static_bodytok', re.compile('(?i)BODY(STRUCTURE){0,1}')),
+        ('number_tok', re.compile('[0-9]+')),
+        ('nz_number_tok', re.compile('[1-9][0-9]*')),
+        ('QUOTED_CHAR_TOK', re.compile('(?![\\n\\r"\\\\])[\\x01-\\x7f]')),
+        ('quoted_specials', re.compile('["\\\\]')),
+        ('resp_cond_auth_tok', re.compile('(?i)(OK|PREAUTH)')),
+        ('resp_cond_state_tok', re.compile('(?i){OK|NO|BAD)')),
+        ('resp_specials', re.compile('\\]')),
+        ('RESP_TEXT_CHAR', re.compile('(?![\\n\\r\\]])[\\x01-\\x7f]')),
+        ('section_msgtext_tok', re.compile('(?i)HEADER(\\.FIELDS){0,1}(\\.NOT){0,1}')),
+        ('status_att', re.compile('(?i)(MESSAGES|RECENT|UIDNEXT|UIDVALIDITY|UNSEEN)')),
+        ('TAG_ATOM_CHAR', re.compile('(?![+(){ \\x00-\\x1f\\x7f%*"\\\\\\]])[\\x01-\\x7f]')),
+        ('TEXT_CHAR', re.compile('(?![\\n\\r])[\\x01-\\x7f]')),
+    ]
+    def __init__(self, str):
+        Scanner.__init__(self,None,[],str)
+
+class IMAP(Parser):
+    def address(self):
+        LPAREN = self._scan('LPAREN')
+        addr_name = self.addr_name()
+        SP = self._scan('SP')
+        addr_adl = self.addr_adl()
+        SP = self._scan('SP')
+        addr_mailbox = self.addr_mailbox()
+        SP = self._scan('SP')
+        addr_host = self.addr_host()
+        RPAREN = self._scan('RPAREN')
+        return {'name': addr_name, 'adl': addr_adl, 'mailbox': addr_mailbox, 'host': addr_host}
+
+    def addr_adl(self):
+        nstring = self.nstring()
+        return nstring
+
+    def addr_host(self):
+        nstring = self.nstring()
+        return nstring
+
+    def addr_mailbox(self):
+        nstring = self.nstring()
+        return nstring
+
+    def addr_name(self):
+        nstring = self.nstring()
+        return nstring
+
+    def astring(self):
+        _token_ = self._peek('"\\""', "r'\\{'", 'ATOM_CHAR', 'resp_specials')
+        if _token_ not in ['ATOM_CHAR', 'resp_specials']:
+            string = self.string()
+            return string
+        else: # in ['ATOM_CHAR', 'resp_specials']
+            v = ''
+            while 1:
+                ASTRING_CHAR = self.ASTRING_CHAR()
+                v += ASTRING_CHAR
+                if self._peek('ATOM_CHAR', 'resp_specials', 'SP', 'RPAREN', 'CRLF') not in ['ATOM_CHAR', 'resp_specials']: break
+            return v
+
+    def atom(self):
+        v = ''
+        while 1:
+            ATOM_CHAR = self._scan('ATOM_CHAR')
+            v += ATOM_CHAR
+            if self._peek('ATOM_CHAR', 'SP', 'RESP_TEXT_CHAR', 'CRLF', 'RBRACKET', '"(?i)IMAP4rev1"', 'RPAREN') != 'ATOM_CHAR': break
+        return v
+
+    def ASTRING_CHAR(self):
+        _token_ = self._peek('ATOM_CHAR', 'resp_specials')
+        if _token_ == 'ATOM_CHAR':
+            ATOM_CHAR = self._scan('ATOM_CHAR')
+            return ATOM_CHAR
+        else: # == 'resp_specials'
+            resp_specials = self._scan('resp_specials')
+            return resp_specials
+
+    def atom_specials(self):
+        _token_ = self._peek('atom_specials_tok', 'SP', 'CTL', 'list_wildcards', 'quoted_specials', 'resp_specials')
+        if _token_ == 'atom_specials_tok':
+            atom_specials_tok = self._scan('atom_specials_tok')
+            return atom_specials_tok
+        elif _token_ == 'SP':
+            SP = self._scan('SP')
+            return SP
+        elif _token_ == 'CTL':
+            CTL = self._scan('CTL')
+            return CTL
+        elif _token_ == 'list_wildcards':
+            list_wildcards = self._scan('list_wildcards')
+            return list_wildcards
+        elif _token_ == 'quoted_specials':
+            quoted_specials = self._scan('quoted_specials')
+            return quoted_specials
+        else: # == 'resp_specials'
+            resp_specials = self._scan('resp_specials')
+            return resp_specials
+
+    def authenticate(self):
+        self._scan('"(?i)AUTHENTICATE"')
+        SP = self._scan('SP')
+        auth_type = self.auth_type()
+        v = {'auth_type': auth_type}
+        if 1:
+            CRLF = self._scan('CRLF')
+            base64 = self.base64()
+            v['base64'] = base64
+        return v
+
+    def auth_type(self):
+        atom = self.atom()
+        return atom
+
+    def base64(self):
+        v = ''
+        while self._peek('base64_char_x4', 'base64_char_x2', 'base64_char_x3', 'CRLF') == 'base64_char_x4':
+            self._scan('base64_char_x4')
+            v += base64_char_x4
+        if self._peek('base64_char_x2', 'base64_char_x3', 'CRLF') != 'CRLF':
+            base64_terminal = self.base64_terminal()
+            v += base64_terminal
+        return v
+
+    def base64_terminal(self):
+        _token_ = self._peek('base64_char_x2', 'base64_char_x3')
+        if _token_ == 'base64_char_x2':
+            self._scan('base64_char_x2')
+            self._scan('"=="')
+            return base64_char_x2 + "=="
+        else: # == 'base64_char_x3'
+            self._scan('base64_char_x3')
+            self._scan('"="')
+            return base64_char_x3 + "="
+
+    def body(self):
+        LPAREN = self._scan('LPAREN')
+        _token_ = self._peek('LPAREN', 'media_message', 'DQUOTE', '"\\""', "r'\\{'")
+        if _token_ != 'LPAREN':
+            body_type_1part = self.body_type_1part()
+            return body_type_1part
+        else: # == 'LPAREN'
+            body_type_mpart = self.body_type_mpart()
+            return body_type_mpart
+        RPAREN = self._scan('RPAREN')
+
+    def body_extension(self):
+        _token_ = self._peek('LPAREN', "r'(?i)NIL'", 'number_tok', '"\\""', "r'\\{'")
+        if _token_ not in ['LPAREN', 'number_tok']:
+            nstring = self.nstring()
+            v = nstring
+        elif _token_ == 'number_tok':
+            number = self.number()
+            v = number
+        else: # == 'LPAREN'
+            LPAREN = self._scan('LPAREN')
+            body_extension = self.body_extension()
+            v = [body_extension]
+            while self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                body_extension = self.body_extension()
+                v.append(body_extension)
+        return v
+
+    def body_ext_1part(self):
+        body_fld_md5 = self.body_fld_md5()
+        v = {'md5': body_fld_md5, 'extension': []}
+        if self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            body_fld_dsp = self.body_fld_dsp()
+            v['dsp']: body_fld_dsp
+            if self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                body_fld_lang = self.body_fld_lang()
+                v['lang']: body_fld_lang
+                if self._peek('SP', 'RPAREN') == 'SP':
+                    SP = self._scan('SP')
+                    body_fld_loc = self.body_fld_loc()
+                    v['loc']: body_fld_loc
+                    while self._peek('SP', 'RPAREN') == 'SP':
+                        SP = self._scan('SP')
+                        body_extension = self.body_extension()
+                        v['extension'].append(body_extension)
+        return v
+
+    def body_ext_mpart(self):
+        body_fld_param = self.body_fld_param()
+        v = {'param': body_fld_param, 'extension': []}
+        if self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            body_fld_dsp = self.body_fld_dsp()
+            v['dsp']: body_fld_dsp
+            if self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                body_fld_lang = self.body_fld_lang()
+                v['lang']: body_fld_lang
+                if self._peek('SP', 'RPAREN') == 'SP':
+                    SP = self._scan('SP')
+                    body_fld_loc = self.body_fld_loc()
+                    v['loc']: body_fld_loc
+                    while self._peek('SP', 'RPAREN') == 'SP':
+                        SP = self._scan('SP')
+                        body_extension = self.body_extension()
+                        v['extension'].append(body_extension)
+        return v
+
+    def body_fields(self):
+        body_fld_param = self.body_fld_param()
+        SP = self._scan('SP')
+        body_fld_id = self.body_fld_id()
+        SP = self._scan('SP')
+        body_fld_desc = self.body_fld_desc()
+        SP = self._scan('SP')
+        body_fld_enc = self.body_fld_enc()
+        SP = self._scan('SP')
+        body_fld_octets = self.body_fld_octets()
+        return {'param': body_fld_param, 'id': body_fld_id, 'desc': body_fld_desc, 'enc': body_fld_enc, 'octets': body_fld_octets}
+
+    def body_fld_desc(self):
+        nstring = self.nstring()
+        return nstring
+
+    def body_fld_dsp(self):
+        _token_ = self._peek('LPAREN', "r'(?i)NIL'")
+        if _token_ == "r'(?i)NIL'":
+            nil = self.nil()
+            v = nil
+        else: # == 'LPAREN'
+            LPAREN = self._scan('LPAREN')
+            string = self.string()
+            SP = self._scan('SP')
+            body_fld_param = self.body_fld_param()
+            RPAREN = self._scan('RPAREN')
+            v = [string, body_fld_param]
+        return v
+
+    def body_fld_enc(self):
+        string = self.string()
+        return string
+
+    def body_fld_id(self):
+        nstring = self.nstring()
+        return nstring
+
+    def body_fld_lang(self):
+        _token_ = self._peek('LPAREN', "r'(?i)NIL'", '"\\""', "r'\\{'")
+        if _token_ != 'LPAREN':
+            nstring = self.nstring()
+            v = [nstring]
+        else: # == 'LPAREN'
+            LPAREN = self._scan('LPAREN')
+            string = self.string()
+            v = [string]
+            while self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                string = self.string()
+                v.append(string)
+        return v
+
+    def body_fld_loc(self):
+        nstring = self.nstring()
+        return nstring
+
+    def body_fld_lines(self):
+        number = self.number()
+        return number
+
+    def body_fld_md5(self):
+        nstring = self.nstring()
+        return nstring
+
+    def body_fld_octets(self):
+        number = self.number()
+        return number
+
+    def body_fld_param(self):
+        _token_ = self._peek('LPAREN', "r'(?i)NIL'")
+        if _token_ == "r'(?i)NIL'":
+            nil = self.nil()
+            v = nil
+        else: # == 'LPAREN'
+            LPAREN = self._scan('LPAREN')
+            v = []
+            string = self.string()
+            x = string
+            SP = self._scan('SP')
+            string = self.string()
+            v.append([x, string])
+            while self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                string = self.string()
+                x = string
+                SP = self._scan('SP')
+                string = self.string()
+                v.append([x, string])
+            RPAREN = self._scan('RPAREN')
+        return v
+
+    def body_type_1part(self):
+        _token_ = self._peek('media_message', 'DQUOTE', '"\\""', "r'\\{'")
+        if _token_ not in ['media_message', 'DQUOTE']:
+            body_type_basic = self.body_type_basic()
+            v = [body_type_basic]
+        elif _token_ == 'media_message':
+            body_type_msg = self.body_type_msg()
+            v = [body_type_msg]
+        else: # == 'DQUOTE'
+            body_type_text = self.body_type_text()
+            v = [body_type_text]
+        if self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            body_ext_1part = self.body_ext_1part()
+            v.append(body_ext_1part)
+        return v
+
+    def body_type_basic(self):
+        media_basic = self.media_basic()
+        v = {'media_basic': media_basic}
+        SP = self._scan('SP')
+        body_fields = self.body_fields()
+        v['body_fields']: body_fields
+        return v
+
+    def body_type_mpart(self):
+        v_body = []
+        while 1:
+            body = self.body()
+            v_body.append(body)
+            if self._peek('LPAREN', 'SP') != 'LPAREN': break
+        v = {'body': v_body}
+        SP = self._scan('SP')
+        media_subtype = self.media_subtype()
+        v['media_subtype']: media_subtype
+        if self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            body_ext_mpart = self.body_ext_mpart()
+            v['body_ext_mpart']: body_ext_mpart
+        return v
+
+    def body_type_msg(self):
+        media_message = self._scan('media_message')
+        SP = self._scan('SP')
+        body_fields = self.body_fields()
+        SP = self._scan('SP')
+        envelope = self.envelope()
+        SP = self._scan('SP')
+        body = self.body()
+        SP = self._scan('SP')
+        body_fld_lines = self.body_fld_lines()
+        return {'media_message': media_message, 'body_fields': body_fields,'envelope': envelope, 'body': body, 'bofy_fld_lines': body_fld_lines}
+
+    def body_type_text(self):
+        media_text = self.media_text()
+        SP = self._scan('SP')
+        body_fields = self.body_fields()
+        SP = self._scan('SP')
+        body_fld_lines = self.body_fld_lines()
+        return {'media_text': media_text, 'body_fields': body_fields, 'body_fld_lines': body_fld_lines}
+
+    def capability(self):
+        _token_ = self._peek('"(?i)AUTH="', 'ATOM_CHAR')
+        if _token_ == '"(?i)AUTH="':
+            self._scan('"(?i)AUTH="')
+            auth_type = self.auth_type()
+            v = "AUTH=" + auth_type
+        else: # == 'ATOM_CHAR'
+            atom = self.atom()
+            v = atom
+        return v
+
+    def capability_data(self):
+        self._scan('"(?i)CAPABILITY"')
+        v = []
+        while self._peek('SP', '"(?i)IMAP4rev1"') == 'SP':
+            SP = self._scan('SP')
+            capability = self.capability()
+            v.append(capability)
+        self._scan('"(?i)IMAP4rev1"')
+        v.append("IMAP4rev1")
+        while self._peek('SP', 'RESP_TEXT_CHAR', 'CRLF', 'RBRACKET') == 'SP':
+            SP = self._scan('SP')
+            capability = self.capability()
+            v.append(capability)
+        return v
+
+    def continue_req(self):
+        PLUS = self._scan('PLUS')
+        SP = self._scan('SP')
+        _token_ = self._peek('base64_char_x4', 'CRLF', 'LBRACKET', 'base64_char_x2', 'base64_char_x3', 'TEXT_CHAR')
+        if _token_ in ['LBRACKET', 'TEXT_CHAR']:
+            resp_text = self.resp_text()
+            v = resp_text
+        else: 
+            base64 = self.base64()
+            v = base64
+        CRLF = self._scan('CRLF')
+        return v
+
+    def date(self):
+        _token_ = self._peek('DQUOTE', 'date_day')
+        if _token_ == 'date_day':
+            date_text = self.date_text()
+        else: # == 'DQUOTE'
+            DQUOTE = self._scan('DQUOTE')
+            date_text = self.date_text()
+            DQUOTE = self._scan('DQUOTE')
+        return date_text
+
+    def date_text(self):
+        date_day = self._scan('date_day')
+        DASH = self._scan('DASH')
+        date_month = self._scan('date_month')
+        DASH = self._scan('DASH')
+        date_year = self._scan('date_year')
+        return {'day': int(date_day), 'month': date_month, 'year': int(date_year)}
+
+    def date_time(self):
+        DQUOTE = self._scan('DQUOTE')
+        date_day_fixed = self._scan('date_day_fixed')
+        DASH = self._scan('DASH')
+        date_month = self._scan('date_month')
+        DASH = self._scan('DASH')
+        date_year = self._scan('date_year')
+        SP = self._scan('SP')
+        time = self.time()
+        SP = self._scan('SP')
+        zone = self.zone()
+        DQUOTE = self._scan('DQUOTE')
+        return {'day': int(date_day_fixed.strip()), 'month': date_month, 'year': int(date_year),'time': time, 'zone': zone}
+
+    def envelope(self):
+        LPAREN = self._scan('LPAREN')
+        env_date = self.env_date()
+        SP = self._scan('SP')
+        env_subject = self.env_subject()
+        SP = self._scan('SP')
+        env_from = self.env_from()
+        SP = self._scan('SP')
+        env_sender = self.env_sender()
+        SP = self._scan('SP')
+        env_reply_to = self.env_reply_to()
+        SP = self._scan('SP')
+        env_to = self.env_to()
+        SP = self._scan('SP')
+        env_cc = self.env_cc()
+        SP = self._scan('SP')
+        env_bcc = self.env_bcc()
+        SP = self._scan('SP')
+        env_in_reply_to = self.env_in_reply_to()
+        SP = self._scan('SP')
+        env_message_id = self.env_message_id()
+        RPAREN = self._scan('RPAREN')
+        return {'date': env_date, 'subject': env_subject, 'from': env_from, 'sender': env_sender, 'reply_to': env_reply_to, 'to': env_to, 'cc': env_cc, 'bcc': env_bcc, 'in_reply_to': env_in_reply_to, 'message_id': env_message_id }
+
+    def env_custom_addrs(self):
+        _token_ = self._peek('LPAREN', "r'(?i)NIL'")
+        if _token_ == "r'(?i)NIL'":
+            nil = self.nil()
+            v = []
+        else: # == 'LPAREN'
+            LPAREN = self._scan('LPAREN')
+            v = []
+            while 1:
+                address = self.address()
+                v.append(address)
+                if self._peek('LPAREN', 'RPAREN') != 'LPAREN': break
+            RPAREN = self._scan('RPAREN')
+        return v
+
+    def env_bcc(self):
+        env_custom_addrs = self.env_custom_addrs()
+        return env_custom_addrs
+
+    def env_cc(self):
+        env_custom_addrs = self.env_custom_addrs()
+        return env_custom_addrs
+
+    def env_date(self):
+        nstring = self.nstring()
+        return nstring
+
+    def env_from(self):
+        env_custom_addrs = self.env_custom_addrs()
+        return env_custom_addrs
+
+    def env_in_reply_to(self):
+        nstring = self.nstring()
+        return nstring
+
+    def env_message_id(self):
+        nstring = self.nstring()
+        return nstring
+
+    def env_reply_to(self):
+        env_custom_addrs = self.env_custom_addrs()
+        return env_custom_addrs
+
+    def env_sender(self):
+        env_custom_addrs = self.env_custom_addrs()
+        return env_custom_addrs
+
+    def env_subject(self):
+        nstring = self.nstring()
+        return nstring
+
+    def env_to(self):
+        env_custom_addrs = self.env_custom_addrs()
+        return env_custom_addrs
+
+    def flag(self):
+        _token_ = self._peek('flag_custom_base', 'ATOM_CHAR', 'BACKSLASH')
+        if _token_ == 'flag_custom_base':
+            flag_custom_base = self._scan('flag_custom_base')
+            v = flag_custom_base
+        elif _token_ == 'ATOM_CHAR':
+            flag_keyword = self.flag_keyword()
+            v = flag_keyword
+        else: # == 'BACKSLASH'
+            flag_extension = self.flag_extension()
+            v = flag_extension
+        return v
+
+    def flag_extension(self):
+        BACKSLASH = self._scan('BACKSLASH')
+        atom = self.atom()
+        return "\\" + atom
+
+    def flag_fetch(self):
+        _token_ = self._peek('flag_custom_base', "r'(?i)\\\\Recent'", 'ATOM_CHAR', 'BACKSLASH')
+        if _token_ != "r'(?i)\\\\Recent'":
+            flag = self.flag()
+            v = flag
+        else: # == "r'(?i)\\\\Recent'"
+            self._scan("r'(?i)\\\\Recent'")
+            v = "\\Recent"
+        return v
+
+    def flag_keyword(self):
+        atom = self.atom()
+        return atom
+
+    def flag_list(self):
+        LPAREN = self._scan('LPAREN')
+        v = []
+        if self._peek('flag_custom_base', 'SP', 'RPAREN', 'ATOM_CHAR', 'BACKSLASH') not in ['SP', 'RPAREN']:
+            flag = self.flag()
+            v.append(flag)
+            while self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                flag = self.flag()
+                v.append(flag)
+        RPAREN = self._scan('RPAREN')
+        return v
+
+    def flag_perm(self):
+        flag = self.flag()
+        v = flag
+        return v
+
+    def greeting(self):
+        ASTERISK = self._scan('ASTERISK')
+        SP = self._scan('SP')
+        _token_ = self._peek('resp_cond_auth_tok', "r'(?i)BYE'")
+        if _token_ == 'resp_cond_auth_tok':
+            resp_cond_auth = self.resp_cond_auth()
+            v = resp_cond_auth
+        else: # == "r'(?i)BYE'"
+            resp_cond_bye = self.resp_cond_bye()
+            v = resp_cond_bye
+        CRLF = self._scan('CRLF')
+        return v
+
+    def header_fld_name(self):
+        astring = self.astring()
+        return astring
+
+    def header_list(self):
+        LPAREN = self._scan('LPAREN')
+        header_fld_name = self.header_fld_name()
+        v = [header_fld_name]
+        while self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            header_fld_name = self.header_fld_name()
+            v.append(header_fld_name)
+        RPAREN = self._scan('RPAREN')
+        return v
+
+    def list_char(self):
+        _token_ = self._peek('ATOM_CHAR', 'list_wildcards', 'resp_specials')
+        if _token_ == 'ATOM_CHAR':
+            ATOM_CHAR = self._scan('ATOM_CHAR')
+            v = ATOM_CHAR
+        elif _token_ == 'list_wildcards':
+            list_wildcards = self._scan('list_wildcards')
+            v = list_wildcards
+        else: # == 'resp_specials'
+            resp_specials = self._scan('resp_specials')
+            v = resp_specials
+        return v
+
+    def literal(self):
+        self._scan("r'\\{'")
+        number = self.number()
+        self._scan("r'\\}'")
+        CRLF = self._scan('CRLF')
+        literal_load = self.literal_load(number)
+        return literal_load
+
+    def literal_load(self, X):
+        count = 0
+        data = ''
+        while self._peek('CHAR8', 'SP', 'RPAREN', 'CRLF') == 'CHAR8':
+            if count == X: break
+            self._scan('CHAR8')
+            count += 1
+            data += CHAR8
+        return data
+
+    def mailbox(self):
+        _token_ = self._peek('"INBOX"', '"\\""', "r'\\{'", 'ATOM_CHAR', 'resp_specials')
+        if _token_ == '"INBOX"':
+            self._scan('"INBOX"')
+            v = "INBOX"
+        else: # in ['"\\""', "r'\\{'", 'ATOM_CHAR', 'resp_specials']
+            astring = self.astring()
+            v = astring
+        return v
+
+    def mailbox_data(self):
+        v = {}
+        _token_ = self._peek('"(?i)FLAGS"', '"(?i)(LIST|LSUB)"', '"(?i)SEARCH"', '"(?i)STATUS"', 'number_tok')
+        if _token_ == '"(?i)FLAGS"':
+            self._scan('"(?i)FLAGS"')
+            SP = self._scan('SP')
+            flag_list = self.flag_list()
+            v['flags'] = flag_list
+        elif _token_ == '"(?i)(LIST|LSUB)"':
+            self._scan('"(?i)(LIST|LSUB)"')
+            SP = self._scan('SP')
+            mailbox_list = self.mailbox_list()
+            v['list'] = mailbox_list
+        elif _token_ == '"(?i)SEARCH"':
+            self._scan('"(?i)SEARCH"')
+            v['search'] = []
+            while self._peek('SP', 'CRLF') == 'SP':
+                SP = self._scan('SP')
+                nz_number = self.nz_number()
+                v['search'].append(nz_number)
+        elif _token_ == '"(?i)STATUS"':
+            self._scan('"(?i)STATUS"')
+            SP = self._scan('SP')
+            mailbox = self.mailbox()
+            v['status'] = {'mailbox': mailbox}
+            SP = self._scan('SP')
+            LPAREN = self._scan('LPAREN')
+            if self._peek('RPAREN', 'status_att') == 'status_att':
+                status_att_list = self.status_att_list()
+                v['status']['att'] = status_att_list
+            RPAREN = self._scan('RPAREN')
+        else: # == 'number_tok'
+            number = self.number()
+            SP = self._scan('SP')
+            mailbox_data_tok = self._scan('mailbox_data_tok')
+            v[mailbox_data_tok.upper()] = number
+        return v
+
+    def mailbox_list(self):
+        v = {}
+        LPAREN = self._scan('LPAREN')
+        if self._peek('RPAREN', 'mbx_list_sflag', 'BACKSLASH') != 'RPAREN':
+            mbx_list_flags = self.mbx_list_flags()
+            v['flags'] = mbx_list_flags
+        RPAREN = self._scan('RPAREN')
+        SP = self._scan('SP')
+        _token_ = self._peek('DQUOTE', "r'(?i)NIL'")
+        if _token_ == "r'(?i)NIL'":
+            nil = self.nil()
+            v['data'] = nil
+        else: # == 'DQUOTE'
+            DQUOTE = self._scan('DQUOTE')
+            QUOTED_CHAR = self.QUOTED_CHAR()
+            DQUOTE = self._scan('DQUOTE')
+            v['data'] = QUOTED_CHAR
+        SP = self._scan('SP')
+        mailbox = self.mailbox()
+        v['mailbox'] = mailbox
+        return v
+
+    def mbx_list_flags(self):
+        v = []
+        _token_ = self._peek('mbx_list_sflag', 'BACKSLASH')
+        if _token_ == 'BACKSLASH':
+            mbx_list_oflag = self.mbx_list_oflag()
+            v.append(mbx_list_oflag)
+        else: # == 'mbx_list_sflag'
+            mbx_list_sflag = self._scan('mbx_list_sflag')
+            v.append(mbx_list_sflag)
+        while self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            _token_ = self._peek('mbx_list_sflag', 'BACKSLASH')
+            if _token_ == 'BACKSLASH':
+                mbx_list_oflag = self.mbx_list_oflag()
+                v.append(mbx_list_oflag)
+            else: # == 'mbx_list_sflag'
+                mbx_list_sflag = self._scan('mbx_list_sflag')
+                v.append(mbx_list_sflag)
+        return v
+
+    def mbx_list_oflag(self):
+        flag_extension = self.flag_extension()
+        return flag_extension
+
+    def media_basic(self):
+        string = self.string()
+        SP = self._scan('SP')
+        media_subtype = self.media_subtype()
+        return (string, media_subtype)
+
+    def media_subtype(self):
+        string = self.string()
+        return string
+
+    def media_text(self):
+        DQUOTE = self._scan('DQUOTE')
+        self._scan("r'(?i)TEXT'")
+        DQUOTE = self._scan('DQUOTE')
+        SP = self._scan('SP')
+        media_subtype = self.media_subtype()
+        return ('TEXT', media_subtype)
+
+    def message_data(self):
+        nz_number = self.nz_number()
+        SP = self._scan('SP')
+        v = [nz_number]
+        _token_ = self._peek("r'(?i)EXPUNGE'", "r'(?i)FETCH'")
+        if _token_ == "r'(?i)EXPUNGE'":
+            self._scan("r'(?i)EXPUNGE'")
+            v.append('EXPUNGE')
+        else: # == "r'(?i)FETCH'"
+            self._scan("r'(?i)FETCH'")
+            SP = self._scan('SP')
+            msg_att = self.msg_att()
+            v.extend(['FETCH', msg_att])
+        return v
+
+    def msg_att(self):
+        LPAREN = self._scan('LPAREN')
+        v = {}
+        _token_ = self._peek("r'(?i)FLAGS'", "r'(?i)ENVELOPE'", "r'(?i)INTERNALDATE'", 'msg_att_static_tok', "r'(?i)RFC822\\.SIZE'", 'msg_att_static_bodytok', "r'(?i)BODY'", "r'(?i)UID'")
+        if _token_ == "r'(?i)FLAGS'":
+            msg_att_dynamic = self.msg_att_dynamic()
+            v.update(msg_att_dynamic)
+        else: 
+            msg_att_static = self.msg_att_static()
+            v.update(msg_att_static)
+        while self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            _token_ = self._peek("r'(?i)FLAGS'", "r'(?i)ENVELOPE'", "r'(?i)INTERNALDATE'", 'msg_att_static_tok', "r'(?i)RFC822\\.SIZE'", 'msg_att_static_bodytok', "r'(?i)BODY'", "r'(?i)UID'")
+            if _token_ == "r'(?i)FLAGS'":
+                msg_att_dynamic = self.msg_att_dynamic()
+                v.update(msg_att_dynamic)
+            else: 
+                msg_att_static = self.msg_att_static()
+                v.update(msg_att_static)
+        RPAREN = self._scan('RPAREN')
+        return v
+
+    def msg_att_dynamic(self):
+        self._scan("r'(?i)FLAGS'")
+        SP = self._scan('SP')
+        LPAREN = self._scan('LPAREN')
+        v = []
+        if self._peek('flag_custom_base', "r'(?i)\\\\Recent'", 'SP', 'RPAREN', 'ATOM_CHAR', 'BACKSLASH') not in ['SP', 'RPAREN']:
+            flag_fetch = self.flag_fetch()
+            v.append(flag_fetch)
+            while self._peek('SP', 'RPAREN') == 'SP':
+                SP = self._scan('SP')
+                flag_fetch = self.flag_fetch()
+                v.append(flag_fetch)
+        RPAREN = self._scan('RPAREN')
+        return {'FLAGS': v}
+
+    def msg_att_static(self):
+        _token_ = self._peek("r'(?i)ENVELOPE'", "r'(?i)INTERNALDATE'", 'msg_att_static_tok', "r'(?i)RFC822\\.SIZE'", 'msg_att_static_bodytok', "r'(?i)BODY'", "r'(?i)UID'")
+        if _token_ == "r'(?i)ENVELOPE'":
+            self._scan("r'(?i)ENVELOPE'")
+            SP = self._scan('SP')
+            envelope = self.envelope()
+            t = 'ENVELOPE'
+            v = envelope
+        elif _token_ == "r'(?i)INTERNALDATE'":
+            self._scan("r'(?i)INTERNALDATE'")
+            SP = self._scan('SP')
+            date_time = self.date_time()
+            t = 'INTERNALDATE'
+            v = date_time
+        elif _token_ == 'msg_att_static_tok':
+            msg_att_static_tok = self._scan('msg_att_static_tok')
+            SP = self._scan('SP')
+            nstring = self.nstring()
+            t = msg_att_static_tok
+            v=nstring
+        elif _token_ == "r'(?i)RFC822\\.SIZE'":
+            self._scan("r'(?i)RFC822\\.SIZE'")
+            SP = self._scan('SP')
+            number = self.number()
+            t = 'RFC822.SIZE'
+            v=number
+        elif _token_ == 'msg_att_static_bodytok':
+            msg_att_static_bodytok = self._scan('msg_att_static_bodytok')
+            SP = self._scan('SP')
+            body = self.body()
+            t=msg_att_static_bodytok
+            v=body
+        elif _token_ == "r'(?i)BODY'":
+            self._scan("r'(?i)BODY'")
+            t='BODYsect'
+            section = self.section()
+            v = {'section': section}
+            if self._peek('LT', 'SP') == 'LT':
+                LT = self._scan('LT')
+                number = self.number()
+                GT = self._scan('GT')
+                v['number'] = number
+            SP = self._scan('SP')
+            nstring = self.nstring()
+            v['nstring'] = nstring
+        else: # == "r'(?i)UID'"
+            self._scan("r'(?i)UID'")
+            SP = self._scan('SP')
+            uniqueid = self.uniqueid()
+            t='UID'
+            v = uniqueid
+        return {t: v}
+
+    def nil(self):
+        self._scan("r'(?i)NIL'")
+        return None
+
+    def nstring(self):
+        _token_ = self._peek("r'(?i)NIL'", '"\\""', "r'\\{'")
+        if _token_ != "r'(?i)NIL'":
+            string = self.string()
+            v = string
+        else: # == "r'(?i)NIL'"
+            nil = self.nil()
+            v = nil
+        return  v
+
+    def number(self):
+        number_tok = self._scan('number_tok')
+        return int(number_tok)
+
+    def nz_number(self):
+        nz_number_tok = self._scan('nz_number_tok')
+        return int(nz_number_tok)
+
+    def password(self):
+        astring = self.astring()
+        return astring
+
+    def quoted(self):
+        self._scan('"\\""')
+        v = ''
+        while self._peek('"\\""', 'QUOTED_CHAR_TOK', '"\\\\\\\\"') != '"\\""':
+            QUOTED_CHAR = self.QUOTED_CHAR()
+            v += QUOTED_CHAR
+        self._scan('"\\""')
+        return v
+
+    def QUOTED_CHAR(self):
+        _token_ = self._peek('QUOTED_CHAR_TOK', '"\\\\\\\\"')
+        if _token_ == 'QUOTED_CHAR_TOK':
+            QUOTED_CHAR_TOK = self._scan('QUOTED_CHAR_TOK')
+            return QUOTED_CHAR_TOK
+        else: # == '"\\\\\\\\"'
+            self._scan('"\\\\\\\\"')
+            quoted_specials = self._scan('quoted_specials')
+            return quoted_specials
+
+    def response(self):
+        v = []
+        while self._peek('PLUS', 'ASTERISK', 'TAG_ATOM_CHAR', 'resp_specials') in ['PLUS', 'ASTERISK']:
+            _token_ = self._peek('PLUS', 'ASTERISK')
+            if _token_ == 'PLUS':
+                continue_req = self.continue_req()
+                v.append(continue_req)
+            else: # == 'ASTERISK'
+                response_data = self.response_data()
+                v.append(response_data)
+        response_done = self.response_done()
+        return [response_done] + v
+
+    def response_data(self):
+        ASTERISK = self._scan('ASTERISK')
+        SP = self._scan('SP')
+        _token_ = self._peek('"(?i)FLAGS"', '"(?i)(LIST|LSUB)"', '"(?i)SEARCH"', '"(?i)STATUS"', '"(?i)CAPABILITY"', 'resp_cond_state_tok', "r'(?i)BYE'", 'number_tok', 'nz_number_tok')
+        if _token_ == 'resp_cond_state_tok':
+            resp_cond_state = self.resp_cond_state()
+            v = resp_cond_date
+        elif _token_ == "r'(?i)BYE'":
+            resp_cond_bye = self.resp_cond_bye()
+            v = resp_cond_bye
+        elif _token_ not in ['"(?i)CAPABILITY"', 'nz_number_tok']:
+            mailbox_data = self.mailbox_data()
+            v = mailbox_data
+        elif _token_ == 'nz_number_tok':
+            message_data = self.message_data()
+            v = message_data
+        else: # == '"(?i)CAPABILITY"'
+            capability_data = self.capability_data()
+            v = capability_data
+        CRLF = self._scan('CRLF')
+        return v
+
+    def response_done(self):
+        _token_ = self._peek('ASTERISK', 'TAG_ATOM_CHAR', 'resp_specials')
+        if _token_ != 'ASTERISK':
+            response_tagged = self.response_tagged()
+            v = response_tagged
+        else: # == 'ASTERISK'
+            response_fatal = self.response_fatal()
+            v = response_fatal
+        return v
+
+    def response_fatal(self):
+        ASTERISK = self._scan('ASTERISK')
+        SP = self._scan('SP')
+        resp_cond_bye = self.resp_cond_bye()
+        CRLF = self._scan('CRLF')
+        return resp_cond_bye
+
+    def response_tagged(self):
+        tag = self.tag()
+        SP = self._scan('SP')
+        resp_cond_state = self.resp_cond_state()
+        CRLF = self._scan('CRLF')
+        return {'tag': tag, 'state': resp_cond_state}
+
+    def resp_cond_auth(self):
+        resp_cond_auth_tok = self._scan('resp_cond_auth_tok')
+        SP = self._scan('SP')
+        resp_text = self.resp_text()
+        return {'result': resp_cond_auth_tok, 'detail': resp_text}
+
+    def resp_cond_bye(self):
+        self._scan("r'(?i)BYE'")
+        SP = self._scan('SP')
+        resp_text = self.resp_text()
+        return {'result': BYE, 'detail': resp_text}
+
+    def resp_cond_state(self):
+        resp_cond_state_tok = self._scan('resp_cond_state_tok')
+        SP = self._scan('SP')
+        resp_text = self.resp_text()
+        return {'result': resp_cond_state_tok, 'detail': resp_text}
+
+    def resp_text(self):
+        v = {}
+        if self._peek('LBRACKET', 'TEXT_CHAR') == 'LBRACKET':
+            LBRACKET = self._scan('LBRACKET')
+            resp_text_code = self.resp_text_code()
+            RBRACKET = self._scan('RBRACKET')
+            SP = self._scan('SP')
+            v['code'] = resp_text_code
+        text = self.text()
+        v['text'] = text
+        return v
+
+    def resp_text_code(self):
+        _token_ = self._peek("r'(?i)ALERT'", "r'(?i)BADCHARSET'", '"(?i)CAPABILITY"', "r'(?i)PARSE'", "r'(?i)PERMANENTFLAGS'", "r'(?i)READ-ONLY'", "r'(?i)READ-WRITE'", "r'(?i)TRYCREATE'", "r'(?i)UIDNEXT'", "r'(?i)UIDVALIDITY'", "r'(?i)UNSEEN'", 'ATOM_CHAR')
+        if _token_ == "r'(?i)ALERT'":
+            self._scan("r'(?i)ALERT'")
+            v = ['ALERT']
+        elif _token_ == "r'(?i)BADCHARSET'":
+            self._scan("r'(?i)BADCHARSET'")
+            v = ['BADCHARSET']
+            if self._peek('SP', 'RESP_TEXT_CHAR', 'RBRACKET') == 'SP':
+                SP = self._scan('SP')
+                LPAREN = self._scan('LPAREN')
+                astring = self.astring()
+                v.append(astring)
+                while self._peek('SP', 'RPAREN') == 'SP':
+                    SP = self._scan('SP')
+                    astring = self.astring()
+                    v.append(astring)
+                RPAREN = self._scan('RPAREN')
+        elif _token_ == '"(?i)CAPABILITY"':
+            capability_data = self.capability_data()
+            v = [capability_data]
+        elif _token_ == "r'(?i)PARSE'":
+            self._scan("r'(?i)PARSE'")
+            v = ['PARSE']
+        elif _token_ == "r'(?i)PERMANENTFLAGS'":
+            self._scan("r'(?i)PERMANENTFLAGS'")
+            SP = self._scan('SP')
+            LPAREN = self._scan('LPAREN')
+            v = ['PERMANENTFLAGS']
+            if self._peek('flag_custom_base', 'SP', 'RPAREN', 'ATOM_CHAR', 'BACKSLASH') not in ['SP', 'RPAREN']:
+                flag_perm = self.flag_perm()
+                v.append(flag_perm)
+                while self._peek('SP', 'RPAREN') == 'SP':
+                    SP = self._scan('SP')
+                    flag_perm = self.flag_perm()
+                    v.append(flag_perm)
+            RPAREN = self._scan('RPAREN')
+        elif _token_ == "r'(?i)READ-ONLY'":
+            self._scan("r'(?i)READ-ONLY'")
+            v = ['READ-ONLY']
+        elif _token_ == "r'(?i)READ-WRITE'":
+            self._scan("r'(?i)READ-WRITE'")
+            v = ['READ-WRITE']
+        elif _token_ == "r'(?i)TRYCREATE'":
+            self._scan("r'(?i)TRYCREATE'")
+            v = ['TRYCREATE']
+        elif _token_ == "r'(?i)UIDNEXT'":
+            self._scan("r'(?i)UIDNEXT'")
+            SP = self._scan('SP')
+            nz_number = self.nz_number()
+            v = ['UIDNEXT', nz_number]
+        elif _token_ == "r'(?i)UIDVALIDITY'":
+            self._scan("r'(?i)UIDVALIDITY'")
+            SP = self._scan('SP')
+            nz_number = self.nz_number()
+            v = ['UIDVALIDITY', nz_number]
+        elif _token_ == "r'(?i)UNSEEN'":
+            self._scan("r'(?i)UNSEEN'")
+            SP = self._scan('SP')
+            nz_number = self.nz_number()
+            v = ['UNSEEN', nz_number]
+        else: # == 'ATOM_CHAR'
+            atom = self.atom()
+            v = [atom]
+            if self._peek('SP', 'RESP_TEXT_CHAR', 'RBRACKET') == 'SP':
+                SP = self._scan('SP')
+                v.append('')
+                while 1:
+                    RESP_TEXT_CHAR = self._scan('RESP_TEXT_CHAR')
+                    v[1] += RESP_TEXT_CHAR
+                    if self._peek('RESP_TEXT_CHAR', 'RBRACKET') != 'RESP_TEXT_CHAR': break
+        return v
+
+    def section(self):
+        v = None
+        LBRACKET = self._scan('LBRACKET')
+        if self._peek('RBRACKET', 'section_msgtext_tok', 'nz_number_tok') != 'RBRACKET':
+            section_spec = self.section_spec()
+            v = section_spec
+        RBRACKET = self._scan('RBRACKET')
+        return v
+
+    def section_msgtext(self):
+        section_msgtext_tok = self._scan('section_msgtext_tok')
+        v = [section_msgtext_tok]
+        SP = self._scan('SP')
+        _token_ = self._peek('LPAREN', "r'(?i)TEXT'")
+        if _token_ == 'LPAREN':
+            header_list = self.header_list()
+            v.append(header_list)
+        else: # == "r'(?i)TEXT'"
+            self._scan("r'(?i)TEXT'")
+            v.append('TEXT')
+        return v
+
+    def section_part(self):
+        nz_number = self.nz_number()
+        v = str(nz_number)
+        while self._peek('PERIOD', 'RBRACKET') == 'PERIOD':
+            PERIOD = self._scan('PERIOD')
+            nz_number = self.nz_number()
+            v += '.' + str(nz_number)
+        return v
+
+    def section_spec(self):
+        _token_ = self._peek('section_msgtext_tok', 'nz_number_tok')
+        if _token_ == 'section_msgtext_tok':
+            section_msgtext = self.section_msgtext()
+            v = {'msgtext': section_msgtext}
+        else: # == 'nz_number_tok'
+            section_part = self.section_part()
+            v = {'part'}: section_part
+            if self._peek('PERIOD', 'RBRACKET') == 'PERIOD':
+                PERIOD = self._scan('PERIOD')
+                section_text = self.section_text()
+                v['text'] = section_text
+        return v
+
+    def section_text(self):
+        _token_ = self._peek('section_msgtext_tok', "r'(?i)MIME'")
+        if _token_ == 'section_msgtext_tok':
+            section_msgtext = self.section_msgtext()
+            v = section_msgtext
+        else: # == "r'(?i)MIME'"
+            self._scan("r'(?i)MIME'")
+            v = 'MIME'
+        return v
+
+    def status_att_list(self):
+        v = {}
+        status_att = self._scan('status_att')
+        SP = self._scan('SP')
+        number = self.number()
+        v[status_att] = number
+        while self._peek('SP', 'RPAREN') == 'SP':
+            SP = self._scan('SP')
+            status_att = self._scan('status_att')
+            SP = self._scan('SP')
+            number = self.number()
+            v[status_att] = number
+        return v
+
+    def string(self):
+        _token_ = self._peek('"\\""', "r'\\{'")
+        if _token_ == '"\\""':
+            quoted = self.quoted()
+            v = quoted
+        else: # == "r'\\{'"
+            literal = self.literal()
+            v = literal
+        return v
+
+    def TAG_ASTRING_CHAR(self):
+        _token_ = self._peek('TAG_ATOM_CHAR', 'resp_specials')
+        if _token_ == 'TAG_ATOM_CHAR':
+            TAG_ATOM_CHAR = self._scan('TAG_ATOM_CHAR')
+            return TAG_ATOM_CHAR
+        else: # == 'resp_specials'
+            resp_specials = self._scan('resp_specials')
+            return resp_specials
+
+    def tag(self):
+        v = ''
+        while 1:
+            TAG_ASTRING_CHAR = self.TAG_ASTRING_CHAR()
+            v += TAG_ASTRING_CHAR
+            if self._peek('TAG_ATOM_CHAR', 'resp_specials', 'SP') not in ['TAG_ATOM_CHAR', 'resp_specials']: break
+        return v
+
+    def text(self):
+        v = ''
+        while 1:
+            TEXT_CHAR = self._scan('TEXT_CHAR')
+            v += TEXT_CHAR
+            if self._peek('TEXT_CHAR', 'CRLF') != 'TEXT_CHAR': break
+        return v
+
+    def time(self):
+        self._scan('DIGITx2')
+        x = {'hours': DIGITx2}
+        self._scan('":"')
+        self._scan('DIGITx2')
+        x['minutes']= DIGITx2}
+        self._scan('":"')
+        self._scan('DIGITx2')
+        x['seconds']= DIGITx2}
+        return x
+
+    def uniqueid(self):
+        nz_number = self.nz_number()
+        return nz_number
+
+    def userid(self):
+        astring = self.astring()
+        return astring
+
+    def zone(self):
+        PLUSMINUS = self._scan('PLUSMINUS')
+        self._scan('DIGITx4')
+        return PLUSMINUS + DIGITx4
+
+
+def parse(rule, text):
+    P = IMAP(IMAPScanner(text))
+    return wrap_error_reporter(P, rule)
+
+if __name__=='__main__':
+    from sys import argv, stdin
+    if len(argv) >= 2:
+        if len(argv) >= 3:
+            f = open(argv[2],'r')
+        else:
+            f = stdin
+        print parse(argv[1], f.read())
+    else: print 'Args:  <rule> [<filename>]'

Added: imaplib/head/imap2/parser/yappsrt.py
==============================================================================
--- imaplib/head/imap2/parser/yappsrt.py	2003-07-16 18:38:03 UTC (rev 495)
+++ imaplib/head/imap2/parser/yappsrt.py	2003-07-16 18:58:20 UTC (rev 496)
@@ -0,0 +1,172 @@
+# Yapps 2.0 Runtime
+#
+# This module is needed to run generated parsers.
+
+from string import *
+import exceptions
+import re
+
+class SyntaxError(Exception):
+    """When we run into an unexpected token, this is the exception to use"""
+    def __init__(self, pos=-1, msg="Bad Token"):
+	self.pos = pos
+	self.msg = msg
+    def __repr__(self):
+	if self.pos < 0: return "#<syntax-error>"
+	else: return "SyntaxError[@ char " + `self.pos` + ": " + self.msg + "]"
+
+class NoMoreTokens(Exception):
+    """Another exception object, for when we run out of tokens"""
+    pass
+
+class Scanner:
+    def __init__(self, patterns, ignore, input):
+	"""Patterns is [(terminal,regex)...]
+        Ignore is [terminal,...];
+	Input is a string"""
+	self.tokens = []
+	self.restrictions = []
+	self.input = input
+	self.pos = 0
+	self.ignore = ignore
+	# The stored patterns are a pair (compiled regex,source
+	# regex).  If the patterns variable passed in to the
+	# constructor is None, we assume that the class already has a
+	# proper .patterns list constructed
+        if patterns is not None:
+            self.patterns = []
+            for k,r in patterns:
+                self.patterns.append( (k, re.compile(r)) )
+	
+    def token(self, i, restrict=0):
+	"""Get the i'th token, and if i is one past the end, then scan 
+	for another token; restrict is a list of tokens that
+	are allowed, or 0 for any token."""
+	if i == len(self.tokens): self.scan(restrict)
+	if i < len(self.tokens):
+	    # Make sure the restriction is more restricted
+	    if restrict and self.restrictions[i]:
+		for r in restrict:
+		    if r not in self.restrictions[i]:
+			raise "Unimplemented: restriction set changed"
+	    return self.tokens[i]
+	raise NoMoreTokens()
+    
+    def __repr__(self):
+	"""Print the last 10 tokens that have been scanned in"""
+	output = ''
+	for t in self.tokens[-10:]:
+	    output = '%s\n  (@%s)  %s  =  %s' % (output,t[0],t[2],`t[3]`)
+	return output
+    
+    def scan(self, restrict):
+	"""Should scan another token and add it to the list, self.tokens,
+	and add the restriction to self.restrictions"""
+	# Keep looking for a token, ignoring any in self.ignore
+	while 1:
+	    # Search the patterns for the longest match, with earlier
+	    # tokens in the list having preference
+	    best_match = -1
+	    best_pat = '(error)'
+	    for p, regexp in self.patterns:
+		# First check to see if we're ignoring this token
+		if restrict and p not in restrict and p not in self.ignore: 
+		    continue
+		m = regexp.match(self.input, self.pos)
+		if m and len(m.group(0)) > best_match:
+		    # We got a match that's better than the previous one
+		    best_pat = p
+		    best_match = len(m.group(0))
+		    
+	    # If we didn't find anything, raise an error
+	    if best_pat == '(error)' and best_match < 0:
+		msg = "Bad Token"
+		if restrict:
+		    msg = "Trying to find one of "+join(restrict,", ")
+		raise SyntaxError(self.pos, msg)
+
+	    # If we found something that isn't to be ignored, return it
+	    if best_pat not in self.ignore:
+		# Create a token with this data
+		token = (self.pos, self.pos+best_match, best_pat,
+			 self.input[self.pos:self.pos+best_match])
+		self.pos = self.pos + best_match
+		# Only add this token if it's not in the list
+		# (to prevent looping)
+		if not self.tokens or token != self.tokens[-1]:
+		    self.tokens.append(token)
+		    self.restrictions.append(restrict)
+		return
+	    else:
+		# This token should be ignored ..
+		self.pos = self.pos + best_match
+
+class Parser:
+    def __init__(self, scanner):
+        self._scanner = scanner
+        self._pos = 0
+        
+    def _peek(self, *types):
+        """Returns the token type for lookahead; if there are any args
+        then the list of args is the set of token types to allow"""
+        tok = self._scanner.token(self._pos, types)
+        return tok[2]
+        
+    def _scan(self, type):
+        """Returns the matched text, and moves to the next token"""
+        tok = self._scanner.token(self._pos, [type])
+        if tok[2] != type:
+            raise SyntaxError(tok[0], 'Trying to find '+type)
+        self._pos = 1+self._pos
+        return tok[3]
+
+
+
+def print_error(input, err, scanner):
+    """This is a really dumb long function to print error messages nicely."""
+    p = err.pos
+    # Figure out the line number
+    line = count(input[:p], '\n')
+    print err.msg+" on line "+`line+1`+":"
+    # Now try printing part of the line
+    text = input[max(p-80,0):p+80]
+    p = p - max(p-80,0)
+
+    # Strip to the left
+    i = rfind(text[:p],'\n')
+    j = rfind(text[:p],'\r')
+    if i < 0 or (j < i and j >= 0): i = j
+    if i >= 0 and i < p: 
+	p = p - i - 1
+	text = text[i+1:]
+
+    # Strip to the right
+    i = find(text,'\n',p)
+    j = find(text,'\r',p)
+    if i < 0 or (j < i and j >= 0): i = j
+    if i >= 0: 
+	text = text[:i]
+
+    # Now shorten the text
+    while len(text) > 70 and p > 60:
+	# Cut off 10 chars
+	text = "..." + text[10:]
+	p = p - 7
+
+    # Now print the string, along with an indicator
+    print '> ',text
+    print '> ',' '*p + '^'
+    print 'List of nearby tokens:', scanner
+
+def wrap_error_reporter(parser, rule):
+    try: return getattr(parser, rule)()
+    except SyntaxError, s:
+        input = parser._scanner.input
+        try:
+            print_error(input, s, parser._scanner)
+        except ImportError:
+            print 'Syntax Error',s.msg,'on line',1+count(input[:s.pos], '\n')
+    except NoMoreTokens:
+        print 'Could not complete parsing; stopped around here:'
+        print parser._scanner
+