Ignore:
Timestamp:
02/19/06 17:17:28 (9 years ago)
Author:
xi
Message:

Parser is done. Add iterator interfaces for Scanner and Parser.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pyyaml3000/tests/test_appliance.py

    r48 r51  
    11 
    22import unittest, os 
     3 
     4from yaml.tokens import * 
     5from yaml.events import * 
    36 
    47class TestAppliance(unittest.TestCase): 
     
    3336    add_tests = classmethod(add_tests) 
    3437 
    35 class Node: 
    36     def __repr__(self): 
    37         args = [] 
    38         for attribute in ['anchor', 'tag', 'value']: 
    39             if hasattr(self, attribute): 
    40                 args.append(repr(getattr(self, attribute))) 
    41         return "%s(%s)" % (self.__class__.__name__, ', '.join(args)) 
    42  
    43 class AliasNode(Node): 
    44     def __init__(self, anchor): 
    45         self.anchor = anchor 
    46  
    47 class ScalarNode(Node): 
    48     def __init__(self, anchor, tag, value): 
    49         self.anchor = anchor 
    50         self.tag = tag 
    51         self.value = value 
    52  
    53 class SequenceNode(Node): 
    54     def __init__(self, anchor, tag, value): 
    55         self.anchor = anchor 
    56         self.tag = tag 
    57         self.value = value 
    58  
    59 class MappingNode(Node): 
    60     def __init__(self, anchor, tag, value): 
    61         self.anchor = anchor 
    62         self.tag = tag 
    63         self.value = value 
    64  
    65 class Token: 
    66     def __repr__(self): 
    67         args = [] 
    68         if hasattr(self, 'value'): 
    69             args.append(repr(self.value)) 
    70         return "%s(%s)" % (self.__class__.__name__, ''.join(args)) 
    71  
    72 class StreamEndToken(Token): 
    73     pass 
    74  
    75 class DirectiveToken(Token): 
    76     pass 
    77  
    78 class DocumentStartToken(Token): 
    79     pass 
    80  
    81 class SequenceStartToken(Token): 
    82     pass 
    83  
    84 class MappingStartToken(Token): 
    85     pass 
    86  
    87 class SequenceEndToken(Token): 
    88     pass 
    89  
    90 class MappingEndToken(Token): 
    91     pass 
    92  
    93 class KeyToken(Token): 
    94     pass 
    95  
    96 class ValueToken(Token): 
    97     pass 
    98  
    99 class EntryToken(Token): 
    100     pass 
    101  
    102 class AliasToken(Token): 
    103     def __init__(self, value): 
    104         self.value = value 
    105  
    106 class AnchorToken(Token): 
    107     def __init__(self, value): 
    108         self.value = value 
    109  
    110 class TagToken(Token): 
    111     def __init__(self, value): 
    112         self.value = value 
    113  
    114 class ScalarToken(Token): 
    115     def __init__(self, value): 
    116         self.value = value 
    117  
    11838class Error(Exception): 
    11939    pass 
     
    12141class CanonicalScanner: 
    12242 
    123     def __init__(self, source, data): 
    124         self.source = source 
     43    def __init__(self, data): 
    12544        self.data = unicode(data, 'utf-8')+u'\0' 
    12645        self.index = 0 
     
    13352            ch = self.data[self.index] 
    13453            if ch == u'\0': 
    135                 tokens.append(StreamEndToken()) 
     54                tokens.append(StreamEndToken(None, None)) 
    13655                break 
    13756            elif ch == u'%': 
     
    13958            elif ch == u'-' and self.data[self.index:self.index+3] == u'---': 
    14059                self.index += 3 
    141                 tokens.append(DocumentStartToken()) 
     60                tokens.append(DocumentStartToken(None, None)) 
    14261            elif ch == u'[': 
    14362                self.index += 1 
    144                 tokens.append(SequenceStartToken()) 
     63                tokens.append(FlowSequenceStartToken(None, None)) 
    14564            elif ch == u'{': 
    14665                self.index += 1 
    147                 tokens.append(MappingStartToken()) 
     66                tokens.append(FlowMappingStartToken(None, None)) 
    14867            elif ch == u']': 
    14968                self.index += 1 
    150                 tokens.append(SequenceEndToken()) 
     69                tokens.append(FlowSequenceEndToken(None, None)) 
    15170            elif ch == u'}': 
    15271                self.index += 1 
    153                 tokens.append(MappingEndToken()) 
     72                tokens.append(FlowMappingEndToken(None, None)) 
    15473            elif ch == u'?': 
    15574                self.index += 1 
    156                 tokens.append(KeyToken()) 
     75                tokens.append(KeyToken(None, None)) 
    15776            elif ch == u':': 
    15877                self.index += 1 
    159                 tokens.append(ValueToken()) 
     78                tokens.append(ValueToken(None, None)) 
    16079            elif ch == u',': 
    16180                self.index += 1 
    162                 tokens.append(EntryToken()) 
     81                tokens.append(FlowEntryToken(None, None)) 
    16382            elif ch == u'*' or ch == u'&': 
    16483                tokens.append(self.scan_alias()) 
     
    17796                self.data[self.index+len(self.DIRECTIVE)] in u' \n\0': 
    17897            self.index += len(self.DIRECTIVE) 
    179             return DirectiveToken() 
     98            return DirectiveToken('YAML', (1, 1), None, None) 
    18099 
    181100    def scan_alias(self): 
     
    189108            self.index += 1 
    190109        value = self.data[start:self.index] 
    191         return TokenClass(value) 
     110        return TokenClass(value, None, None) 
    192111 
    193112    def scan_tag(self): 
     
    199118        if value[0] == u'!': 
    200119            value = 'tag:yaml.org,2002:'+value[1:] 
     120        elif value[0] == u'<' and value[-1] == u'>': 
     121            value = value[1:-1] 
    201122        else: 
    202             value = value[1:-1] 
    203         return TagToken(value) 
     123            value = u'!'+value 
     124        return TagToken(value, None, None) 
    204125 
    205126    QUOTE_CODES = { 
     
    265186        chunks.append(self.data[start:self.index]) 
    266187        self.index += 1 
    267         return ScalarToken(u''.join(chunks)) 
     188        return ScalarToken(u''.join(chunks), False, None, None) 
    268189 
    269190    def find_token(self): 
     
    282203class CanonicalParser: 
    283204 
    284     def __init__(self, source, data): 
    285         self.scanner = CanonicalScanner(source, data) 
     205    def __init__(self, data): 
     206        self.scanner = CanonicalScanner(data) 
     207        self.events = [] 
    286208 
    287209    # stream: document* END 
    288210    def parse_stream(self): 
    289         documents = [] 
    290211        while not self.test_token(StreamEndToken): 
    291212            if self.test_token(DirectiveToken, DocumentStartToken): 
    292                 documents.append(self.parse_document()) 
     213                self.parse_document() 
    293214            else: 
    294215                raise Error("document is expected, got "+repr(self.tokens[self.index])) 
    295         return documents 
    296  
    297     # document: DIRECTIVE? DOCUMENT-START node? 
     216        self.events.append(StreamEndEvent(None, None)) 
     217 
     218    # document: DIRECTIVE? DOCUMENT-START node 
    298219    def parse_document(self): 
    299220        node = None 
     
    301222            self.consume_token(DirectiveToken) 
    302223        self.consume_token(DocumentStartToken) 
    303         if self.test_token(TagToken, AliasToken, AnchorToken, TagToken, 
    304                 SequenceStartToken, MappingStartToken, ScalarToken): 
    305             node = self.parse_node() 
    306         return node 
     224        self.parse_node() 
    307225 
    308226    # node: ALIAS | ANCHOR? TAG? (SCALAR|sequence|mapping) 
    309227    def parse_node(self): 
    310228        if self.test_token(AliasToken): 
    311             return AliasNode(self.get_value()) 
     229            self.events.append(AliasEvent(self.get_value(), None, None)) 
    312230        else: 
    313231            anchor = None 
    314232            if self.test_token(AnchorToken): 
    315233                anchor = self.get_value() 
    316             tag = None 
     234            tag = u'!' 
    317235            if self.test_token(TagToken): 
    318236                tag = self.get_value() 
    319237            if self.test_token(ScalarToken): 
    320                 return ScalarNode(anchor, tag, self.get_value()) 
    321             elif self.test_token(SequenceStartToken): 
    322                 return SequenceNode(anchor, tag, self.parse_sequence()) 
    323             elif self.test_token(MappingStartToken): 
    324                 return MappingNode(anchor, tag, self.parse_mapping()) 
     238                self.events.append(ScalarEvent(anchor, tag, self.get_value(), None, None)) 
     239            elif self.test_token(FlowSequenceStartToken): 
     240                self.events.append(SequenceEvent(anchor, tag, None, None)) 
     241                self.parse_sequence() 
     242            elif self.test_token(FlowMappingStartToken): 
     243                self.events.append(MappingEvent(anchor, tag, None, None)) 
     244                self.parse_mapping() 
    325245            else: 
    326246                raise Error("SCALAR, '[', or '{' is expected, got "+repr(self.tokens[self.index])) 
     
    328248    # sequence: SEQUENCE-START (node (ENTRY node)*)? ENTRY? SEQUENCE-END 
    329249    def parse_sequence(self): 
    330         values = [] 
    331         self.consume_token(SequenceStartToken) 
    332         if not self.test_token(SequenceEndToken): 
    333             values.append(self.parse_node()) 
    334             while not self.test_token(SequenceEndToken): 
    335                 self.consume_token(EntryToken) 
    336                 if not self.test_token(SequenceEndToken): 
    337                     values.append(self.parse_node()) 
    338         self.consume_token(SequenceEndToken) 
    339         return values 
     250        self.consume_token(FlowSequenceStartToken) 
     251        if not self.test_token(FlowSequenceEndToken): 
     252            self.parse_node() 
     253            while not self.test_token(FlowSequenceEndToken): 
     254                self.consume_token(FlowEntryToken) 
     255                if not self.test_token(FlowSequenceEndToken): 
     256                    self.parse_node() 
     257        self.consume_token(FlowSequenceEndToken) 
     258        self.events.append(CollectionEndEvent(None, None)) 
    340259 
    341260    # mapping: MAPPING-START (map_entry (ENTRY map_entry)*)? ENTRY? MAPPING-END 
    342261    def parse_mapping(self): 
    343         values = [] 
    344         self.consume_token(MappingStartToken) 
    345         if not self.test_token(MappingEndToken): 
    346             values.append(self.parse_map_entry()) 
    347             while not self.test_token(MappingEndToken): 
    348                 self.consume_token(EntryToken) 
    349                 if not self.test_token(MappingEndToken): 
    350                     values.append(self.parse_map_entry()) 
    351         self.consume_token(MappingEndToken) 
    352         return values 
     262        self.consume_token(FlowMappingStartToken) 
     263        if not self.test_token(FlowMappingEndToken): 
     264            self.parse_map_entry() 
     265            while not self.test_token(FlowMappingEndToken): 
     266                self.consume_token(FlowEntryToken) 
     267                if not self.test_token(FlowMappingEndToken): 
     268                    self.parse_map_entry() 
     269        self.consume_token(FlowMappingEndToken) 
     270        self.events.append(CollectionEndEvent(None, None)) 
    353271 
    354272    # map_entry: KEY node VALUE node 
    355273    def parse_map_entry(self): 
    356274        self.consume_token(KeyToken) 
    357         key = self.parse_node() 
     275        self.parse_node() 
    358276        self.consume_token(ValueToken) 
    359         value = self.parse_node() 
    360         return (key, value) 
     277        self.parse_node() 
    361278 
    362279    def test_token(self, *choices): 
     
    379296        self.tokens = self.scanner.scan() 
    380297        self.index = 0 
    381         return self.parse_stream() 
    382  
     298        self.parse_stream() 
     299        return self.events 
     300 
Note: See TracChangeset for help on using the changeset viewer.