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
+