Changeset 55 for trunk/orca/parse.c

Show
Ignore:
Timestamp:
02/18/06 18:19:46 (3 years ago)
Author:
krobillard
Message:

Implemented block parse.
orEqual() now works with words.
Added orDatatype macro.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/orca/parse.c

    r46 r55  
    8585*/ 
    8686static const OValue* evalParseStr( const OValue* rit, const OValue* rend, 
    87                                    const OString* str, int* spos ) 
     87                                   OIndex strN, int* spos ) 
    8888{ 
     89    OString* str; 
     90    int atom; 
    8991    int pos = *spos; 
    9092 
    91 cont: 
     93match: 
    9294 
    9395    while( rit != rend ) 
    9496    { 
    95         switch( rit->type ) 
     97        switch( orType(rit) ) 
    9698        { 
    9799            case OT_WORD: 
    98                 if( orAtom(rit) == OR_ATOM_OPT ) 
     100                atom = orAtom(rit); 
     101 
     102                if( atom == OR_ATOM_OPT ) 
    99103                { 
    100104                    const OValue* r2 = rit + 1; 
     
    103107                        return 0; 
    104108 
    105                     evalParseStr( r2, r2 + 1, str, &pos ); 
     109                    evalParseStr( r2, r2 + 1, strN, &pos ); 
    106110                    if( orErrorThrown ) 
    107111                        return 0; 
    108112                    rit += 2; 
    109113                } 
    110                 else if( orAtom(rit) == OR_ATOM_ANY ) 
     114                else if( atom == OR_ATOM_ANY ) 
    111115                { 
    112116                    //until [not eval-pstr second it] 
     
    126130                    if( orIs(r2, OT_BITSET) ) 
    127131                    { 
    128                         const uint8_t* it  = str->byteArray + pos; 
    129                         const uint8_t* end = str->byteArray + str->used; 
     132                        const uint8_t* it; 
     133                        const uint8_t* end; 
     134 
     135                        str = orStringPtr(strN); 
     136                        it  = str->byteArray + pos; 
     137                        end = str->byteArray + str->used; 
    130138 
    131139                        end = thruChars( r2, it, end ); 
     
    140148                    } 
    141149                } 
    142                 else if( orAtom(rit) == OR_ATOM_SOME ) 
     150                else if( atom == OR_ATOM_SOME ) 
    143151                { 
    144152                    const OValue* found; 
    145                     const OValue* rend2; 
     153                    const OValue* r2end; 
    146154                    const OValue* r2 = rit + 1; 
    147155 
     
    161169                        blk2 = orBLOCK(r2); 
    162170                        r2    = blk2->values + r2->series.it; 
    163                         rend2 = blk2->values + blk2->used; 
    164  
    165                         found = evalParseStr( r2, rend2, str, &pos ); 
     171                        r2end = blk2->values + blk2->used; 
     172 
     173                        found = evalParseStr( r2, r2end, strN, &pos ); 
    166174                        if( found ) 
    167175                        { 
    168176                            do 
    169177                            { 
    170                                 found = evalParseStr( r2, rend2, str, &pos ); 
     178                                found = evalParseStr( r2, r2end, strN, &pos ); 
    171179                                if( orErrorThrown ) 
    172180                                    return 0; 
     
    182190                    else if( orIs(r2, OT_BITSET) ) 
    183191                    { 
    184                         const uint8_t* it  = str->byteArray + pos; 
    185                         const uint8_t* end = str->byteArray + str->used; 
     192                        const uint8_t* it; 
     193                        const uint8_t* end; 
     194 
     195                        str = orStringPtr(strN); 
     196                        it  = str->byteArray + pos; 
     197                        end = str->byteArray + str->used; 
    186198 
    187199                        end = thruChars( r2, it, end ); 
     
    204216                    } 
    205217                } 
    206                 else if( orAtom(rit) == OR_ATOM_BREAK ) 
     218                else if( atom == OR_ATOM_BREAK ) 
    207219                { 
    208220                    return rit; 
    209221                } 
    210                 else if( orAtom(rit) == OR_ATOM_BAR ) 
     222                else if( atom == OR_ATOM_BAR ) 
    211223                { 
    212224                    goto complete; 
    213225                } 
    214                 else if( orAtom(rit) == OR_ATOM_TO ) 
     226                else if( atom == OR_ATOM_TO ) 
    215227                { 
    216228                    int si; 
     
    220232                        return 0; 
    221233 
    222                     if( ! orIsString(r2->type) ) 
    223                         return 0; 
    224  
    225                     si = orFindString(str, pos, orSTRING(r2), r2->series.it); 
     234                    if( ! orIsString( orType(r2) ) ) 
     235                        return 0; 
     236 
     237                    si = orFindString( orStringPtr(strN), pos, 
     238                                       orSTRING(r2), r2->series.it ); 
    226239                    if( si > -1 ) 
    227240                    { 
     
    234247                    } 
    235248                } 
     249                else if( atom == OR_ATOM_SKIP ) 
     250                { 
     251                    //if( pos >= str->used ) 
     252                    //    return 0; 
     253                    ++rit; 
     254                    ++pos; 
     255                } 
    236256                /* 
    237                 else if( orAtom(rit) == OR_ATOM_THRU ) 
    238                 { 
    239                 } 
    240                 else if( orAtom(rit) == OR_ATOM_SKIP ) 
    241                 { 
    242                 } 
    243                 else if( orAtom(rit) == OR_ATOM_SET ) 
    244                 { 
    245                 } 
    246                 else if( orAtom(rit) == OR_ATOM_COPY ) 
     257                else if( atom == OR_ATOM_THRU ) 
     258                { 
     259                } 
     260                else if( atom == OR_ATOM_SET ) 
     261                { 
     262                } 
     263                else if( atom == OR_ATOM_COPY ) 
    247264                { 
    248265                } 
     
    257274                    if( orIs(wval, OT_BLOCK) ) 
    258275                    { 
     276                        // Same as case OT_BLOCK below. 
    259277                        cblk = orBLOCK( wval ); 
    260278                        wval = evalParseStr( cblk->values + wval->series.it, 
    261279                                             cblk->values + cblk->used, 
    262                                              str, &pos ); 
     280                                             strN, &pos ); 
    263281                        if( wval ) 
    264282                            ++rit; 
     
    269287                    { 
    270288                        OString* bin = orSTRING( wval ); 
    271                         int c = str->charArray[ pos ]; 
     289                        int c; 
     290 
     291                        str = orStringPtr(strN); 
     292                        c = str->charArray[ pos ]; 
    272293                        if( orBitIsSet( bin->byteArray, c ) ) 
    273294                        { 
     
    294315 
    295316                orSetTF( wval, OT_STRING ); 
    296                 orSetSeries( wval, orStringN(str), pos ); 
     317                orSetSeries( wval, strN, pos ); 
    297318 
    298319                ++rit; 
     
    318339                    while( 1 ) 
    319340                    { 
    320                         if( ! evalParseStr( r2, r2 + 1, str, &pos ) ) 
     341                        if( ! evalParseStr( r2, r2 + 1, strN, &pos ) ) 
    321342                            break; 
    322343                        ++count; 
     
    334355 
    335356            case OT_CHAR: 
     357                str = orStringPtr(strN); 
    336358                if( str->charArray[ pos ] == orInt(rit) ) 
    337359                { 
     
    351373                found = evalParseStr( cblk->values + rit->series.it, 
    352374                                      cblk->values + cblk->used, 
    353                                       str, &pos ); 
     375                                      strN, &pos ); 
    354376                if( found ) 
    355377                    ++rit; 
     
    360382 
    361383            case OT_PAREN: 
     384            { 
    362385                orEvalBlock( orBLOCK(rit), rit->series.it ); 
     386                if( orErrorThrown ) 
     387                    return 0; 
    363388                ++rit; 
     389            } 
    364390                break; 
    365391 
     
    368394                OString* mstr = orSTRING(rit); 
    369395 
     396                str = orStringPtr(strN); 
    370397                /* 
    371398                if( useCase ) 
     
    383410 
    384411            default: 
    385                 orError( "invalid parse value %s", orDatatypeName(rit->type) ); 
     412                orError( "invalid parse value %s", 
     413                         orDatatypeName( orType(rit) ) ); 
    386414                return 0; 
    387415        } 
     
    404432    { 
    405433        pos = *spos; 
    406         goto cont; 
     434        goto match; 
    407435    } 
    408436    return 0; 
     
    412440/* 
    413441   strV points to string OValue. 
    414    ruleV points to rule block OValue. 
     442   rules points to rule block OValue. 
    415443*/ 
    416 static void parseStringRules( OValue* strV, OValue* ruleV, int all, 
     444static void parseStringRules( OValue* strV, OValue* rules, int all, 
    417445                              int useCase ) 
    418446{ 
    419     OBlock* rblk = orBLOCK(ruleV); 
    420     const OValue* rit  = rblk->values + ruleV->series.it; 
     447    OBlock* rblk = orBLOCK(rules); 
     448    const OValue* rit  = rblk->values + rules->series.it; 
    421449    const OValue* rend = rblk->values + rblk->used; 
    422     OString* str = orSTRING(strV); 
    423     int si = strV->series.it; 
    424     int lresult = 0; 
     450    OIndex strN  = strV->series.n; 
     451    int si       = strV->series.it; 
     452    int lresult  = 0; 
     453 
    425454 
    426455    (void) all; 
    427456    (void) useCase; 
    428457 
    429     rit = evalParseStr( rit, rend, str, &si ); 
     458    orRefAvailErr( 2 ); 
     459    orRefPush( OT_BLOCK, rules->series.n ); 
     460    orRefPush( OT_STRING, strN ); 
     461 
     462    rit = evalParseStr( rit, rend, strN, &si ); 
     463 
     464    orRefPop( 2 ); 
     465 
    430466    if( rit ) 
    431467    { 
     468        OString* str = orStringPtr(strN); 
    432469        if( si >= str->used ) 
    433470            lresult = 1; 
     
    527564 
    528565 
     566/*==========================================================================*/ 
     567 
     568 
     569/** 
     570  Returns index in blkV where fval is found or -1 if fval is not found. 
     571*/ 
     572static int _findBlock( const OBlock* blk, OIndex pos, const OValue* fval ) 
     573{ 
     574    OValue* it  = blk->values + pos; 
     575    OValue* end = blk->values + blk->used; 
     576 
     577    // TODO: If fval is block then all values must match. 
     578 
     579    assert( pos <= blk->used ); 
     580 
     581    while( it != end ) 
     582    { 
     583        if( orEqual(it, fval) ) 
     584            return it - blk->values; 
     585        ++it; 
     586    } 
     587    return -1; 
     588} 
     589 
     590 
     591/* 
     592   Returns zero if matching rule not found. 
     593*/ 
     594static const OValue* evalParseBlock( const OValue* rit, const OValue* rend, 
     595                                     OIndex blkN, int* spos ) 
     596{ 
     597    OBlock* blk; 
     598    OValue* val; 
     599    int atom; 
     600    int pos = *spos; 
     601 
     602match: 
     603 
     604    while( rit != rend ) 
     605    { 
     606        switch( orType(rit) ) 
     607        { 
     608            case OT_WORD: 
     609                atom = orAtom(rit); 
     610 
     611                if( atom < OT_COUNT ) 
     612                { 
     613                    // Datatype 
     614                    blk = orBlockPtr(blkN); 
     615                    val = blk->values + pos; 
     616                    if( orType(val) != orAtom(rit) ) 
     617                    { 
     618                        if( orAtom(rit) == OT_NUMBER ) 
     619                        { 
     620                            if( orIs(val, OT_INTEGER) || orIs(val, OT_DECIMAL) ) 
     621                                goto datatype_match; 
     622                        } 
     623                        goto failed; 
     624                    } 
     625datatype_match: 
     626                    ++rit; 
     627                    ++pos; 
     628                } 
     629                else if( atom == OR_ATOM_OPT ) 
     630                { 
     631                    const OValue* r2 = rit + 1; 
     632 
     633                    if( r2 == rend ) 
     634                        return 0; 
     635 
     636                    evalParseBlock( r2, r2 + 1, blkN, &pos ); 
     637                    if( orErrorThrown ) 
     638                        return 0; 
     639                    rit += 2; 
     640                } 
     641                else if( atom == OR_ATOM_ANY ) 
     642                { 
     643                    const OValue* r2 = rit + 1; 
     644 
     645                    if( r2 == rend ) 
     646                        return 0; 
     647 
     648                    if( orIs(r2, OT_WORD) ) 
     649                    { 
     650                        OBlock* ctxBlk; 
     651                        orWordVal( r2, ctxBlk, r2 ); 
     652                    } 
     653 
     654                    if( orIs(r2, OT_BLOCK) ) 
     655                    { 
     656                        const OValue* found; 
     657                        const OValue* r2end; 
     658                        OBlock* blk2; 
     659 
     660                        blk2 = orBLOCK(r2); 
     661                        r2    = blk2->values + r2->series.it; 
     662                        r2end = blk2->values + blk2->used; 
     663 
     664                        do 
     665                        { 
     666                            found = evalParseBlock( r2, r2end, blkN, &pos ); 
     667                            if( orErrorThrown ) 
     668                                return 0; 
     669                        } 
     670                        while( found ); 
     671 
     672                        rit += 2; 
     673                    } 
     674                    else 
     675                    { 
     676                        orError( "parse any expected block" ); 
     677                        return 0; 
     678                    } 
     679                } 
     680                else if( atom == OR_ATOM_SOME ) 
     681                { 
     682                    const OValue* r2 = rit + 1; 
     683 
     684                    if( r2 == rend ) 
     685                        return 0; 
     686 
     687                    if( orIs(r2, OT_WORD) ) 
     688                    { 
     689                        OBlock* ctxBlk; 
     690                        orWordVal( r2, ctxBlk, r2 ); 
     691                    } 
     692 
     693                    if( orIs(r2, OT_BLOCK) ) 
     694                    { 
     695                        const OValue* found; 
     696                        const OValue* r2end; 
     697                        OBlock* blk2; 
     698 
     699                        blk2 = orBLOCK(r2); 
     700                        r2    = blk2->values + r2->series.it; 
     701                        r2end = blk2->values + blk2->used; 
     702 
     703                        found = evalParseBlock( r2, r2end, blkN, &pos ); 
     704                        if( found ) 
     705                        { 
     706                            do 
     707                            { 
     708                                found = evalParseBlock( r2, r2end, blkN, &pos ); 
     709                                if( orErrorThrown ) 
     710                                    return 0; 
     711                            } 
     712                            while( found ); 
     713 
     714                            rit += 2; 
     715                        } 
     716                        else 
     717                        { 
     718                            goto failed_eval; 
     719                        } 
     720                    } 
     721                    else 
     722                    { 
     723                        orError( "parse some expected block" ); 
     724                        return 0; 
     725                    } 
     726                } 
     727                else if( atom == OR_ATOM_BREAK ) 
     728                { 
     729                    return rit; 
     730                } 
     731                else if( atom == OR_ATOM_BAR ) 
     732                { 
     733                    goto complete; 
     734                } 
     735                else if( atom == OR_ATOM_TO ) 
     736                { 
     737                    int si; 
     738                    const OValue* r2 = rit + 1; 
     739 
     740                    if( r2 == rend ) 
     741                        return 0; 
     742 
     743                    si = _findBlock( orBlockPtr(blkN), pos, r2 ); 
     744                    if( si < 0 ) 
     745                        goto failed; 
     746 
     747                    pos = si; 
     748                    rit += 2; 
     749                } 
     750                else if( atom == OR_ATOM_SKIP ) 
     751                { 
     752                    //if( pos >= ser->used ) 
     753                    //    return 0; 
     754                    ++rit; 
     755                    ++pos; 
     756                } 
     757                /* 
     758                else if( atom == OR_ATOM_THRU ) 
     759                { 
     760                } 
     761                else if( atom == OR_ATOM_SET ) 
     762                { 
     763                } 
     764                else if( atom == OR_ATOM_COPY ) 
     765                { 
     766                } 
     767                */ 
     768                else 
     769                { 
     770                    const OValue* wval; 
     771                    const OBlock* cblk; 
     772 
     773                    orWordVal( rit, cblk, wval ); 
     774 
     775                    if( orIs(wval, OT_BLOCK) ) 
     776                    { 
     777                        // Same as case OT_BLOCK below. 
     778                        cblk = orBLOCK( wval ); 
     779                        wval = evalParseBlock( cblk->values + wval->series.it, 
     780                                               cblk->values + cblk->used, 
     781                                               blkN, &pos ); 
     782                        if( wval ) 
     783                            ++rit; 
     784                        else 
     785                            goto failed_eval; 
     786                    } 
     787                    else 
     788                    { 
     789                        orError( "parse expected block" ); 
     790                        return 0; 
     791                    } 
     792                } 
     793                break; 
     794 
     795            case OT_SETWORD: 
     796            { 
     797                OValue* wval; 
     798                OBlock* ctxBlk; 
     799 
     800                orWordVal( rit, ctxBlk, wval ); 
     801 
     802                orSetTF( wval, OT_BLOCK ); 
     803                orSetSeries( wval, blkN, pos ); 
     804 
     805                ++rit; 
     806            } 
     807                break; 
     808 
     809            case OT_LITWORD: 
     810            { 
     811                blk = orBlockPtr(blkN); 
     812                val = blk->values + pos; 
     813                if( orIs(val, OT_WORD) && (orAtom(val) == orAtom(rit)) ) 
     814                { 
     815                    ++rit; 
     816                    ++pos; 
     817                } 
     818                else 
     819                    goto failed; 
     820            } 
     821                break; 
     822 
     823            case OT_INTEGER: 
     824            { 
     825                const OValue* r2 = rit + 1; 
     826 
     827                if( r2 == rend ) 
     828                    return 0; 
     829 
     830                if( orIs(r2, OT_INTEGER) ) 
     831                { 
     832                    int count = 0; 
     833                    int maxCount = orInt(r2); 
     834 
     835                    ++r2; 
     836                    if( r2 == rend ) 
     837                        return 0; 
     838 
     839                    while( 1 ) 
     840                    { 
     841                        if( ! evalParseBlock( r2, r2 + 1, blkN, &pos ) ) 
     842                            break; 
     843                        ++count; 
     844                    } 
     845 
     846                    if( orErrorThrown ) 
     847                        return 0; 
     848                    if( (count >= orInt(rit)) && (count <= maxCount) ) 
     849                        rit += 3; 
     850                    else 
     851                        goto failed; 
     852                } 
     853            } 
     854                break; 
     855#if 0 
     856            case OT_DATATYPE: 
     857            { 
     858                OValue* val; 
     859 
     860                blk = orBlockPtr(blkN); 
     861                val = blk->values + pos; 
     862                if( orType(val) == orDatatype(rit) ) 
     863                { 
     864                    ++rit; 
     865                    ++pos; 
     866                } 
     867                else 
     868                    goto failed; 
     869            } 
     870                break; 
     871#endif 
     872            case OT_BLOCK: 
     873            { 
     874                const OValue* found; 
     875                const OBlock* cblk; 
     876 
     877                cblk = orBLOCK( rit ); 
     878                found = evalParseBlock( cblk->values + rit->series.it, 
     879                                        cblk->values + cblk->used, 
     880                                        blkN, &pos ); 
     881                if( found ) 
     882                    ++rit; 
     883                else 
     884                    goto failed_eval; 
     885            } 
     886                break; 
     887 
     888            case OT_PAREN: 
     889            { 
     890                orEvalBlock( orBLOCK(rit), rit->series.it ); 
     891                if( orErrorThrown ) 
     892                    return 0; 
     893                ++rit; 
     894            } 
     895                break; 
     896 
     897            default: 
     898                orError( "invalid parse value %s", 
     899                         orDatatypeName( orType(rit) ) ); 
     900                return 0; 
     901        } 
     902    } 
     903 
     904complete: 
     905 
     906    *spos = pos; 
     907    return rit; 
     908 
     909failed_eval: 
     910 
     911    if( orErrorThrown ) 
     912        return 0;