Changeset 127


Ignore:
Timestamp:
03/26/06 17:57:23 (9 years ago)
Author:
xi
Message:

Parser now provides style information. Allow empty plain scalars if a tag or anchor is given.

Location:
pyyaml/branches/working-on-emitter
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/branches/working-on-emitter/lib/yaml/emitter.py

    r122 r127  
    176176 
    177177    def write_indent(self): 
    178         self.writer.write("\n"+" "*(self.level*4)) 
     178        self.writer.write("\n"+" "*(self.level*2)) 
    179179        self.soft_space = False 
    180180 
  • pyyaml/branches/working-on-emitter/lib/yaml/events.py

    r122 r127  
    2121 
    2222class ScalarEvent(NodeEvent): 
    23     def __init__(self, anchor, tag, value, start_mark=None, end_mark=None): 
     23    def __init__(self, anchor, tag, value, start_mark=None, end_mark=None, 
     24            implicit=None, style=None): 
    2425        self.anchor = anchor 
    2526        self.tag = tag 
     
    2728        self.start_mark = start_mark 
    2829        self.end_mark = end_mark 
     30        self.implicit = implicit 
     31        self.style = style 
    2932 
    3033class CollectionEvent(NodeEvent): 
    31     def __init__(self, anchor, tag, start_mark=None, end_mark=None): 
     34    def __init__(self, anchor, tag, start_mark=None, end_mark=None, 
     35            flow=None, compact=None): 
    3236        self.anchor = anchor 
    3337        self.tag = tag 
    3438        self.start_mark = start_mark 
    3539        self.end_mark = end_mark 
     40        self.flow = flow 
     41        self.compact = compact 
    3642 
    3743class SequenceEvent(CollectionEvent): 
     
    4551 
    4652class DocumentStartEvent(Event): 
    47     pass 
     53    def __init__(self, start_mark=None, end_mark=None, 
     54            indent=None, implicit=None, version=None, tags=None, 
     55            canonical=None): 
     56        self.start_mark = start_mark 
     57        self.end_mark = end_mark 
     58        self.indent = indent 
     59        self.implicit = implicit 
     60        self.version = version 
     61        self.tags = tags 
     62        self.canonical = canonical 
    4863 
    4964class DocumentEndEvent(Event): 
     
    5166 
    5267class StreamStartEvent(Event): 
    53     pass 
     68    def __init__(self, start_mark=None, end_mark=None, 
     69            encoding=None): 
     70        self.start_mark = start_mark 
     71        self.end_mark = end_mark 
     72        self.encoding = encoding 
    5473 
    5574class StreamEndEvent(Event): 
  • pyyaml/branches/working-on-emitter/lib/yaml/parser.py

    r121 r127  
    131131        # Parse start of stream. 
    132132        token = self.scanner.get() 
    133         yield StreamStartEvent(token.start_mark, token.end_mark) 
     133        yield StreamStartEvent(token.start_mark, token.end_mark, 
     134                encoding=token.encoding) 
    134135 
    135136        # Parse implicit document. 
     
    139140            token = self.scanner.peek() 
    140141            start_mark = end_mark = token.start_mark 
    141             yield DocumentStartEvent(start_mark, end_mark) 
     142            yield DocumentStartEvent(start_mark, end_mark, implicit=True) 
    142143            for event in self.parse_block_node(): 
    143144                yield event 
     
    153154            token = self.scanner.peek() 
    154155            start_mark = token.start_mark 
    155             self.process_directives() 
     156            version, tags = self.process_directives() 
    156157            if not self.scanner.check(DocumentStartToken): 
    157158                raise ParserError(None, None, 
     
    161162            token = self.scanner.get() 
    162163            end_mark = token.end_mark 
    163             yield DocumentStartEvent(start_mark, end_mark) 
     164            yield DocumentStartEvent(start_mark, end_mark, 
     165                    implicit=False, version=version, tags=tags) 
    164166            if self.scanner.check(DirectiveToken, 
    165167                    DocumentStartToken, DocumentEndToken, StreamEndToken): 
     
    202204                            token.start_mark) 
    203205                self.tag_handles[handle] = prefix 
     206        version_value = self.yaml_version 
     207        tags_value = None 
     208        if self.tag_handles: 
     209            tags_value = self.tag_handles.copy() 
    204210        for key in self.DEFAULT_TAGS: 
    205211            if key not in self.tag_handles: 
    206212                self.tag_handles[key] = self.DEFAULT_TAGS[key] 
     213        return version_value, tags_value 
    207214 
    208215    def parse_block_node(self): 
     
    233240            if self.scanner.check(AnchorToken): 
    234241                token = self.scanner.get() 
    235                 start_mark = end_mark = token.start_mark 
     242                start_mark = token.start_mark 
     243                end_mark = token.end_mark 
    236244                anchor = token.value 
    237245                if self.scanner.check(TagToken): 
    238246                    token = self.scanner.get() 
    239                     end_mark = tag_mark = token.start_mark 
     247                    tag_mark = token.start_mark 
     248                    end_mark = token.end_mark 
    240249                    tag = token.value 
    241250            elif self.scanner.check(TagToken): 
    242251                token = self.scanner.get() 
    243                 start_mark = end_mark = tag_mark = token.start_mark 
     252                start_mark = tag_mark = token.start_mark 
     253                end_mark = token.end_mark 
    244254                tag = token.value 
    245255                if self.scanner.check(AnchorToken): 
    246256                    token = self.scanner.get() 
    247                     end_mark = token.start_mark 
     257                    end_mark = token.end_mark 
    248258                    anchor = token.value 
    249259            if tag is not None: 
     
    262272                    tag = u'!' 
    263273            if start_mark is None: 
    264                 start_mark = self.scanner.peek().start_mark 
     274                start_mark = end_mark = self.scanner.peek().start_mark 
    265275            event = None 
    266276            collection_events = None 
    267277            if indentless_sequence and self.scanner.check(BlockEntryToken): 
    268278                end_mark = self.scanner.peek().end_mark 
    269                 event = SequenceEvent(anchor, tag, start_mark, end_mark) 
     279                event = SequenceEvent(anchor, tag, start_mark, end_mark, 
     280                        flow=False, compact=False) 
    270281                collection_events = self.parse_indentless_sequence() 
    271282            else: 
     
    274285                    end_mark = token.end_mark 
    275286                    event = ScalarEvent(anchor, tag, token.value, 
    276                             start_mark, end_mark) 
     287                            start_mark, end_mark, 
     288                            implicit=(tag is None), style=token.style) 
    277289                elif self.scanner.check(FlowSequenceStartToken): 
    278290                    end_mark = self.scanner.peek().end_mark 
    279                     event = SequenceEvent(anchor, tag, start_mark, end_mark) 
     291                    event = SequenceEvent(anchor, tag, start_mark, end_mark, 
     292                            flow=True) 
    280293                    collection_events = self.parse_flow_sequence() 
    281294                elif self.scanner.check(FlowMappingStartToken): 
    282295                    end_mark = self.scanner.peek().end_mark 
    283                     event = MappingEvent(anchor, tag, start_mark, end_mark) 
     296                    event = MappingEvent(anchor, tag, start_mark, end_mark, 
     297                            flow=True) 
    284298                    collection_events = self.parse_flow_mapping() 
    285299                elif block and self.scanner.check(BlockSequenceStartToken): 
    286300                    end_mark = self.scanner.peek().start_mark 
    287                     event = SequenceEvent(anchor, tag, start_mark, end_mark) 
     301                    compact = self.scanner.peek().inline 
     302                    event = SequenceEvent(anchor, tag, start_mark, end_mark, 
     303                            flow=False, compact=compact) 
    288304                    collection_events = self.parse_block_sequence() 
    289305                elif block and self.scanner.check(BlockMappingStartToken): 
    290306                    end_mark = self.scanner.peek().start_mark 
    291                     event = MappingEvent(anchor, tag, start_mark, end_mark) 
     307                    compact = self.scanner.peek().inline 
     308                    event = MappingEvent(anchor, tag, start_mark, end_mark, 
     309                            flow=False, compact=compact) 
    292310                    collection_events = self.parse_block_mapping() 
     311                elif anchor is not None or tag is not None: 
     312                    # Empty scalars are allowed even if a tag or an anchor is 
     313                    # specified. 
     314                    event = ScalarEvent(anchor, tag, u'', start_mark, end_mark, 
     315                            implicit=False, style='') 
    293316                else: 
    294317                    if block: 
     
    385408                token = self.scanner.get() 
    386409                yield MappingEvent(None, u'!', 
    387                         token.start_mark, token.end_mark) 
     410                        token.start_mark, token.end_mark, 
     411                        flow=True, compact=True) 
    388412                if not self.scanner.check(ValueToken, 
    389413                        FlowEntryToken, FlowSequenceEndToken): 
     
    461485 
    462486    def process_empty_scalar(self, mark): 
    463         return ScalarEvent(None, None, u'', mark, mark) 
    464  
     487        return ScalarEvent(None, None, u'', mark, mark, implicit=True) 
     488 
  • pyyaml/branches/working-on-emitter/lib/yaml/reader.py

    r121 r127  
    101101        self.raw_buffer = None 
    102102        self.raw_decode = None 
     103        self.encoding = None 
    103104        self.index = 0 
    104105        self.line = 0 
     
    157158            if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): 
    158159                self.raw_decode = utf_16_le_decode 
     160                self.encoding = 'utf-16-le' 
    159161            elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): 
    160162                self.raw_decode = utf_16_be_decode 
     163                self.encoding = 'utf-16-be' 
    161164            else: 
    162165                self.raw_decode = utf_8_decode 
     166                self.encoding = 'utf-8' 
    163167        self.update(1) 
    164168 
  • pyyaml/branches/working-on-emitter/lib/yaml/scanner.py

    r121 r127  
    3636    # See below simple keys treatment. 
    3737 
    38     def __init__(self, token_number, required, index, line, column, mark): 
     38    def __init__(self, token_number, required, index, line, column, mark=None, 
     39            inline=None): 
    3940        self.token_number = token_number 
    4041        self.required = required 
     
    4344        self.column = column 
    4445        self.mark = mark 
     46        self.inline = inline 
    4547 
    4648class Scanner: 
     
    8183        # Past indentation levels. 
    8284        self.indents = [] 
     85 
     86        # Used for providing style information to the parser. 
     87        self.current_line = self.previous_line = self.reader.line 
     88        self.current_column = self.previus_column = self.reader.column 
    8389 
    8490        # Variables related to simple keys treatment. 
     
    322328            column = self.reader.column 
    323329            mark = self.reader.get_mark() 
     330            inline = (self.current_line == self.previous_line) 
    324331            key = SimpleKey(token_number, required, 
    325                     index, line, column, mark) 
     332                    index, line, column, mark, inline) 
    326333            self.possible_simple_keys[self.flow_level] = key 
    327334 
     
    381388         
    382389        # Add STREAM-END. 
    383         self.tokens.append(StreamStartToken(mark, mark)) 
    384          
     390        self.tokens.append(StreamStartToken(mark, mark, 
     391            encoding=self.reader.encoding)) 
    385392 
    386393    def fetch_stream_end(self): 
     
    510517            if self.add_indent(self.reader.column): 
    511518                mark = self.reader.get_mark() 
    512                 self.tokens.append(BlockSequenceStartToken(mark, mark)) 
     519                inline = (self.current_line == self.previous_line) 
     520                self.tokens.append(BlockSequenceStartToken(mark, mark, inline)) 
    513521 
    514522        # It's an error for the block entry to occur in the flow context, 
     
    543551            if self.add_indent(self.reader.column): 
    544552                mark = self.reader.get_mark() 
    545                 self.tokens.append(BlockMappingStartToken(mark, mark)) 
     553                inline = (self.current_line == self.previous_line) 
     554                self.tokens.append(BlockMappingStartToken(mark, mark, inline)) 
    546555 
    547556        # Simple keys are allowed after '?' in the block context. 
     
    573582                if self.add_indent(key.column): 
    574583                    self.tokens.insert(key.token_number-self.tokens_taken, 
    575                             BlockMappingStartToken(key.mark, key.mark)) 
     584                            BlockMappingStartToken(key.mark, key.mark, 
     585                                key.inline)) 
    576586 
    577587            # There cannot be two simple keys one after another. 
     
    791801            else: 
    792802                found = True 
     803 
     804        self.previous_line = self.current_line 
     805        self.previous_column = self.current_column 
     806        self.current_line = self.reader.line 
     807        self.current_column = self.reader.column 
    793808 
    794809    def scan_directive(self): 
     
    10541069 
    10551070        # We are done. 
    1056         return ScalarToken(u''.join(chunks), False, start_mark, end_mark) 
     1071        if folded: 
     1072            style = '>' 
     1073        else: 
     1074            style = '|' 
     1075        return ScalarToken(u''.join(chunks), False, start_mark, end_mark, 
     1076                style) 
    10571077 
    10581078    def scan_block_scalar_indicators(self, start_mark): 
     
    11551175        self.reader.forward() 
    11561176        end_mark = self.reader.get_mark() 
    1157         return ScalarToken(u''.join(chunks), False, start_mark, end_mark) 
     1177        if double: 
     1178            style = '"' 
     1179        else: 
     1180            style = '\'' 
     1181        return ScalarToken(u''.join(chunks), False, start_mark, end_mark, 
     1182                style) 
    11581183 
    11591184    ESCAPE_REPLACEMENTS = { 
     
    13061331                    or (not self.flow_level and self.reader.column < indent): 
    13071332                break 
    1308         return ScalarToken(u''.join(chunks), True, start_mark, end_mark) 
     1333        return ScalarToken(u''.join(chunks), True, start_mark, end_mark, '') 
    13091334 
    13101335    def scan_plain_spaces(self, indent, start_mark): 
  • pyyaml/branches/working-on-emitter/lib/yaml/tokens.py

    r122 r127  
    2525class DocumentStartToken(Token): 
    2626    id = '<document start>' 
     27    def __init__(self, name, value, start_mark=None, end_mark=None): 
     28        self.name = name 
     29        self.value = value 
     30        self.start_mark = start_mark 
     31        self.end_mark = end_mark 
    2732 
    2833class DocumentEndToken(Token): 
     
    3136class StreamStartToken(Token): 
    3237    id = '<stream start>' 
     38    def __init__(self, start_mark=None, end_mark=None, 
     39            encoding=None): 
     40        self.start_mark = start_mark 
     41        self.end_mark = end_mark 
     42        self.encoding = encoding 
    3343 
    3444class StreamEndToken(Token): 
     
    3747class BlockSequenceStartToken(Token): 
    3848    id = '<block sequence start>' 
     49    def __init__(self, start_mark=None, end_mark=None, 
     50            inline=None): 
     51        self.start_mark = start_mark 
     52        self.end_mark = end_mark 
     53        self.inline = inline 
    3954 
    4055class BlockMappingStartToken(Token): 
    4156    id = '<block mapping start>' 
     57    def __init__(self, start_mark=None, end_mark=None, 
     58            inline=None): 
     59        self.start_mark = start_mark 
     60        self.end_mark = end_mark 
     61        self.inline = inline 
    4262 
    4363class BlockEndToken(Token): 
     
    91111class ScalarToken(Token): 
    92112    id = '<scalar>' 
    93     def __init__(self, value, plain, start_mark=None, end_mark=None): 
     113    def __init__(self, value, plain, start_mark=None, end_mark=None, 
     114            style=None): 
    94115        self.value = value 
    95116        self.plain = plain 
    96117        self.start_mark = start_mark 
    97118        self.end_mark = end_mark 
     119        self.style = style 
    98120 
  • pyyaml/branches/working-on-emitter/tests/data/spec-08-12.canonical

    r38 r127  
    77  *A, 
    88  !!str "", 
     9  !!str "", 
    910] 
  • pyyaml/branches/working-on-emitter/tests/data/spec-08-12.data

    r44 r127  
    44  !!str 'Tagged', 
    55  *anchor, # Alias node 
    6 #  !!str,   # Empty plain scalar 
     6  !!str ,  # Empty plain scalar 
    77  '',   # Empty plain scalar 
    88] 
  • pyyaml/branches/working-on-emitter/tests/test_emitter.py

    r122 r127  
    11 
    2 import test_appliance, sys 
     2import test_appliance, sys, StringIO 
    33 
    44from yaml import * 
     
    88    def _testEmitterOnCanonical(self, test_name, canonical_filename): 
    99        events = list(iter(Parser(Scanner(Reader(file(canonical_filename, 'rb')))))) 
    10         writer = sys.stdout 
     10        #writer = sys.stdout 
     11        writer = StringIO.StringIO() 
    1112        emitter = Emitter(writer) 
    12         print "-"*30 
    13         print "ORIGINAL DATA:" 
    14         print file(canonical_filename, 'rb').read() 
     13        #print "-"*30 
     14        #print "ORIGINAL DATA:" 
     15        #print file(canonical_filename, 'rb').read() 
    1516        for event in events: 
    1617            emitter.emit(event) 
Note: See TracChangeset for help on using the changeset viewer.