Ignore:
Timestamp:
02/15/06 08:35:29 (8 years ago)
Author:
xi
Message:

All tests passed! Scanner and Parser seem to be correct.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pyyaml3000/lib/yaml/parser.py

    r43 r44  
    4040# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } 
    4141 
     42from scanner import * 
     43 
     44class Error(Exception): 
     45    pass 
     46 
     47class 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 
     55class AliasNode(Node): 
     56    def __init__(self, anchor): 
     57        self.anchor = anchor 
     58 
     59class ScalarNode(Node): 
     60    def __init__(self, anchor, tag, value): 
     61        self.anchor = anchor 
     62        self.tag = tag 
     63        self.value = value 
     64 
     65class SequenceNode(Node): 
     66    def __init__(self, anchor, tag, value): 
     67        self.anchor = anchor 
     68        self.tag = tag 
     69        self.value = value 
     70 
     71class MappingNode(Node): 
     72    def __init__(self, anchor, tag, value): 
     73        self.anchor = anchor 
     74        self.tag = tag 
     75        self.value = value 
     76 
    4277class Parser: 
    4378 
    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() 
    5294 
    5395    def parse_stream(self): 
    5496        documents = [] 
    55         if self.tokens[0] not in ['DIRECTIVE', 'DOCUMENT_START', 'END']: 
     97        if not self.is_token(DirectiveToken, DocumentStartToken, EndToken): 
    5698            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): 
    64107                documents.append(None) 
    65108            else: 
    66109                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 
    72115 
    73116    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) 
    86118 
    87119    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() 
    100121 
    101122    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) 
    116154 
    117155    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): 
    122159            return self.parse_block_sequence() 
    123         elif self.tokens[0] == 'BLOCK_MAP_START': 
     160        elif self.is_token(BlockMappingStartToken): 
    124161            return self.parse_block_mapping() 
    125         elif self.tokens[0] == 'FLOW_SEQ_START': 
     162        elif self.is_token(FlowSequenceStartToken): 
    126163            return self.parse_flow_sequence() 
    127         elif self.tokens[0] == 'FLOW_MAP_START': 
     164        elif self.is_token(FlowMappingStartToken): 
    128165            return self.parse_flow_mapping() 
    129166        else: 
    130             self.error('block content is expected') 
     167            self.fail('block content is expected') 
    131168 
    132169    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): 
    137173            return self.parse_flow_sequence() 
    138         elif self.tokens[0] == 'FLOW_MAP_START': 
     174        elif self.is_token(FlowMappingStartToken): 
    139175            return self.parse_flow_mapping() 
    140176        else: 
    141             self.error('flow content is expected') 
     177            self.fail('flow content is expected') 
    142178 
    143179    def parse_block_sequence(self): 
    144180        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): 
    151187                sequence.append(self.parse_block_node()) 
    152188            else: 
    153189                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() 
    157193        return sequence 
    158194 
    159195    def parse_indentless_sequence(self): 
    160196        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): 
    164200                sequence.append(self.parse_block_node()) 
    165201            else: 
     
    169205    def parse_block_mapping(self): 
    170206        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): 
    175211            key = None 
    176212            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): 
    180216                    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): 
    184220                    value = self.parse_block_node_or_indentless_sequence() 
    185221            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() 
    189225        return mapping 
    190226 
    191227    def parse_flow_sequence(self): 
    192228        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() 
    199235                key = None 
    200236                value = None 
    201                 if self.tokens[0] != 'VALUE': 
     237                if not self.is_token(ValueToken): 
    202238                    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): 
    206242                        value = self.parse_flow_node() 
    207                 sequence.append([(key, value)]) 
     243                node = MappingNode(None, None, [(key, value)]) 
     244                sequence.append(node) 
    208245            else: 
    209246                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 is expected") 
    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() 
    217254        return sequence 
    218255 
    219256    def parse_flow_mapping(self): 
    220257        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() 
    227264                key = None 
    228265                value = None 
    229                 if self.tokens[0] != 'VALUE': 
     266                if not self.is_token(ValueToken): 
    230267                    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): 
    234271                        value = self.parse_flow_node() 
    235272                mapping.append((key, value)) 
    236273            else: 
    237274                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 is expected") 
    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() 
    245282        return mapping 
    246283 
    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.