Ignore:
Timestamp:
07/03/06 07:29:45 (8 years ago)
Author:
xi
Message:

To make porting easier, rewrite Parser not using generators.

Fix handling of unexpected block mapping values, like

: foo

Remove obsolete and unused __iter__ functions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/lib/yaml/parser.py

    r137 r198  
    11 
    2 # YAML can be parsed by an LL(1) parser! 
     2# The following YAML grammar is LL(1) and is parsed by a recursive descent 
     3# parser. 
    34# 
    4 # We use the following production rules: 
    55# stream            ::= STREAM-START implicit_document? explicit_document* STREAM-END 
    6 # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END? 
    7 # implicit_document ::= block_node DOCUMENT-END? 
    8 # block_node    ::= ALIAS | properties? block_content 
    9 # flow_node     ::= ALIAS | properties? flow_content 
    10 # properties    ::= TAG ANCHOR? | ANCHOR TAG? 
     6# implicit_document ::= block_node DOCUMENT-END* 
     7# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 
     8# block_node_or_indentless_sequence ::= 
     9#                       ALIAS 
     10#                       | properties (block_content | indentless_block_sequence)? 
     11#                       | block_content 
     12#                       | indentless_block_sequence 
     13# block_node        ::= ALIAS 
     14#                       | properties block_content? 
     15#                       | block_content 
     16# flow_node         ::= ALIAS 
     17#                       | properties flow_content? 
     18#                       | flow_content 
     19# properties        ::= TAG ANCHOR? | ANCHOR TAG? 
    1120# block_content     ::= block_collection | flow_collection | SCALAR 
    1221# flow_content      ::= flow_collection | SCALAR 
    1322# block_collection  ::= block_sequence | block_mapping 
     23# flow_collection   ::= flow_sequence | flow_mapping 
    1424# block_sequence    ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 
    15 # block_mapping     ::= BLOCK-MAPPING_START ((KEY block_node_or_indentless_sequence?)? (VALUE block_node_or_indentless_sequence?)?)* BLOCK-END 
    16 # block_node_or_indentless_sequence ::= ALIAS | properties? (block_content | indentless_block_sequence) 
    17 # indentless_block_sequence         ::= (BLOCK-ENTRY block_node?)+ 
    18 # flow_collection   ::= flow_sequence | flow_mapping 
    19 # flow_sequence     ::= FLOW-SEQUENCE-START (flow_sequence_entry FLOW-ENTRY)* flow_sequence_entry? FLOW-SEQUENCE-END 
    20 # flow_mapping      ::= FLOW-MAPPING-START (flow_mapping_entry FLOW-ENTRY)* flow_mapping_entry? FLOW-MAPPING-END 
     25# indentless_sequence   ::= (BLOCK-ENTRY block_node?)+ 
     26# block_mapping     ::= BLOCK-MAPPING_START 
     27#                       ((KEY block_node_or_indentless_sequence?)? 
     28#                       (VALUE block_node_or_indentless_sequence?)?)* 
     29#                       BLOCK-END 
     30# flow_sequence     ::= FLOW-SEQUENCE-START 
     31#                       (flow_sequence_entry FLOW-ENTRY)* 
     32#                       flow_sequence_entry? 
     33#                       FLOW-SEQUENCE-END 
    2134# flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)? 
     35# flow_mapping      ::= FLOW-MAPPING-START 
     36#                       (flow_mapping_entry FLOW-ENTRY)* 
     37#                       flow_mapping_entry? 
     38#                       FLOW-MAPPING-END 
    2239# flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)? 
    23  
    24 # TODO: support for BOM within a stream. 
    25 # stream ::= (BOM? implicit_document)? (BOM? explicit_document)* STREAM-END 
    26  
     40# 
    2741# FIRST sets: 
     42# 
    2843# stream: { STREAM-START } 
    2944# explicit_document: { DIRECTIVE DOCUMENT-START } 
     
    7085        self.yaml_version = None 
    7186        self.tag_handles = {} 
    72         self.event_generator = self.parse_stream() 
     87        self.states = [] 
     88        self.marks = [] 
     89        self.state = self.parse_stream_start 
    7390 
    7491    def check_event(self, *choices): 
    7592        # Check the type of the next event. 
    7693        if self.current_event is None: 
    77             try: 
    78                 self.current_event = self.event_generator.next() 
    79             except StopIteration: 
    80                 pass 
     94            if self.state: 
     95                self.current_event = self.state() 
    8196        if self.current_event is not None: 
    8297            if not choices: 
     
    90105        # Get the next event. 
    91106        if self.current_event is None: 
    92             try: 
    93                 self.current_event = self.event_generator.next() 
    94             except StopIteration: 
    95                 pass 
     107            if self.state: 
     108                self.current_event = self.state() 
    96109        return self.current_event 
    97110 
    98111    def get_event(self): 
    99         # Get the next event. 
     112        # Get the next event and proceed further. 
    100113        if self.current_event is None: 
    101             try: 
    102                 self.current_event = self.event_generator.next() 
    103             except StopIteration: 
    104                 pass 
     114            if self.state: 
     115                self.current_event = self.state() 
    105116        value = self.current_event 
    106117        self.current_event = None 
    107118        return value 
    108119 
    109     def __iter__(self): 
    110         # Iterator protocol. 
    111         return self.event_generator 
    112  
    113     def parse_stream(self): 
    114         # STREAM-START implicit_document? explicit_document* STREAM-END 
    115  
    116         # Parse start of stream. 
    117         token = self.get_token() 
    118         yield StreamStartEvent(token.start_mark, token.end_mark, 
     120    # stream    ::= STREAM-START implicit_document? explicit_document* STREAM-END 
     121    # implicit_document ::= block_node DOCUMENT-END* 
     122    # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 
     123 
     124    def parse_stream_start(self): 
     125 
     126        # Parse the stream start. 
     127        token = self.get_token() 
     128        event = StreamStartEvent(token.start_mark, token.end_mark, 
    119129                encoding=token.encoding) 
    120130 
    121         # Parse implicit document. 
     131        # Prepare the next state. 
     132        self.state = self.parse_implicit_document_start 
     133 
     134        return event 
     135 
     136    def parse_implicit_document_start(self): 
     137 
     138        # Parse an implicit document. 
    122139        if not self.check_token(DirectiveToken, DocumentStartToken, 
    123140                StreamEndToken): 
     
    125142            token = self.peek_token() 
    126143            start_mark = end_mark = token.start_mark 
    127             yield DocumentStartEvent(start_mark, end_mark, 
     144            event = DocumentStartEvent(start_mark, end_mark, 
    128145                    explicit=False) 
    129             for event in self.parse_block_node(): 
    130                 yield event 
    131             token = self.peek_token() 
    132             start_mark = end_mark = token.start_mark 
    133             explicit = False 
    134             while self.check_token(DocumentEndToken): 
    135                 token = self.get_token() 
    136                 end_mark = token.end_mark 
    137                 explicit = True 
    138             yield DocumentEndEvent(start_mark, end_mark, 
    139                     explicit=explicit) 
    140  
    141         # Parse explicit documents. 
    142         while not self.check_token(StreamEndToken): 
     146 
     147            # Prepare the next state. 
     148            self.states.append(self.parse_document_end) 
     149            self.state = self.parse_block_node 
     150 
     151            return event 
     152 
     153        else: 
     154            return self.parse_document_start() 
     155 
     156    def parse_document_start(self): 
     157 
     158        # Parse an explicit document. 
     159        if not self.check_token(StreamEndToken): 
    143160            token = self.peek_token() 
    144161            start_mark = token.start_mark 
     
    151168            token = self.get_token() 
    152169            end_mark = token.end_mark 
    153             yield DocumentStartEvent(start_mark, end_mark, 
     170            event = DocumentStartEvent(start_mark, end_mark, 
    154171                    explicit=True, version=version, tags=tags) 
    155             if self.check_token(DirectiveToken, 
    156                     DocumentStartToken, DocumentEndToken, StreamEndToken): 
    157                 yield self.process_empty_scalar(token.end_mark) 
    158             else: 
    159                 for event in self.parse_block_node(): 
    160                     yield event 
    161             token = self.peek_token() 
    162             start_mark = end_mark = token.start_mark 
    163             explicit = False 
    164             while self.check_token(DocumentEndToken): 
    165                 token = self.get_token() 
    166                 end_mark = token.end_mark 
    167                 explicit=True 
    168             yield DocumentEndEvent(start_mark, end_mark, 
    169                     explicit=explicit) 
    170  
    171         # Parse end of stream. 
    172         token = self.get_token() 
    173         yield StreamEndEvent(token.start_mark, token.end_mark) 
     172            self.states.append(self.parse_document_end) 
     173            self.state = self.parse_document_content 
     174        else: 
     175            # Parse the end of the stream. 
     176            token = self.get_token() 
     177            event = StreamEndEvent(token.start_mark, token.end_mark) 
     178            assert not self.states 
     179            assert not self.marks 
     180            self.state = None 
     181        return event 
     182 
     183    def parse_document_end(self): 
     184 
     185        # Parse the document end. 
     186        token = self.peek_token() 
     187        start_mark = end_mark = token.start_mark 
     188        explicit = False 
     189        while self.check_token(DocumentEndToken): 
     190            token = self.get_token() 
     191            end_mark = token.end_mark 
     192            explicit = True 
     193        event = DocumentEndEvent(start_mark, end_mark, 
     194                explicit=explicit) 
     195 
     196        # Prepare the next state. 
     197        self.state = self.parse_document_start 
     198 
     199        return event 
     200 
     201    def parse_document_content(self): 
     202        if self.check_token(DirectiveToken, 
     203                DocumentStartToken, DocumentEndToken, StreamEndToken): 
     204            event = self.process_empty_scalar(self.peek_token().start_mark) 
     205            self.state = self.states.pop() 
     206            return event 
     207        else: 
     208            return self.parse_block_node() 
    174209 
    175210    def process_directives(self): 
    176         # DIRECTIVE* 
    177211        self.yaml_version = None 
    178212        self.tag_handles = {} 
     
    205239        return value 
    206240 
     241    # block_node_or_indentless_sequence ::= ALIAS 
     242    #               | properties (block_content | indentless_block_sequence)? 
     243    #               | block_content 
     244    #               | indentless_block_sequence 
     245    # block_node    ::= ALIAS 
     246    #                   | properties block_content? 
     247    #                   | block_content 
     248    # flow_node     ::= ALIAS 
     249    #                   | properties flow_content? 
     250    #                   | flow_content 
     251    # properties    ::= TAG ANCHOR? | ANCHOR TAG? 
     252    # block_content     ::= block_collection | flow_collection | SCALAR 
     253    # flow_content      ::= flow_collection | SCALAR 
     254    # block_collection  ::= block_sequence | block_mapping 
     255    # flow_collection   ::= flow_sequence | flow_mapping 
     256 
    207257    def parse_block_node(self): 
    208258        return self.parse_node(block=True) 
     
    215265 
    216266    def parse_node(self, block=False, indentless_sequence=False): 
    217         # block_node    ::= ALIAS | properties? block_content 
    218         # flow_node     ::= ALIAS | properties? flow_content 
    219         # properties    ::= TAG ANCHOR? | ANCHOR TAG? 
    220         # block_content     ::= block_collection | flow_collection | SCALAR 
    221         # flow_content      ::= flow_collection | SCALAR 
    222         # block_collection  ::= block_sequence | block_mapping 
    223         # block_node_or_indentless_sequence ::= ALIAS | properties? 
    224         #                                       (block_content | indentless_block_sequence) 
    225267        if self.check_token(AliasToken): 
    226268            token = self.get_token() 
    227             yield AliasEvent(token.value, token.start_mark, token.end_mark) 
     269            event = AliasEvent(token.value, token.start_mark, token.end_mark) 
     270            self.state = self.states.pop() 
    228271        else: 
    229272            anchor = None 
     
    272315                event = SequenceStartEvent(anchor, tag, implicit, 
    273316                        start_mark, end_mark) 
    274                 collection_events = self.parse_indentless_sequence() 
     317                self.state = self.parse_indentless_sequence_entry 
    275318            else: 
    276319                if self.check_token(ScalarToken): 
     
    285328                    event = ScalarEvent(anchor, tag, implicit, token.value, 
    286329                            start_mark, end_mark, style=token.style) 
     330                    self.state = self.states.pop() 
    287331                elif self.check_token(FlowSequenceStartToken): 
    288332                    end_mark = self.peek_token().end_mark 
    289333                    event = SequenceStartEvent(anchor, tag, implicit, 
    290334                            start_mark, end_mark, flow_style=True) 
    291                     collection_events = self.parse_flow_sequence() 
     335                    self.state = self.parse_flow_sequence_first_entry 
    292336                elif self.check_token(FlowMappingStartToken): 
    293337                    end_mark = self.peek_token().end_mark 
    294338                    event = MappingStartEvent(anchor, tag, implicit, 
    295339                            start_mark, end_mark, flow_style=True) 
    296                     collection_events = self.parse_flow_mapping() 
     340                    self.state = self.parse_flow_mapping_first_key 
    297341                elif block and self.check_token(BlockSequenceStartToken): 
    298342                    end_mark = self.peek_token().start_mark 
    299343                    event = SequenceStartEvent(anchor, tag, implicit, 
    300344                            start_mark, end_mark, flow_style=False) 
    301                     collection_events = self.parse_block_sequence() 
     345                    self.state = self.parse_block_sequence_first_entry 
    302346                elif block and self.check_token(BlockMappingStartToken): 
    303347                    end_mark = self.peek_token().start_mark 
    304348                    event = MappingStartEvent(anchor, tag, implicit, 
    305349                            start_mark, end_mark, flow_style=False) 
    306                     collection_events = self.parse_block_mapping() 
     350                    self.state = self.parse_block_mapping_first_key 
    307351                elif anchor is not None or tag is not None: 
    308352                    # Empty scalars are allowed even if a tag or an anchor is 
     
    310354                    event = ScalarEvent(anchor, tag, (implicit, False), u'', 
    311355                            start_mark, end_mark) 
     356                    self.state = self.states.pop() 
    312357                else: 
    313358                    if block: 
     
    319364                            "expected the node content, but found %r" % token.id, 
    320365                            token.start_mark) 
    321             yield event 
    322             if collection_events is not None: 
    323                 for event in collection_events: 
    324                     yield event 
    325  
    326     def parse_block_sequence(self): 
    327         # BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 
    328         token = self.get_token() 
    329         start_mark = token.start_mark 
    330         while self.check_token(BlockEntryToken): 
     366        return event 
     367 
     368    # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 
     369 
     370    def parse_block_sequence_first_entry(self): 
     371        token = self.get_token() 
     372        self.marks.append(token.start_mark) 
     373        return self.parse_block_sequence_entry() 
     374 
     375    def parse_block_sequence_entry(self): 
     376        if self.check_token(BlockEntryToken): 
    331377            token = self.get_token() 
    332378            if not self.check_token(BlockEntryToken, BlockEndToken): 
    333                 for event in self.parse_block_node(): 
    334                     yield event 
    335             else: 
    336                 yield self.process_empty_scalar(token.end_mark) 
     379                self.states.append(self.parse_block_sequence_entry) 
     380                return self.parse_block_node() 
     381            else: 
     382                self.state = self.parse_block_sequence_entry 
     383                return self.process_empty_scalar(token.end_mark) 
    337384        if not self.check_token(BlockEndToken): 
    338385            token = self.peek_token() 
    339             raise ParserError("while scanning a block collection", start_mark, 
     386            raise ParserError("while scanning a block collection", self.marks[-1], 
    340387                    "expected <block end>, but found %r" % token.id, token.start_mark) 
    341388        token = self.get_token() 
    342         yield SequenceEndEvent(token.start_mark, token.end_mark) 
    343  
    344     def parse_indentless_sequence(self): 
    345         # (BLOCK-ENTRY block_node?)+ 
    346         while self.check_token(BlockEntryToken): 
     389        event = SequenceEndEvent(token.start_mark, token.end_mark) 
     390        self.state = self.states.pop() 
     391        self.marks.pop() 
     392        return event 
     393 
     394    # indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 
     395 
     396    def parse_indentless_sequence_entry(self): 
     397        if self.check_token(BlockEntryToken): 
    347398            token = self.get_token() 
    348399            if not self.check_token(BlockEntryToken, 
    349400                    KeyToken, ValueToken, BlockEndToken): 
    350                 for event in self.parse_block_node(): 
    351                     yield event 
    352             else: 
    353                 yield self.process_empty_scalar(token.end_mark) 
     401                self.states.append(self.parse_indentless_sequence_entry) 
     402                return self.parse_block_node() 
     403            else: 
     404                self.state = self.parse_indentless_sequence_entry 
     405                return self.process_empty_scalar(token.end_mark) 
    354406        token = self.peek_token() 
    355         yield SequenceEndEvent(token.start_mark, token.start_mark) 
    356  
    357     def parse_block_mapping(self): 
    358         # BLOCK-MAPPING_START 
    359         #   ((KEY block_node_or_indentless_sequence?)? 
    360         #   (VALUE block_node_or_indentless_sequence?)?)* 
    361         # BLOCK-END 
    362         token = self.get_token() 
    363         start_mark = token.start_mark 
    364         while self.check_token(KeyToken, ValueToken): 
     407        event = SequenceEndEvent(token.start_mark, token.start_mark) 
     408        self.state = self.states.pop() 
     409        return event 
     410 
     411    # block_mapping     ::= BLOCK-MAPPING_START 
     412    #                       ((KEY block_node_or_indentless_sequence?)? 
     413    #                       (VALUE block_node_or_indentless_sequence?)?)* 
     414    #                       BLOCK-END 
     415 
     416    def parse_block_mapping_first_key(self): 
     417        token = self.get_token() 
     418        self.marks.append(token.start_mark) 
     419        return self.parse_block_mapping_key() 
     420 
     421    def parse_block_mapping_key(self): 
     422        if self.check_token(KeyToken): 
     423            token = self.get_token() 
     424            if not self.check_token(KeyToken, ValueToken, BlockEndToken): 
     425                self.states.append(self.parse_block_mapping_value) 
     426                return self.parse_block_node_or_indentless_sequence() 
     427            else: 
     428                self.state = self.parse_block_mapping_value 
     429                return self.process_empty_scalar(token.end_mark) 
     430        if not self.check_token(BlockEndToken): 
     431            token = self.peek_token() 
     432            raise ParserError("while scanning a block mapping", self.marks[-1], 
     433                    "expected <block end>, but found %r" % token.id, token.start_mark) 
     434        token = self.get_token() 
     435        event = MappingEndEvent(token.start_mark, token.end_mark) 
     436        self.state = self.states.pop() 
     437        self.marks.pop() 
     438        return event 
     439 
     440    def parse_block_mapping_value(self): 
     441        if self.check_token(ValueToken): 
     442            token = self.get_token() 
     443            if not self.check_token(KeyToken, ValueToken, BlockEndToken): 
     444                self.states.append(self.parse_block_mapping_key) 
     445                return self.parse_block_node_or_indentless_sequence() 
     446            else: 
     447                self.state = self.parse_block_mapping_key 
     448                return self.process_empty_scalar(token.end_mark) 
     449        else: 
     450            self.state = self.parse_block_mapping_key 
     451            token = self.peek_token() 
     452            return self.process_empty_scalar(token.start_mark) 
     453 
     454    # flow_sequence     ::= FLOW-SEQUENCE-START 
     455    #                       (flow_sequence_entry FLOW-ENTRY)* 
     456    #                       flow_sequence_entry? 
     457    #                       FLOW-SEQUENCE-END 
     458    # flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)? 
     459    # 
     460    # Note that while production rules for both flow_sequence_entry and 
     461    # flow_mapping_entry are equal, their interpretations are different. 
     462    # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?` 
     463    # generate an inline mapping (set syntax). 
     464 
     465    def parse_flow_sequence_first_entry(self): 
     466        token = self.get_token() 
     467        self.marks.append(token.start_mark) 
     468        return self.parse_flow_sequence_entry(first=True) 
     469 
     470    def parse_flow_sequence_entry(self, first=False): 
     471        if not self.check_token(FlowSequenceEndToken): 
     472            if not first: 
     473                if self.check_token(FlowEntryToken): 
     474                    self.get_token() 
     475                else: 
     476                    token = self.peek_token() 
     477                    raise ParserError("while scanning a flow sequence", self.marks[-1], 
     478                            "expected ',' or ']', but got %r" % token.id, token.start_mark) 
     479             
    365480            if self.check_token(KeyToken): 
    366481                token = self.get_token() 
    367                 if not self.check_token(KeyToken, ValueToken, BlockEndToken): 
    368                     for event in self.parse_block_node_or_indentless_sequence(): 
    369                         yield event 
    370                 else: 
    371                     yield self.process_empty_scalar(token.end_mark) 
    372             if self.check_token(ValueToken): 
    373                 token = self.get_token() 
    374                 if not self.check_token(KeyToken, ValueToken, BlockEndToken): 
    375                     for event in self.parse_block_node_or_indentless_sequence(): 
    376                         yield event 
    377                 else: 
    378                     yield self.process_empty_scalar(token.end_mark) 
    379             else: 
    380                 token = self.peek_token() 
    381                 yield self.process_empty_scalar(token.start_mark) 
    382         if not self.check_token(BlockEndToken): 
    383             token = self.peek_token() 
    384             raise ParserError("while scanning a block mapping", start_mark, 
    385                     "expected <block end>, but found %r" % token.id, token.start_mark) 
    386         token = self.get_token() 
    387         yield MappingEndEvent(token.start_mark, token.end_mark) 
    388  
    389     def parse_flow_sequence(self): 
    390         # flow_sequence     ::= FLOW-SEQUENCE-START 
    391         #                       (flow_sequence_entry FLOW-ENTRY)* 
    392         #                       flow_sequence_entry? 
    393         #                       FLOW-SEQUENCE-END 
    394         # flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)? 
    395         # 
    396         # Note that while production rules for both flow_sequence_entry and 
    397         # flow_mapping_entry are equal, their interpretations are different. 
    398         # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?` 
    399         # generate an inline mapping (set syntax). 
    400         token = self.get_token() 
    401         start_mark = token.start_mark 
    402         while not self.check_token(FlowSequenceEndToken): 
    403             if self.check_token(KeyToken): 
    404                 token = self.get_token() 
    405                 yield MappingStartEvent(None, None, True, 
     482                event = MappingStartEvent(None, None, True, 
    406483                        token.start_mark, token.end_mark, 
    407484                        flow_style=True) 
    408                 if not self.check_token(ValueToken, 
    409                         FlowEntryToken, FlowSequenceEndToken): 
    410                     for event in self.parse_flow_node(): 
    411                         yield event 
    412                 else: 
    413                     yield self.process_empty_scalar(token.end_mark) 
    414                 if self.check_token(ValueToken): 
    415                     token = self.get_token() 
    416                     if not self.check_token(FlowEntryToken, FlowSequenceEndToken): 
    417                         for event in self.parse_flow_node(): 
    418                             yield event 
    419                     else: 
    420                         yield self.process_empty_scalar(token.end_mark) 
     485                self.state = self.parse_flow_sequence_entry_mapping_key 
     486                return event 
     487            elif not self.check_token(FlowSequenceEndToken): 
     488                self.states.append(self.parse_flow_sequence_entry) 
     489                return self.parse_flow_node() 
     490        token = self.get_token() 
     491        event = SequenceEndEvent(token.start_mark, token.end_mark) 
     492        self.state = self.states.pop() 
     493        self.marks.pop() 
     494        return event 
     495 
     496    def parse_flow_sequence_entry_mapping_key(self): 
     497        if not self.check_token(ValueToken, 
     498                FlowEntryToken, FlowSequenceEndToken): 
     499            self.states.append(self.parse_flow_sequence_entry_mapping_value) 
     500            return self.parse_flow_node() 
     501        else: 
     502            self.state = self.parse_flow_sequence_entry_mapping_value 
     503            return self.process_empty_scalar(token.end_mark) 
     504 
     505    def parse_flow_sequence_entry_mapping_value(self): 
     506        if self.check_token(ValueToken): 
     507            token = self.get_token() 
     508            if not self.check_token(FlowEntryToken, FlowSequenceEndToken): 
     509                self.states.append(self.parse_flow_sequence_entry_mapping_end) 
     510                return self.parse_flow_node() 
     511            else: 
     512                self.state = self.parse_flow_sequence_entry_mapping_end 
     513                return self.process_empty_scalar(token.end_mark) 
     514        else: 
     515            self.state = self.parse_flow_sequence_entry_mapping_end 
     516            token = self.peek_token() 
     517            return self.process_empty_scalar(token.start_mark) 
     518 
     519    def parse_flow_sequence_entry_mapping_end(self): 
     520        self.state = self.parse_flow_sequence_entry 
     521        token = self.peek_token() 
     522        return MappingEndEvent(token.start_mark, token.start_mark) 
     523 
     524    # flow_mapping  ::= FLOW-MAPPING-START 
     525    #                   (flow_mapping_entry FLOW-ENTRY)* 
     526    #                   flow_mapping_entry? 
     527    #                   FLOW-MAPPING-END 
     528    # flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)? 
     529 
     530    def parse_flow_mapping_first_key(self): 
     531        token = self.get_token() 
     532        self.marks.append(token.start_mark) 
     533        return self.parse_flow_mapping_key(first=True) 
     534 
     535    def parse_flow_mapping_key(self, first=False): 
     536        if not self.check_token(FlowMappingEndToken): 
     537            if not first: 
     538                if self.check_token(FlowEntryToken): 
     539                    self.get_token() 
    421540                else: 
    422541                    token = self.peek_token() 
    423                     yield self.process_empty_scalar(token.start_mark) 
    424                 token = self.peek_token() 
    425                 yield MappingEndEvent(token.start_mark, token.start_mark) 
    426             else: 
    427                 for event in self.parse_flow_node(): 
    428                     yield event 
    429             if not self.check_token(FlowEntryToken, FlowSequenceEndToken): 
    430                 token = self.peek_token() 
    431                 raise ParserError("while scanning a flow sequence", start_mark, 
    432                         "expected ',' or ']', but got %r" % token.id, token.start_mark) 
    433             if self.check_token(FlowEntryToken): 
    434                 self.get_token() 
    435         token = self.get_token() 
    436         yield SequenceEndEvent(token.start_mark, token.end_mark) 
    437  
    438     def parse_flow_mapping(self): 
    439         # flow_mapping      ::= FLOW-MAPPING-START 
    440         #                       (flow_mapping_entry FLOW-ENTRY)* 
    441         #                       flow_mapping_entry? 
    442         #                       FLOW-MAPPING-END 
    443         # flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)? 
    444         token = self.get_token() 
    445         start_mark = token.start_mark 
    446         while not self.check_token(FlowMappingEndToken): 
     542                    raise ParserError("while scanning a flow mapping", self.marks[-1], 
     543                            "expected ',' or '}', but got %r" % token.id, token.start_mark) 
    447544            if self.check_token(KeyToken): 
    448545                token = self.get_token() 
    449546                if not self.check_token(ValueToken, 
    450547                        FlowEntryToken, FlowMappingEndToken): 
    451                     for event in self.parse_flow_node(): 
    452                         yield event 
     548                    self.states.append(self.parse_flow_mapping_value) 
     549                    return self.parse_flow_node() 
    453550                else: 
    454                     yield self.process_empty_scalar(token.end_mark) 
    455                 if self.check_token(ValueToken): 
    456                     token = self.get_token() 
    457                     if not self.check_token(FlowEntryToken, FlowMappingEndToken): 
    458                         for event in self.parse_flow_node(): 
    459                             yield event 
    460                     else: 
    461                         yield self.process_empty_scalar(token.end_mark) 
    462                 else: 
    463                     token = self.peek_token() 
    464                     yield self.process_empty_scalar(token.start_mark) 
    465             else: 
    466                 for event in self.parse_flow_node(): 
    467                     yield event 
    468                 yield self.process_empty_scalar(self.peek_token().start_mark) 
     551                    self.state = self.parse_flow_mapping_value 
     552                    return self.process_empty_scalar(token.end_mark) 
     553            elif not self.check_token(FlowMappingEndToken): 
     554                self.states.append(self.parse_flow_mapping_empty_value) 
     555                return self.parse_flow_node() 
     556        token = self.get_token() 
     557        event = MappingEndEvent(token.start_mark, token.end_mark) 
     558        self.state = self.states.pop() 
     559        self.marks.pop() 
     560        return event 
     561 
     562    def parse_flow_mapping_value(self): 
     563        if self.check_token(ValueToken): 
     564            token = self.get_token() 
    469565            if not self.check_token(FlowEntryToken, FlowMappingEndToken): 
    470                 token = self.peek_token() 
    471                 raise ParserError("while scanning a flow mapping", start_mark, 
    472                         "expected ',' or '}', but got %r" % token.id, token.start_mark) 
    473             if self.check_token(FlowEntryToken): 
    474                 self.get_token() 
    475         if not self.check_token(FlowMappingEndToken): 
    476             token = self.peek_token() 
    477             raise ParserError("while scanning a flow mapping", start_mark, 
    478                     "expected '}', but found %r" % token.id, token.start_mark) 
    479         token = self.get_token() 
    480         yield MappingEndEvent(token.start_mark, token.end_mark) 
     566                self.states.append(self.parse_flow_mapping_key) 
     567                return self.parse_flow_node() 
     568            else: 
     569                self.state = self.parse_flow_mapping_key 
     570                return self.process_empty_scalar(token.end_mark) 
     571        else: 
     572            self.state = self.parse_flow_mapping_key 
     573            token = self.peek_token() 
     574            return self.process_empty_scalar(token.start_mark) 
     575 
     576    def parse_flow_mapping_empty_value(self): 
     577        self.state = self.parse_flow_mapping_key 
     578        return self.process_empty_scalar(self.peek_token().start_mark) 
    481579 
    482580    def process_empty_scalar(self, mark): 
Note: See TracChangeset for help on using the changeset viewer.