Changeset 1987 for proto/parabix2


Ignore:
Timestamp:
Mar 29, 2012, 5:43:12 PM (7 years ago)
Author:
lindanl
Message:

Add DTD parsing into parabix.py

Location:
proto/parabix2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • proto/parabix2/pablo.py

    r1959 r1987  
    3939        mask = 128
    4040        index = 0
     41        global data
    4142        while index < 8:
    4243                current = 0
     
    6566                elif index == 8:
    6667                        b.bit_7 = current
    67         data = s
     68        data  = s
    6869        return cursor-1  # basis streams and EOF mask
     70
     71def match(s,marker):
     72        pos = count_leading_zeroes(marker)
     73        i = 0
     74        for byte in s:
     75                if byte != data[pos+i]:
     76                        return 0
     77                i +=1
     78        return marker
    6979
    7080def inFile(lex_error):
     
    8797        return zeroes
    8898       
    89 def NoteError(s, lex_error):
    90         pos = count_leading_zeroes(lex_error)
    91         print s + " at position " + str(pos)
    9299#
    93100#  ScanThru is the core operation for parallel scanning.
     
    108115def Advance(stream):
    109116        return stream + stream
     117       
     118def AdvancebyPos(stream, pos):
     119        return stream << pos
    110120
    111121
  • proto/parabix2/parabix2.py

    r1959 r1987  
    9292        EmptyTag_marks = 0
    9393        EndTag_marks = 0
    94        
     94
     95class ID_Callouts():
     96        pubid_start = 0
     97        pubid_end = 0
     98        sysid_start = 0
     99        sysid_end = 0
     100
    95101class Check_streams():
    96102        misc_mask = 0
     
    100106        name_follows = 0
    101107        att_refs = 0
     108
     109class DTD_Callouts():
     110        root_name_start = 0
     111        root_name_follow = 0
     112        pubid_start = 0
     113        pubid_end = 0
     114        sysid_start = 0
     115        sysid_end = 0
     116        PERef_starts = 0
     117        PERef_ends = 0
     118        PI_starts = 0
     119        PI_name_follows = 0
     120        PI_ends = 0
     121        notation_name_start = 0
     122        notation_name_follow = 0
     123        notation_pubid_start = 0
     124        notation_pubid_end = 0
     125        notation_sysid_start = 0
     126        notation_sysid_end = 0
     127
    102128
    103129def Classify_bytes_Validate_utf8(basis_bits, lex, u8): 
     
    312338                CD_Ct_Cursor = pablo.Advance(CtCDPI_Cursor & ~PI_Cursor)
    313339                CD_Cursor = CD_Ct_Cursor & lex.LBracket
    314                 Ct_Cursor = CD_Ct_Cursor & lex.Hyphen
     340                Ct_Cursor = CD_Ct_Cursor & lex.Hyphen
     341                DTD_Cursor = 0
    315342                # PI processing
    316343                if PI_Cursor:
     
    329356
    330357                # CDATA section processing
    331                 if CD_Cursor:
     358                elif CD_Cursor:
    332359                        ctCDPI_Callouts.CD_starts |= CD_Cursor
    333360                        CD_Cursor = pablo.ScanTo(CD_Cursor, CD_closer)
     
    336363
    337364                # Comment processing
    338                 if Ct_Cursor:
     365                elif Ct_Cursor:
    339366                        ctCDPI_Callouts.Ct_starts |= Ct_Cursor
    340367                        Ct_Cursor = pablo.Advance(Ct_Cursor) 
     
    349376                        if Ct_error:
    350377                                error_tracker.NoteError("Error in comment syntax", Ct_error)
     378                else:
     379                        DTD_Cursor = ParseDTD(CD_Ct_Cursor, DTD_out)
     380                        CtCDPI_ends |= DTD_Cursor
    351381
    352382                # Common processing
    353                 CtCDPI_Cursor = PI_Cursor | CD_Cursor | Ct_Cursor
     383                CtCDPI_Cursor = PI_Cursor | CD_Cursor | Ct_Cursor | DTD_Cursor
    354384                CtCDPI_Cursor = pablo.ScanTo(CtCDPI_Cursor, CtCDPI_opener)
    355                 ctCDPI_mask |= (CtCDPI_ends - CtCDPI_starts) | CtCDPI_ends             
     385                ctCDPI_mask |= (CtCDPI_ends - CtCDPI_starts) | CtCDPI_ends
     386
    356387                # If any of the Comment, CDATA or PI markups are unterminated, it is an error.
    357388                ctCDPI_error = pablo.atEOF(ctCDPI_mask)
     
    457488        # Attribute value spans
    458489        tag_Callouts.AttVal_spans = tag_Callouts.AttVal_ends - tag_Callouts.AttVal_starts
     490       
     491#
     492#  Parse a public/system ID of one of the form
     493#  'PUBLIC' S pubid_literal:quoted_string S sysid_literal:quoted_string |
     494#  'PUBLIC' S pubid_literal:quoted_string S?|
     495#  'SYSTEM' S sysid_literal:quoted_string
     496#  Form 2 is permitted only if require_system_id = 0
     497#  (Note that the system literal is optional in NOTATION declarations.)
     498#  Generate callout.{pubid_start, pubid_end, sysid_start, sysid_end, end_marker}
     499def ParseExternalID(input_marker, require_system_id, callout):
     500        if pablo.match('PUBLIC', input_marker):
     501                marker = pablo.AdvancebyPos(input_marker, 6)
     502                if marker &~ lex.WS:
     503                        error_tracker.NoteError('ExpectedWhitespace', marker)
     504                callout.pubid_start = pablo.ScanThru(marker, lex.WS)
     505                if callout.pubid_start &~ (lex.DQuote | lex.SQuote):
     506                        error_tracker.NoteError('ExpectedQuotedString', callout.pubid_start)
     507                dq = callout.pubid_start & lex.DQuote
     508                sq = callout.pubid_start & lex.SQuote
     509                callout.pubid_end = pablo.ScanTo(dq, lex.DQuote &~ dq) | pablo.ScanTo(sq, lex.SQuote &~ sq)
     510                if pablo.atEOF(callout.pubid_end):
     511                        error_tracker.NoteError('UnterminatedDOCTYPE', callout.pubid_end)
     512                m1 = pablo.Advance(callout.pubid_end)
     513                marker = pablo.ScanThru(m1, lex.WS)
     514                if marker & (lex.DQuote | lex.SQuote):
     515                        if marker & m1:
     516                                error_tracker.NoteError('ExpectedWhitespace', marker)
     517                        callout.sysid_start = marker
     518                        dq = marker & lex.DQuote
     519                        sq = marker & lex.SQuote
     520                        marker = pablo.ScanTo(dq, lex.DQuote &~ dq) | pablo.ScanTo(sq, lex.SQuote & ~sq)
     521                        if pablo.atEOF(marker):
     522                                error_tracker.NoteError('UnterminatedDOCTYPE', marker)
     523                        callout.sysid_end = marker
     524                elif require_system_id:
     525                        error_tracker.NoteError('ExpectedQuotedString', marker)
     526        # Note the following is problematic for current Pablo, because
     527        # else branches are assumed not to have any carries.   (That is,
     528        # Pablo ifs are based on optimization.)
     529        # If we just use "if" here it will work for valid input, but
     530        # will accept some invalid cases.
     531        elif pablo.match('SYSTEM', input_marker):
     532                # If we just processed a 'PUBLIC' id declaration, this is an error.
     533                # But the following won't work, because the callout might be in a
     534                # block prior to the match with SYSTEM.
     535                #if callout.pubid_start:
     536                #       NoteXercesXMLErr(UnterminatedDOCTYPE, marker)
     537                # Else accept the 'SYSTEM' and continue.
     538                marker = pablo.AdvancebyPos(input_marker, 6)
     539                if marker &~ lex.WS:
     540                        error_tracker.NoteError('ExpectedWhitespace', marker)
     541                callout.sysid_start = pablo.ScanThru(marker, lex.WS)
     542                if callout.sysid_start &~ (lex.DQuote | lex.SQuote):
     543                        error_tracker.NoteError('ExpectedQuotedString', callout.sysid_start)
     544                dq = callout.sysid_start & lex.DQuote
     545                sq = callout.sysid_start & lex.SQuote
     546                marker = pablo.ScanTo(dq, lex.DQuote &~ dq) | pablo.ScanTo(sq, lex.SQuote &~ sq)
     547                if pablo.atEOF(marker):
     548                        error_tracker.NoteError('UnterminatedDOCTYPE', marker)
     549                callout.sysid_end = marker
     550        callout.end_marker = marker
     551
     552
     553def ParseDTD(marker, DTD_out):
     554        if ~pablo.match('DOCTYPE', marker) & marker:
     555                #NoteXercesXMLErr(ExpectedCommentOrCDATA, marker)
     556                return marker
     557        marker = pablo.AdvancebyPos(marker, 7)
     558       
     559        if marker &~ lex.WS:
     560                error_tracker.NoteError('ExpectedWhitespace', marker)
     561        DTD_out.root_name_start = pablo.ScanThru(marker, lex.WS)
     562        DTD_out.root_name_follow = pablo.ScanThru(DTD_out.root_name_start, lex.NameScan)
     563        if DTD_out.root_name_start & DTD_out.root_name_follow:
     564                error_tracker.NoteError('NoRootElemInDOCTYPE', DTD_out.root_name_start)
     565        marker = pablo.ScanThru(DTD_out.root_name_follow, lex.WS)
     566        require_system_id = 1
     567        ParseExternalID(marker, require_system_id, id_out)
     568        DTD_out.pubid_start = id_out.pubid_start
     569        DTD_out.pubid_end = id_out.pubid_end
     570        DTD_out.sysid_start = id_out.sysid_start
     571        DTD_out.sysid_end = id_out.sysid_end
     572        marker = id_out.end_marker
     573        marker = pablo.ScanThru(marker, id_out.end_marker | lex.WS)
     574        # Now must be at "[" for internal subset or ">", if none.
     575        if pablo.match('[', marker):
     576                marker = pablo.ScanThru(marker, marker | lex.WS)
     577                # Now enter the loop to parse the internal ENTITY, ELEMENT,
     578                # ATTLIST, NOTATION, PI, Comment and PErefs.
     579                while marker & lex.LAngle | pablo.match('%', marker):
     580                        if pablo.match('%', marker):
     581                                DTD_out.PERef_starts |= marker
     582                                name_follow = Pablo.ScanThru(marker, marker | lex.NameScan)
     583                                if name_follow &~ lex.Semicolon:
     584                                        error_tracker.NoteError('UnterminatedEntityRef', name_follow)
     585                                DTD_out.PERef_ends |= name_follow
     586
     587                        if marker & lex.LAngle:
     588                                marker = pablo.Advance(marker)
     589                                if marker & lex.QMark:
     590                                        DTD_out.PI_starts |= marker
     591                                        PI_name_follow = pablo.ScanThru(marker, lex.NameScan)
     592                                        PI_error = marker & PI_name_end
     593                                        if PI_error:
     594                                                error_tracker.NoteError('PINameExpected', PI_name_follow)
     595                                        DTD_out.PI_name_follows |= PI_name_follow
     596                                        PI_error = pablo.Advance(PI_name_follow & ~ lex.WS) & ~ PI_closer
     597                                        if PI_error:
     598                                                error_tracker.NoteError('UnterminatedPI', PI_error)
     599                                        marker = pablo.ScanTo(PI_name_follow, PI_closer)
     600                                        if pablo.atEOF(marker):
     601                                                error_tracker.NoteError('UnterminatedPI', marker)
     602                                        DTD_out.PI_ends |= marker
     603                                if pablo.match('!--', marker):
     604                                        # Advance 4 to avoid match a double hyphen too early.
     605                                        marker = pablo.Advance(pablo.ScanTo(pablo.AdvancebyPos(marker, 4), (pablo.Advance(lex.Hyphen)&lex.Hyphen)))
     606                                        if pablo.atEOF(marker):
     607                                                error_tracker.NoteError('UnterminatedComment', marker)
     608                                        if marker & ~ lex.RAngle:
     609                                                error_tracker.NoteError('IllegalSequenceInComment', marker)
     610                                if pablo.match('!ENTITY', marker):
     611                                        is_PE_entity = 0
     612                                        marker = pablo.AdvancebyPos(marker, 7)
     613                                        if marker &~ lex.WS:
     614                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     615                                        marker = pablo.ScanThru(marker, lex.WS)
     616                                        if pablo.match('%', marker):
     617                                                is_PE_entity = 1
     618                                                marker = pablo.Advance(marker)
     619                                                if marker &~ lex.WS:
     620                                                        error_tracker.NoteError('ExpectedWhitespace', marker)
     621                                        entity_name_follow = pablo.ScanThru(marker, lex.NameScan)
     622                                        if entity_name_follow & marker:
     623                                                error_tracker.NoteError('ExpectedPEName', marker)
     624                                        if entity_name_follow &~ lex.WS:
     625                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     626                                        entity_value_start = pablo.ScanThru(entity_name_follow, lex.WS)
     627                                        if entity_value_start & (lex.DQuote | lex.SQuote):
     628                                                dq = entity_value_start & lex.DQuote
     629                                                sq = entity_value_start & lex.SQuote
     630                                                entity_value_end = pablo.ScanTo(dq, lex.DQuote &~ dq) | pablo.ScanTo(sq, lex.SQuote &~ sq)
     631                                                marker = entity_value_end
     632                                        else:
     633                                                require_system_id = 1
     634                                                ParseExternalID(entity_value_start, require_system_id, id_out)
     635                                                m1 = pablo.Advance(id_out.end_marker)
     636                                                marker = pablo.ScanThru(m1, lex.WS)
     637                                                if pablo.match('NDATA', marker):
     638                                                        if marker & m1:
     639                                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     640                                                        if is_PE_entity:
     641                                                                error_tracker.NoteError('NDATANotValidForPE', marker)
     642                                                        marker = pablo.AdvancebyPos(marker, 5)
     643                                                        if marker &~ lex.WS:
     644                                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     645                                                        notation_name_start = pablo.ScanThru(marker, lex.WS)
     646                                                        notation_name_follow =  pablo.ScanThru(notation_name_start, lex.NameScan)
     647                                                        if notation_name_start & notation_name_follow:
     648                                                                error_tracker.NoteError('ExpectedNotationName', notation_name_start)
     649                                                        marker = notation_name_follow
     650                                        marker = pablo.ScanThru(marker, lex.WS)
     651                                        if marker &~ lex.RAngle:
     652                                                error_tracker.NoteError('UnterminatedEntityDecl', marker)
     653                                       
     654                                if pablo.match('!ELEMENT', marker):
     655                                        marker = pablo.AdvancebyPos(marker, 8)
     656                                        if marker &~ lex.WS:
     657                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     658                                        marker = pablo.ScanThru(marker, lex.WS)
     659                                        elem_name_follow = pablo.ScanThru(marker, lex.NameScan)
     660                                        if elem_name_follow & marker:
     661                                                error_tracker.NoteError('ExpectedElemName', marker)
     662                                        if elem_name_follow &~ lex.WS:
     663                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     664                                        marker = pablo.ScanTo(elem_name_follow, lex.RAngle)
     665                                       
     666                                if pablo.match('!ATTLIST', marker):
     667                                        marker = pablo.AdvancebyPos(marker, 8)
     668                                        if marker &~ lex.WS:
     669                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     670                                        marker = pablo.ScanThru(marker, lex.WS)
     671                                        att_name_follow = pablo.ScanThru(marker, lex.NameScan)
     672                                        if att_name_follow & marker:
     673                                                error_tracker.NoteError('ExpectedAttName', marker)
     674                                        #AttDef                                         
     675                                        AttDef_start = att_name_follow
     676                                        marker = pablo.ScanThru(AttDef_start, lex.WS)
     677                                        while marker & ~lex.RAngle:
     678                                                if AttDef_start &~ lex.WS:
     679                                                        error_tracker.NoteError('ExpectedWhitespace', marker)
     680                                                attdef_name_follow = pablo.ScanThru(marker, lex.NameScan)
     681                                                if attdef_name_follow & marker:
     682                                                        error_tracker.NoteError('ExpectedAttDefName', marker)
     683                                                if attdef_name_follow &~ lex.WS:
     684                                                        error_tracker.NoteError('ExpectedWhitespace', marker)
     685                                                marker = pablo.ScanThru(attdef_name_follow, lex.WS)
     686                                                #AttType-StringType
     687                                                if pablo.match('CDATA', marker):
     688                                                        marker = pablo.AdvancebyPos(marker, 5)
     689                                                #AttType-TokenizedType
     690                                                elif pablo.match('ID', marker):
     691                                                        marker = pablo.AdvancebyPos(marker, 2)
     692                                                elif pablo.match('IDREF', marker):
     693                                                        marker = pablo.AdvancebyPos(marker, 5)
     694                                                elif pablo.match('IDREFS', marker):
     695                                                        marker = pablo.AdvancebyPos(marker, 6)
     696                                                elif pablo.match('ENTITY', marker):
     697                                                        marker = pablo.AdvancebyPos(marker, 6)
     698                                                elif pablo.match('ENTITIES', marker):
     699                                                        marker = pablo.AdvancebyPos(marker, 8)
     700                                                elif pablo.match('NMTOKENS', marker):
     701                                                        marker = pablo.AdvancebyPos(marker, 8)
     702                                                elif pablo.match('NMTOKEN', marker):
     703                                                        marker = pablo.AdvancebyPos(marker, 7)
     704                                                #AttType-EnumeratedType-Notaion
     705                                                elif pablo.match('NOTATION', marker):
     706                                                        marker = pablo.AdvancebyPos(marker, 8)
     707                                                        if marker &~ lex.WS:
     708                                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     709                                                        marker = pablo.ScanThru(marker, lex.WS)
     710                                                        if pablo.match('(', marker):
     711                                                                marker = pablo.Advance(marker)
     712                                                        else:
     713                                                                error_tracker.NoteError('ExpectedParentheses', marker)
     714                                                        marker = pablo.ScanThru(marker, lex.WS)
     715                                                        notation_name_follow = pablo.ScanThru(marker, lex.NameScan)
     716                                                        if notation_name_follow & marker:
     717                                                                error_tracker.NoteError('ExpectedNotationName', marker)
     718                                                        marker = pablo.ScanThru(notation_name_follow, lex.WS)
     719                                                        while (~pablo.match(')', marker)) & marker:
     720                                                                if pablo.match('|', marker):
     721                                                                        marker = pablo.ScanThru(marker, marker | lex.WS)
     722                                                                        notation_name_follow = pablo.ScanThru(marker, lex.NameScan)
     723                                                                        if notation_name_follow & marker:
     724                                                                                error_tracker.NoteError('ExpectedNotationName', marker)
     725                                                                        marker = notation_name_follow
     726                                                                else:
     727                                                                        error_tracker.NoteError('ExpectedBar', marker)
     728                                                                marker = pablo.ScanThru(marker, lex.WS)
     729                                                #AttType-EnumeratedType-Enumeration
     730                                                elif pablo.match('(', marker):
     731                                                        marker = pablo.ScanThru(marker, marker | lex.WS)
     732                                                        nmtoken_follow = pablo.ScanThru(marker, lex.NameScan)
     733                                                        if nmtoken_follow & marker:
     734                                                                error_tracker.NoteError('ExpectedNmtoken', marker)
     735                                                        marker = pablo.ScanThru(nmtoken_follow, lex.WS)
     736                                                        while pablo.match('|', marker):
     737                                                                marker = pablo.ScanThru(marker, marker | lex.WS)
     738                                                                nmtoken_follow = pablo.ScanThru(marker, lex.NameScan)
     739                                                                if nmtoken_follow & marker:
     740                                                                        error_tracker.NoteError('ExpectedNmtoken', marker)
     741                                                                marker = pablo.ScanThru(nmtoken_follow, lex.WS)
     742                                                        if pablo.match(')', marker):
     743                                                                marker = pablo.Advance(marker)
     744                                                        else:
     745                                                                error_tracker.NoteError('ExpectedParentheses', marker)
     746                                                else:
     747                                                        error_tracker.NoteError('ExpectedAttType', marker)     
     748                                                #DefaultDecl   
     749                                                if marker &~ lex.WS:
     750                                                        print 'aaaaaaaaaaaaa'
     751                                                        error_tracker.NoteError('ExpectedWhitespace', marker)
     752                                                marker = pablo.ScanThru(marker, lex.WS)
     753                                                if pablo.match('#REQUIRED', marker):
     754                                                        marker = pablo.AdvancebyPos(marker, 9)
     755                                                elif pablo.match('#IMPLIED', marker):
     756                                                        marker = pablo.AdvancebyPos(marker, 8)
     757                                                elif pablo.match('#FIXED', marker):
     758                                                        marker = pablo.AdvancebyPos(marker, 6)
     759                                                elif marker & (lex.DQuote | lex.SQuote):
     760                                                        dq = marker & lex.DQuote
     761                                                        sq = marker & lex.SQuote
     762                                                        marker = pablo.ScanTo(dq, lex.DQuote &~ dq) | pablo.ScanTo(sq, lex.SQuote &~ sq)
     763                                                        marker = pablo.Advance(marker)
     764                                                else:
     765                                                        error_tracker.NoteError('ExpectedDefaultDecl', marker)
     766                                                AttDef_start = marker
     767                                                marker = pablo.ScanThru(AttDef_start, lex.WS)
     768                               
     769                                if pablo.match('!NOTATION', marker):
     770                                        marker = pablo.AdvancebyPos(marker, 9)
     771                                        if marker &~ lex.WS:
     772                                                error_tracker.NoteError('ExpectedWhitespace', marker)
     773                                        DTD_out.notation_name_start |= pablo.ScanThru(marker, lex.WS)
     774                                        DTD_out.notation_name_follow |= pablo.ScanThru(DTD_out.root_name_start, lex.NameScan)
     775                                        if DTD_out.notation_name_start & DTD_out.notation_name_follow:
     776                                                error_tracker.NoteError('ExpectedNotationName', DTD_out.notation_name_start)
     777                                        if DTD_out.notation_name_follow &~ lex.WS:
     778                                                error_tracker.NoteError('ExpectedWhitespace', DTD_out.notation_name_follow)
     779                                        marker = pablo.ScanThru(DTD_out.notation_name_follow, lex.WS)
     780                                        require_system_id = 0
     781                                        ParseExternalID(marker, require_system_id, id_out)
     782                                        DTD_out.notation_pubid_start |= id_out.pubid_start
     783                                        DTD_out.notation_pubid_end |= id_out.pubid_end
     784                                        DTD_out.notation_sysid_start |= id_out.sysid_start
     785                                        DTD_out.notation_sysid_end |= id_out.sysid_end
     786                                        marker = id_out.end_marker
     787                                        marker = pablo.ScanThru(marker, id_out.end_marker | lex.WS)
     788                                        if marker &~ lex.RAngle:
     789                                                error_tracker.NoteError('UnterminatedNotationDecl', marker)
     790                        # Now Advance past the closing ";" or ">" and scan for the
     791                        # next declaration, PI, Comment or PERef.
     792                        marker = pablo.ScanThru(marker, marker | lex.WS)
     793                if pablo.match(']', marker):
     794                        pablo.Advance(marker)
     795                        marker = pablo.ScanThru(marker, marker | lex.WS)
     796                else:
     797                        error_tracker.NoteError('UnterminatedintSubset', marker)
     798        # Finally must be at ">" to close the DTD decl.
     799        if marker &~ lex.RAngle:
     800                error_tracker.NoteError('UnterminatedDOCTYPE', marker)
     801
     802        return marker
    459803
    460804def Parse_refs(lex, marker, ref_Callouts):
     
    558902ctCDPI_Callouts = CtCDPI_Callouts()
    559903tag_Callouts = Tag_Callouts()
     904id_out = ID_Callouts()
    560905ref_Callouts = Ref_Callouts()
    561906check_streams = Check_streams()
     907DTD_out = DTD_Callouts()
    562908
    563909if __name__ == "__main__":
Note: See TracChangeset for help on using the changeset viewer.