Ignore:
Timestamp:
Nov 3, 2010, 6:56:03 PM (9 years ago)
Author:
ksherdy
Message:

Update demo_parallel_prefix_parity. Update string parsing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • proto/JSON/json_prototype.py

    r684 r686  
    3838        return int(hexdigit*(lgth+1),16)&EOF_mask
    3939       
    40 def parse_escape(lex, EOF_mask):
     40def parse_escape(Lex, EOF_mask):
     41        r"""
     42        Marks escaped characters.
     43        Does not mark escaped '\' characters.
     44        '\' characters are either escaped and unmarked or the following character in an odd length run is marked.
     45        """
     46
    4147        odd = simd_const_4('a',EOF_mask)
    4248        even = simd_const_4('5',EOF_mask)
    4349       
    44         start = lex.RSolidus &~ bitutil.Advance(lex.RSolidus)
     50        start = Lex.RSolidus &~ bitutil.Advance(Lex.RSolidus)
    4551       
    4652        even_start = start & even
    47         even_final = (even_start + lex.RSolidus) & ~lex.RSolidus
     53        even_final = (even_start + Lex.RSolidus) & ~Lex.RSolidus
    4854        even_escape = even_final & odd
    4955       
    5056        odd_start = start & odd
    51         odd_final = (odd_start + lex.RSolidus) & ~lex.RSolidus
     57        odd_final = (odd_start + Lex.RSolidus) & ~Lex.RSolidus
    5258        odd_escape = (odd_final & even)
    53        
    54         escape = (even_escape | odd_escape)
     59
     60        escape = (even_escape | odd_escape) 
    5561       
    5662        return escape
     
    6167
    6268        (bit, EOF_mask) = bitutil.transpose_streams(u8data)
    63         (u8, lex, ctrl) = byteclass.classify_bytes(bit)
    64         (escape) = parse_escape(lex,EOF_mask)
     69        (u8, Lex, Ctrl) = byteclass.classify_bytes(bit)
     70        (escape) = parse_escape(Lex,EOF_mask)
    6571
    6672        bitutil.print_aligned_streams([('Input Data', u8data),
    67                               ('lex.RSolidus', bitutil.bitstream2string(lex.RSolidus, lgth)),   
     73                              ('Lex.RSolidus', bitutil.bitstream2string(Lex.RSolidus, lgth)),   
    6874                              ('escape', bitutil.bitstream2string(escape, lgth)),       
    6975                              ('EOF_Mask', bitutil.bitstream2string(EOF_mask, lgth+1))])
     
    101107def demo_parallel_prefix_parity(u8data):
    102108        r"""
    103         >>> demo_parallel_prefix_parity('[data] [data][data] [data] [data')
    104         Input Data        : [data] [data][data] [data] [data
    105         lex.LSquareBracket: 1______1_____1______1______1____
    106         lex.RSquareBracket: _____1______1_____1______1______
    107         parity            : 11111__11111_11111__11111__11111
    108         EOF_Mask          : 11111111111111111111111111111111_
     109        >>> demo_parallel_prefix_parity('"data" "data""data" "data" "data')
     110        Input Data: "data" "data""data" "data" "data
     111        Lex.DQuote: 1____1_1____11____1_1____1_1____
     112        Parity    : 11111__11111_11111__11111__11111
     113        EOF_Mask  : 11111111111111111111111111111111_
    109114        <BLANKLINE>
    110115        """
     
    113118
    114119        (bit, EOF_mask) = bitutil.transpose_streams(u8data)
    115         (u8, lex, ctrl) = byteclass.classify_bytes(bit)
    116         brackets = (lex.LSquareBracket | lex.RSquareBracket)
    117         (parity) = parallel_prefix_parity(brackets,lgth)
     120        (u8, Lex, Ctrl) = byteclass.classify_bytes(bit)
     121        Parity = parallel_prefix_parity(Lex.DQuote,lgth)
    118122
    119123        bitutil.print_aligned_streams([('Input Data', u8data),
    120                               ('lex.LSquareBracket', bitutil.bitstream2string(lex.LSquareBracket, lgth)),
    121                               ('lex.RSquareBracket', bitutil.bitstream2string(lex.RSquareBracket, lgth)),                             
    122                               ('parity', bitutil.bitstream2string(parity, lgth)),       
     124                              ('Lex.DQuote', bitutil.bitstream2string(Lex.DQuote, lgth)),
     125                              ('Parity', bitutil.bitstream2string(Parity, lgth)),       
    123126                              ('EOF_Mask', bitutil.bitstream2string(EOF_mask, lgth+1))])
    124127        return
    125128
    126129
    127 def validate_number(lex, EOF_mask):
    128         Errors = 0     
     130def validate_number(Lex, EOF_mask):
     131        r"""   
     132        RFC 4627 - JavaScript Object Notation (JSON) 
     133        RFC 5234 - Augmented BNF for Syntax Specifications: ABNF
     134
     135        number = [ minus ] int [ frac ] [ exp ]
     136        decimal-point = %x2E       ; .
     137        digit1-9 = %x31-39         ; 1-9
     138        e = %x65 / %x45            ; e E
     139        exp = e [ minus / plus ] 1*DIGIT
     140        frac = decimal-point 1*DIGIT
     141        int = zero / ( digit1-9 *DIGIT )
     142        minus = %x2D               ; -
     143        plus = %x2B                ; +
     144        zero = %x30                ; 0 
     145        """     
     146        Errors = 0
    129147        M0 = 0                                                  # Assume the cursor is at the first Minus, Zero, or Digit_1_9 character
    130         M0 = bitutil.Advance(lex.Comma)                         # WARNING - A hack to set initial cursor postions and ease testing. The 'lexical' FIRST SET for the JSON number production is {-,0,1,..,9} .     
    131 
    132         M1 = bitutil.ScanThru(M0, lex.Minus & M0)               # ? Optional character class [-]
    133         E1 = M1 &~(lex.Zero|lex.Digit1_9)
    134 
    135         M1a = M1 & lex.Zero                                     # Split
    136         M1b = M1 & lex.Digit0_9                         
     148        M0 = bitutil.Advance(Lex.Comma)                         # WARNING - A hack to set initial cursor postions and ease testing. The 'lexical' FIRST SET for the JSON number production is {-,0,1,..,9} .     
     149
     150        M1 = bitutil.ScanThru(M0, Lex.Minus & M0)               # ? Optional character class [-]
     151        E1 = M1 &~(Lex.Zero|Lex.Digit1_9)
     152
     153        M1a = M1 & Lex.Zero                                     # Split
     154        M1b = M1 & Lex.Digit0_9                         
    137155        M2a = bitutil.Advance(M1a)
    138156        M2b = bitutil.Advance(M1b)
    139         M3b = bitutil.ScanThru(M2b,lex.Digit0_9)
     157        M3b = bitutil.ScanThru(M2b,Lex.Digit0_9)
    140158        M4 = M2a | M3b                                          # Join
    141159       
    142         M4a = M4 &~(lex.DecimalPoint)                           # Split
    143         M4b = M4 & (lex.DecimalPoint)
     160        M4a = M4 &~(Lex.DecimalPoint)                           # Split
     161        M4b = M4 & (Lex.DecimalPoint)
    144162        M5b = bitutil.Advance(M4b)
    145         E5b = M5b &~(lex.Digit0_9)                              # + [0-9]+
    146         M6 = bitutil.ScanThru(M5b,lex.Digit0_9)
     163        E5b = M5b &~(Lex.Digit0_9)                              # + [0-9]+
     164        M6 = bitutil.ScanThru(M5b,Lex.Digit0_9)
    147165        M7 = M4a | M6                                           # Join
    148166       
    149         M7a = M7 &~(lex.Ee)                                     # Split
    150         E7a = M7a &~(lex.NumberFollowSet)
    151         M7b = M7 &(lex.Ee)
     167        M7a = M7 &~(Lex.Ee)                                     # Split
     168        E7a = M7a &~(Lex.NumberFollowSet)
     169        M7b = M7 &(Lex.Ee)
    152170        M8b = bitutil.Advance(M7b)
    153         M9b = bitutil.ScanThru(M8b, lex.PlusMinus & M8b)        # ? Optional character class [+-]               
    154         E9b  = M9b &~(lex.Digit0_9)                             # + [0-9]+
    155         M10b = bitutil.ScanThru(M9b,lex.Digit0_9)
    156         E10b = M10b &~(lex.NumberFollowSet)
     171        M9b = bitutil.ScanThru(M8b, Lex.PlusMinus & M8b)        # ? Optional character class [+-]               
     172        E9b  = M9b &~(Lex.Digit0_9)                             # + [0-9]+
     173        M10b = bitutil.ScanThru(M9b,Lex.Digit0_9)
     174        E10b = M10b &~(Lex.NumberFollowSet)
    157175        M11 = M7a | M10b                                        # Join
    158176       
     
    187205
    188206def demo_validate_number(u8data):
    189         r"""   
    190         RFC 4627 - JavaScript Object Notation (JSON) 
    191         RFC 5234 - Augmented BNF for Syntax Specifications: ABNF
    192 
    193         number = [ minus ] int [ frac ] [ exp ]
    194         decimal-point = %x2E       ; .
    195         digit1-9 = %x31-39         ; 1-9
    196         e = %x65 / %x45            ; e E
    197         exp = e [ minus / plus ] 1*DIGIT
    198         frac = decimal-point 1*DIGIT
    199         int = zero / ( digit1-9 *DIGIT )
    200         minus = %x2D               ; -
    201         plus = %x2B                ; +
    202         zero = %x30                ; 0 
    203         """
    204207        r"""
    205208        >>> demo_validate_number(',-,--,-a,00,-00,-0.,-0.e,-0.E,00,-123.456-,0.456+,0e10+,0123456789,')
     
    248251
    249252        (bit, EOF_mask) = bitutil.transpose_streams(u8data)
    250         (u8, lex, ctrl) = byteclass.classify_bytes(bit)
    251         Errors = validate_number(lex,EOF_mask)
     253        (u8, Lex, Ctrl) = byteclass.classify_bytes(bit)
     254        Errors = validate_number(Lex,EOF_mask)
    252255
    253256        bitutil.print_aligned_streams([('Input Data', u8data),
    254                               ('Minus', bitutil.bitstream2string(lex.Minus, lgth)),
    255                               ('Zero', bitutil.bitstream2string(lex.Zero, lgth)),
    256                               ('Digit1_9', bitutil.bitstream2string(lex.Digit1_9, lgth)),
    257                               ('Digit0_9', bitutil.bitstream2string(lex.Digit0_9, lgth)),
    258                               ('DecimalPoint', bitutil.bitstream2string(lex.DecimalPoint, lgth)),
    259                               ('Ee', bitutil.bitstream2string(lex.Ee, lgth)),
    260                               ('PlusMinus', bitutil.bitstream2string(lex.PlusMinus, lgth)),
     257                              ('Minus', bitutil.bitstream2string(Lex.Minus, lgth)),
     258                              ('Zero', bitutil.bitstream2string(Lex.Zero, lgth)),
     259                              ('Digit1_9', bitutil.bitstream2string(Lex.Digit1_9, lgth)),
     260                              ('Digit0_9', bitutil.bitstream2string(Lex.Digit0_9, lgth)),
     261                              ('DecimalPoint', bitutil.bitstream2string(Lex.DecimalPoint, lgth)),
     262                              ('Ee', bitutil.bitstream2string(Lex.Ee, lgth)),
     263                              ('PlusMinus', bitutil.bitstream2string(Lex.PlusMinus, lgth)),
    261264                              ('EOF_Mask', bitutil.bitstream2string(EOF_mask, lgth+1)),
    262265                              ('Errors', bitutil.bitstream2string(Errors, lgth))])
    263266
    264 def validate_string(lex,escape,lgth):
     267def validate_string(Lex,Ctrl,StringMask,EscapeChars,EOF_mask,lgth):
    265268        r"""
    266269        RFC 4627 - JavaScript Object Notation (JSON) 
     
    280283
    281284        escape = %x5C              ; \
    282 
    283285        quotation-mark = %x22      ; "
    284 
    285286        unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
    286         """
    287 
    288         return
     287
     288        JSON string validation requires both:
     289        (1) validation of escape characters,
     290        (2) validation of unescaped characters.
     291        """
     292       
     293        # (1) Validate escape characters
     294        StringEscapeChars = EscapeChars & StringMask
     295        Errors = (StringEscapeChars &~ Lex.Escape)
     296       
     297        u = StringEscapeChars & Lex.u
     298       
     299        uScope1 = bitutil.Advance(u)
     300        uScope2 = bitutil.Advance(uScope1)
     301        uScope3 = bitutil.Advance(uScope2)
     302        uScope4 = bitutil.Advance(uScope3)
     303       
     304        Errors |= uScope1 &~ Lex.HexDigit
     305        Errors |= uScope2 &~ Lex.HexDigit
     306        Errors |= uScope3 &~ Lex.HexDigit
     307        Errors |= uScope4 &~ Lex.HexDigit
     308       
     309        # (2) Validation of unescaped characters
     310        # (2.1) StringMask construction ensures all '"' are escaped.
     311        # (2.2) '\' are either correctly escaped or the character following an odd length run is escaped.
     312        # (2.3) validate_utf8(u8) ensures valid UTF8 encodings in the code point range U+0000 - U+01FFFF. TODO
     313
     314        StringNotEscapedChars = (~(EscapeChars | Lex.RSolidus)) & StringMask # TODO - Verify logic.
     315        Errors |= (StringNotEscapedChars & Ctrl.x00_x1F)
     316               
     317        if debug:
     318                bitutil.print_aligned_streams([('Input Data', u8data),
     319                              ('EscapeChars', bitutil.bitstream2string(EscapeChars, lgth)),
     320                              ('StringEscapeChars', bitutil.bitstream2string(StringEscapeChars, lgth)),
     321                              ('u', bitutil.bitstream2string(u, lgth)),
     322                              ('uScope1', bitutil.bitstream2string(uScope1, lgth)),
     323                              ('uScope2', bitutil.bitstream2string(uScope2, lgth)),
     324                              ('uScope3', bitutil.bitstream2string(uScope3, lgth)),
     325                              ('uScope4', bitutil.bitstream2string(uScope4, lgth)),
     326                              ('StringNotEscapedChars', bitutil.bitstream2string(StringNotEscapedChars, lgth)),
     327                              ('Errors', bitutil.bitstream2string(Errors, lgth+1))])     
     328        return Errors
    289329
    290330def demo_validate_string(u8data):
     
    294334
    295335        (bit, EOF_mask) = bitutil.transpose_streams(u8data)
    296         (u8, lex, ctrl) = byteclass.classify_bytes(bit)
    297         escape = parse_escape(lex, EOF_mask)
    298        
    299         # Mark String starts "
    300         unescaped_quotation_marks = (lex.DQuote &~ escape)
    301        
    302         # Mask String interiors
    303         parity_mask = parallel_prefix_parity(unescaped_quotation_marks, lgth)
    304         string_mask = parity_mask & bitutil.Advance(parity_mask)
    305        
    306        
    307        
    308         errors = validate_string(lex,escape,lgth)
    309        
    310         errors = 1
    311        
     336        (u8, Lex, Ctrl) = byteclass.classify_bytes(bit)
     337       
     338        # Construct string interior mask (1),(2),(3)
     339        # (1) Mark all escaped characters
     340        EscapeChars = parse_escape(Lex, EOF_mask)
     341       
     342        # (2) Mark all unescaped "
     343        UnescapedDQuotes = (Lex.DQuote &~ EscapeChars)
     344       
     345        # (3) Construct mask
     346        ParityMask = parallel_prefix_parity(UnescapedDQuotes, lgth) & EOF_mask # TODO - Solve EOF_mask problem
     347        StringMask = ParityMask & bitutil.Advance(ParityMask)
     348                               
     349        Errors = validate_string(Lex,Ctrl,StringMask,EscapeChars,EOF_mask,lgth)
     350       
     351        # Validate all strings are terminated with an unescaped "
     352        StringCursor = ParityMask &~ bitutil.Advance(ParityMask)
     353        StringCursorEnd = bitutil.ScanThru(StringCursor, ParityMask)
     354        Errors |= StringCursorEnd &~ EOF_mask
     355
    312356        bitutil.print_aligned_streams([('Input Data', u8data),
    313                               ('escape', bitutil.bitstream2string(escape, lgth)),
    314                               ('DQuote', bitutil.bitstream2string(lex.DQuote, lgth)),
    315                               ('unescaped_quotation_marks', bitutil.bitstream2string(unescaped_quotation_marks, lgth)),
    316                               ('string_mask', bitutil.bitstream2string(string_mask, lgth)),                           
     357                              ('EscapeChars', bitutil.bitstream2string(EscapeChars, lgth)),
     358                              ('UnescapedDQuotes', bitutil.bitstream2string(UnescapedDQuotes, lgth)),
     359                              ('ParityMask', bitutil.bitstream2string(ParityMask, lgth+1)),
     360                              ('StringCursorEnd', bitutil.bitstream2string(StringCursorEnd, lgth+1)),
    317361                              ('EOF_Mask', bitutil.bitstream2string(EOF_mask, lgth+1)),
    318                               ('errors', bitutil.bitstream2string(errors, lgth))])     
     362                              ('Errors', bitutil.bitstream2string(Errors, lgth+1))])   
    319363                             
    320364        return
     
    326370       
    327371        # Classify bytes for UTF-8 processing, whitespace, control and JSON lexical analysis.
    328         (u8, lex, ctrl) = byteclass.classify_bytes(bit)
     372        (u8, Lex, Ctrl) = byteclass.classify_bytes(bit)
    329373       
    330374        # Validate UTF-8 multibyte sequences and determine the UTF-8 scope streams.
     
    332376       
    333377        # Mark escape characters
    334         escape = parse_escape(lex, EOF_mask)
    335        
    336 #       bitutil.print_aligned_streams([('Input Data', u8data),
    337 #                             ('escape', bitutil.bitstream2string(escape, lgth)),
    338 #                             ('DQuote', bitutil.bitstream2string(lex.DQuote, lgth)),
    339 #                             ('EOF_Mask', bitutil.bitstream2string(EOF_mask, lgth+1))])       
    340        
    341         # Mark unescaped "
    342        
    343 
     378        escape = parse_escape(Lex, EOF_mask)
     379       
    344380        return
    345381 
     
    363399        u8data = bitutil.readfile(sys.argv[1])
    364400#       demo_parse_escape(u8data)
    365 #       demo_parallel_prefix_parity(u8data)
     401        demo_parallel_prefix_parity(u8data)
    366402#       demo_validate_number(u8data)
    367         demo_validate_string(u8data)
     403#       demo_validate_string(u8data)
    368404#       demo_parse_json(u8data)
Note: See TracChangeset for help on using the changeset viewer.