Changeset 44 for branches/pyyaml3000/lib/yaml/parser.py
- Timestamp:
- 02/15/06 08:35:29 (7 years ago)
- File:
-
- 1 edited
-
branches/pyyaml3000/lib/yaml/parser.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/pyyaml3000/lib/yaml/parser.py
r43 r44 40 40 # flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } 41 41 42 from scanner import * 43 44 class Error(Exception): 45 pass 46 47 class Node: 48 def __repr__(self): 49 args = [] 50 for attribute in ['anchor', 'tag', 'value']: 51 if hasattr(self, attribute): 52 args.append(repr(getattr(self, attribute))) 53 return "%s(%s)" % (self.__class__.__name__, ', '.join(args)) 54 55 class AliasNode(Node): 56 def __init__(self, anchor): 57 self.anchor = anchor 58 59 class ScalarNode(Node): 60 def __init__(self, anchor, tag, value): 61 self.anchor = anchor 62 self.tag = tag 63 self.value = value 64 65 class SequenceNode(Node): 66 def __init__(self, anchor, tag, value): 67 self.anchor = anchor 68 self.tag = tag 69 self.value = value 70 71 class MappingNode(Node): 72 def __init__(self, anchor, tag, value): 73 self.anchor = anchor 74 self.tag = tag 75 self.value = value 76 42 77 class Parser: 43 78 44 def parse(self, source, data): 45 scanner = Scanner() 46 self.tokens = scanner.scan(source, data) 47 self.tokens.append('END') 48 documents = self.parse_stream() 49 if len(documents) == 1: 50 return documents[0] 51 return documents 79 def __init__(self, source, data): 80 self.scanner = Scanner(source, data) 81 82 def is_token(self, *choices): 83 token = self.scanner.peek_token() 84 for choice in choices: 85 if isinstance(token, choices): 86 return True 87 return False 88 89 def get_token(self): 90 return self.scanner.get_token() 91 92 def parse(self): 93 return self.parse_stream() 52 94 53 95 def parse_stream(self): 54 96 documents = [] 55 if self.tokens[0] not in ['DIRECTIVE', 'DOCUMENT_START', 'END']:97 if not self.is_token(DirectiveToken, DocumentStartToken, EndToken): 56 98 documents.append(self.parse_block_node()) 57 while self.tokens[0] != 'END': 58 while self.tokens[0] == 'DIRECTIVE': 59 self.tokens.pop(0) 60 if self.tokens[0] != 'DOCUMENT_START': 61 self.error('DOCUMENT_START is expected') 62 self.tokens.pop(0) 63 if self.tokens[0] in ['DIRECTIVE', 'DOCUMENT_START', 'DOCUMENT_END', 'END']: 99 while not self.is_token(EndToken): 100 while self.is_token(DirectiveToken): 101 self.get_token() 102 if not self.is_token(DocumentStartToken): 103 self.fail('DOCUMENT-START is expected') 104 self.get_token() 105 if self.is_token(DirectiveToken, 106 DocumentStartToken, DocumentEndToken, EndToken): 64 107 documents.append(None) 65 108 else: 66 109 documents.append(self.parse_block_node()) 67 while self. tokens[0] == 'DOCUMENT_END':68 self. tokens.pop(0)69 if self.tokens[0] != 'END':70 self. error("END is expected")71 return tuple(documents)110 while self.is_token(DocumentEndToken): 111 self.get_token() 112 if not self.is_token(EndToken): 113 self.fail("END is expected") 114 return documents 72 115 73 116 def parse_block_node(self): 74 if self.tokens[0] == 'ALIAS': 75 self.tokens.pop(0) 76 return '*' 77 if self.tokens[0] == 'TAG': 78 self.tokens.pop(0) 79 if self.tokens[0] == 'ANCHOR': 80 self.tokens.pop(0) 81 elif self.tokens[0] == 'ANCHOR': 82 self.tokens.pop(0) 83 if self.tokens[0] == 'TAG': 84 self.tokens.pop(0) 85 return self.parse_block_content() 117 return self.parse_node(block=True) 86 118 87 119 def parse_flow_node(self): 88 if self.tokens[0] == 'ALIAS': 89 self.tokens.pop(0) 90 return '*' 91 if self.tokens[0] == 'TAG': 92 self.tokens.pop(0) 93 if self.tokens[0] == 'ANCHOR': 94 self.tokens.pop(0) 95 elif self.tokens[0] == 'ANCHOR': 96 self.tokens.pop(0) 97 if self.tokens[0] == 'TAG': 98 self.tokens.pop(0) 99 return self.parse_flow_content() 120 return self.parse_node() 100 121 101 122 def parse_block_node_or_indentless_sequence(self): 102 if self.tokens[0] == 'ALIAS': 103 self.tokens.pop(0) 104 return '*' 105 if self.tokens[0] == 'TAG': 106 self.tokens.pop(0) 107 if self.tokens[0] == 'ANCHOR': 108 self.tokens.pop(0) 109 elif self.tokens[0] == 'ANCHOR': 110 self.tokens.pop(0) 111 if self.tokens[0] == 'TAG': 112 self.tokens.pop(0) 113 if self.tokens[0] == 'ENTRY': 114 return self.parse_indentless_sequence(self) 115 return self.parse_block_content() 123 return self.parse_node(block=True, indentless_sequence=True) 124 125 def parse_node(self, block=False, indentless_sequence=False): 126 if self.is_token(AliasToken): 127 token = self.get_token() 128 return AliasNode(token.value) 129 anchor = None 130 tag = None 131 if self.is_token(AnchorToken): 132 anchor = self.get_token().value 133 if self.is_token(TagToken): 134 tag = self.get_token().value 135 elif self.is_token(TagToken): 136 tag = self.get_token().value 137 if self.is_token(AnchorToken): 138 anchor = self.get_token().value 139 if indentless_sequence and self.is_token(EntryToken): 140 NodeClass = SequenceNode 141 value = self.parse_indentless_sequence() 142 else: 143 if self.is_token(ScalarToken): 144 NodeClass = ScalarNode 145 elif self.is_token(BlockSequenceStartToken, FlowSequenceStartToken): 146 NodeClass = SequenceNode 147 elif self.is_token(BlockMappingStartToken, FlowMappingStartToken): 148 NodeClass = MappingNode 149 if block: 150 value = self.parse_block_content() 151 else: 152 value = self.parse_flow_content() 153 return NodeClass(anchor, tag, value) 116 154 117 155 def parse_block_content(self): 118 if self.tokens[0] == 'SCALAR': 119 self.tokens.pop(0) 120 return True 121 elif self.tokens[0] == 'BLOCK_SEQ_START': 156 if self.is_token(ScalarToken): 157 return self.get_token().value 158 elif self.is_token(BlockSequenceStartToken): 122 159 return self.parse_block_sequence() 123 elif self. tokens[0] == 'BLOCK_MAP_START':160 elif self.is_token(BlockMappingStartToken): 124 161 return self.parse_block_mapping() 125 elif self. tokens[0] == 'FLOW_SEQ_START':162 elif self.is_token(FlowSequenceStartToken): 126 163 return self.parse_flow_sequence() 127 elif self. tokens[0] == 'FLOW_MAP_START':164 elif self.is_token(FlowMappingStartToken): 128 165 return self.parse_flow_mapping() 129 166 else: 130 self. error('block content is expected')167 self.fail('block content is expected') 131 168 132 169 def parse_flow_content(self): 133 if self.tokens[0] == 'SCALAR': 134 self.tokens.pop(0) 135 return True 136 elif self.tokens[0] == 'FLOW_SEQ_START': 170 if self.is_token(ScalarToken): 171 return self.get_token().value 172 elif self.is_token(FlowSequenceStartToken): 137 173 return self.parse_flow_sequence() 138 elif self. tokens[0] == 'FLOW_MAP_START':174 elif self.is_token(FlowMappingStartToken): 139 175 return self.parse_flow_mapping() 140 176 else: 141 self. error('flow content is expected')177 self.fail('flow content is expected') 142 178 143 179 def parse_block_sequence(self): 144 180 sequence = [] 145 if self.tokens[0] != 'BLOCK_SEQ_START':146 self. error('BLOCK_SEQ_START is expected')147 self. tokens.pop(0)148 while self. tokens[0] == 'ENTRY':149 self. tokens.pop(0)150 if self.tokens[0] not in ['ENTRY', 'BLOCK_END']:181 if not self.is_token(BlockSequenceStartToken): 182 self.fail('BLOCK-SEQUENCE-START is expected') 183 self.get_token() 184 while self.is_token(EntryToken): 185 self.get_token() 186 if not self.is_token(EntryToken, BlockEndToken): 151 187 sequence.append(self.parse_block_node()) 152 188 else: 153 189 sequence.append(None) 154 if self.tokens[0] != 'BLOCK_END':155 self. error('BLOCK_END is expected')156 self. tokens.pop(0)190 if not self.is_token(BlockEndToken): 191 self.fail('BLOCK-END is expected') 192 self.get_token() 157 193 return sequence 158 194 159 195 def parse_indentless_sequence(self): 160 196 sequence = [] 161 while self. tokens[0] == 'ENTRY':162 self. tokens.pop(0)163 if self.tokens[0] not in ['ENTRY']:197 while self.is_token(EntryToken): 198 self.get_token() 199 if not self.is_token(EntryToken): 164 200 sequence.append(self.parse_block_node()) 165 201 else: … … 169 205 def parse_block_mapping(self): 170 206 mapping = [] 171 if self.tokens[0] != 'BLOCK_MAP_START':172 self. error('BLOCK_MAP_START is expected')173 self. tokens.pop(0)174 while self. tokens[0] in ['KEY', 'VALUE']:207 if not self.is_token(BlockMappingStartToken): 208 self.fail('BLOCK-MAPPING-START is expected') 209 self.get_token() 210 while self.is_token(KeyToken, ValueToken): 175 211 key = None 176 212 value = None 177 if self. tokens[0] == 'KEY':178 self. tokens.pop(0)179 if self.tokens[0] not in ['KEY', 'VALUE', 'BLOCK_END']:213 if self.is_token(KeyToken): 214 self.get_token() 215 if not self.is_token(KeyToken, ValueToken, BlockEndToken): 180 216 key = self.parse_block_node_or_indentless_sequence() 181 if self. tokens[0] == 'VALUE':182 self. tokens.pop(0)183 if self.tokens[0] not in ['KEY', 'VALUE', 'BLOCK_END']:217 if self.is_token(ValueToken): 218 self.get_token() 219 if not self.is_token(KeyToken, ValueToken, BlockEndToken): 184 220 value = self.parse_block_node_or_indentless_sequence() 185 221 mapping.append((key, value)) 186 if self.tokens[0] != 'BLOCK_END':187 self. error('BLOCK_END is expected')188 self. tokens.pop(0)222 if not self.is_token(BlockEndToken): 223 self.fail('BLOCK-END is expected') 224 self.get_token() 189 225 return mapping 190 226 191 227 def parse_flow_sequence(self): 192 228 sequence = [] 193 if self.tokens[0] != 'FLOW_SEQ_START':194 self. error('FLOW_SEQ_START is expected')195 self. tokens.pop(0)196 while self.tokens[0] != 'FLOW_SEQ_END':197 if self. tokens[0] == 'KEY':198 self. tokens.pop(0)229 if not self.is_token(FlowSequenceStartToken): 230 self.fail('FLOW-SEQUENCE-START is expected') 231 self.get_token() 232 while not self.is_token(FlowSequenceEndToken): 233 if self.is_token(KeyToken): 234 self.get_token() 199 235 key = None 200 236 value = None 201 if self.tokens[0] != 'VALUE':237 if not self.is_token(ValueToken): 202 238 key = self.parse_flow_node() 203 if self. tokens[0] == 'VALUE':204 self. tokens.pop(0)205 if self.tokens[0] not in ['ENTRY', 'FLOW_SEQ_END']:239 if self.is_token(ValueToken): 240 self.get_token() 241 if not self.is_token(EntryToken, FlowSequenceEndToken): 206 242 value = self.parse_flow_node() 207 sequence.append([(key, value)]) 243 node = MappingNode(None, None, [(key, value)]) 244 sequence.append(node) 208 245 else: 209 246 sequence.append(self.parse_flow_node()) 210 if self.tokens[0] not in ['ENTRY', 'FLOW_SEQ_END']:211 self. error("ENTRY or FLOW_SEQ_END isexpected")212 if self. tokens[0] == 'ENTRY':213 self. tokens.pop(0)214 if self.tokens[0] != 'FLOW_SEQ_END':215 self. error('FLOW_SEQ_END is expected')216 self. tokens.pop(0)247 if not self.is_token(EntryToken, FlowSequenceEndToken): 248 self.fail("ENTRY or FLOW-SEQUENCE-END are expected") 249 if self.is_token(EntryToken): 250 self.get_token() 251 if not self.is_token(FlowSequenceEndToken): 252 self.fail('FLOW-SEQUENCE-END is expected') 253 self.get_token() 217 254 return sequence 218 255 219 256 def parse_flow_mapping(self): 220 257 mapping = [] 221 if self.tokens[0] != 'FLOW_MAP_START':222 self. error('FLOW_MAP_START is expected')223 self. tokens.pop(0)224 while self.tokens[0] != 'FLOW_MAP_END':225 if self. tokens[0] == 'KEY':226 self. tokens.pop(0)258 if not self.is_token(FlowMappingStartToken): 259 self.fail('FLOW-MAPPING-START is expected') 260 self.get_token() 261 while not self.is_token(FlowMappingEndToken): 262 if self.is_token(KeyToken): 263 self.get_token() 227 264 key = None 228 265 value = None 229 if self.tokens[0] != 'VALUE':266 if not self.is_token(ValueToken): 230 267 key = self.parse_flow_node() 231 if self. tokens[0] == 'VALUE':232 self. tokens.pop(0)233 if self.tokens[0] not in ['ENTRY', 'FLOW_MAP_END']:268 if self.is_token(ValueToken): 269 self.get_token() 270 if not self.is_token(EntryToken, FlowMappingEndToken): 234 271 value = self.parse_flow_node() 235 272 mapping.append((key, value)) 236 273 else: 237 274 mapping.append((self.parse_flow_node(), None)) 238 if self.tokens[0] not in ['ENTRY', 'FLOW_MAP_END']:239 self. error("ENTRY or FLOW_MAP_END isexpected")240 if self. tokens[0] == 'ENTRY':241 self. tokens.pop(0)242 if self.tokens[0] != 'FLOW_MAP_END':243 self. error('FLOW_MAP_END is expected')244 self. tokens.pop(0)275 if not self.is_token(EntryToken, FlowMappingEndToken): 276 self.fail("ENTRY or FLOW-MAPPING-END are expected") 277 if self.is_token(EntryToken): 278 self.get_token() 279 if not self.is_token(FlowMappingEndToken): 280 self.fail('FLOW-MAPPING-END is expected') 281 self.get_token() 245 282 return mapping 246 283 247 def error(self, message):248 raise Error(message+': '+str(self.tokens))249 250 284 def fail(self, message): 285 marker = self.scanner.peek_token().start_marker 286 raise Error(message+':\n'+marker.get_snippet()) 287
Note: See TracChangeset
for help on using the changeset viewer.
