Changeset 152:989709474b5a
- Timestamp:
- 08/05/10 09:46:22 (21 months ago)
- Author:
- Menno Smits <menno@…>
- Branch:
- default
- Message:
-
Lexer cleanup done. All tests passing.
- Location:
- imapclient
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r151
|
r152
|
|
| 1 | | """A lexical analyzer class for IMAP responses.""" |
| | 1 | """ |
| | 2 | A lexical analyzer class for IMAP responses. |
| | 3 | |
| | 4 | Although Lexer does all the work, TokenSource is probably the class to |
| | 5 | use for external callers. |
| | 6 | """ |
| 2 | 7 | |
| 3 | 8 | # This was heavily inspired by (ie, ripped off from) python 2.6's shlex |
| … |
… |
|
| 9 | 14 | |
| 10 | 15 | |
| | 16 | class TokenSource(object): |
| | 17 | """ |
| | 18 | A simple iterator for the Lexer class that also provides access to |
| | 19 | the current IMAP literal. |
| | 20 | """ |
| | 21 | |
| | 22 | def __init__(self, text): |
| | 23 | lex = Lexer() |
| | 24 | lex.sources = (LiteralHandlingIter(lex, chunk) for chunk in text) |
| | 25 | self.lex = lex |
| | 26 | self.src = iter(lex) |
| | 27 | |
| | 28 | @property |
| | 29 | def current_literal(self): |
| | 30 | return self.lex.current_source.literal |
| | 31 | |
| | 32 | def __iter__(self): |
| | 33 | return self.src |
| | 34 | |
| | 35 | |
| 11 | 36 | class Lexer(object): |
| 12 | 37 | "A lexical analyzer class for IMAP" |
| … |
… |
|
| 17 | 42 | NON_SPECIALS = [ch for ch in ALL_CHARS if ch not in SPECIALS] |
| 18 | 43 | |
| 19 | | def __init__(self, sources): |
| | 44 | def __init__(self): |
| 20 | 45 | self.wordchars = set(self.NON_SPECIALS) |
| 21 | 46 | self.whitespace = set((' \t\r\n')) |
| 22 | | self.sources = (LiteralHandlingIter(self, chunk) for chunk in sources) |
| | 47 | self.sources = None |
| 23 | 48 | self.current_source = None |
| 24 | 49 | |
| … |
… |
|
| 106 | 131 | yield tok |
| 107 | 132 | |
| 108 | | @classmethod |
| 109 | | def create_token_source(cls, text): |
| 110 | | lex = cls(text) |
| 111 | | return TokenIterator(lex) |
| 112 | | |
| 113 | | |
| 114 | | class TokenIterator(object): |
| 115 | | |
| 116 | | def __init__(self, lex): |
| 117 | | self.lex = lex |
| 118 | | self.src = iter(lex) |
| 119 | | |
| 120 | | @property |
| 121 | | def current_literal(self): |
| 122 | | return self.lex.current_source.literal |
| 123 | | |
| 124 | | def __iter__(self): |
| 125 | | return self.src |
| 126 | | |
| 127 | 133 | |
| 128 | 134 | # imaplib has poor handling of 'literals' - it both fails to remove the |
| … |
… |
|
| 146 | 152 | src_text, self.literal = resp_record |
| 147 | 153 | assert src_text.endswith("}"), src_text |
| 148 | | self.src_text = self.literal |
| | 154 | self.src_text = src_text |
| 149 | 155 | else: |
| 150 | 156 | # just a line with no literals. |
-
|
r151
|
r152
|
|
| 11 | 11 | from datetime import datetime |
| 12 | 12 | from fixed_offset import FixedOffset |
| 13 | | from response_lexer import Lexer |
| | 13 | from response_lexer import TokenSource |
| 14 | 14 | |
| 15 | 15 | |
| … |
… |
|
| 32 | 32 | if not text: |
| 33 | 33 | return |
| 34 | | src = Lexer.create_token_source(text) |
| | 34 | src = TokenSource(text) |
| 35 | 35 | |
| 36 | 36 | token = None |