Changeset 305

Show
Ignore:
Timestamp:
05/27/08 20:12:57 (8 months ago)
Author:
pragma
Message:

Vastly improved version of Enki2 with gobs of new support. Overall, this version is very stable.

  • Improved D code generation
  • Added (optional) AST support
  • Added (optional) positional char parser support
  • Errors now report line and col numbers, if available.
  • Changed "not" operator from "!" to "" to help disambiguate the syntax.
  • Changed behavior of "not" to "parse anything but this" where "anything" is the implicit "any" terminal.
  • Added "nop" terminal.
  • Backend now adds "eoi", "any" and "nop" automatically w/o need of a prototype decl.
  • Added non-trival XML parser example
  • Added Python parser example (untested)
  • Added calculator example
  • Stubbed out D and Wiki parser examples
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/enki2/enki/Backend.d

    r303 r305  
    3232import tango.io.Stdout; 
    3333 
     34 
    3435abstract class BackendT(CharT,BaseClass = Object) : BaseClass{ 
    3536    mixin AllTypesMixin!(CharT); 
     
    4142    public this(){ 
    4243        ruleSet = new RuleSet(); 
     44         
     45        ruleSet.addRule(new RulePrototype("nop","bool")); 
     46        ruleSet.addRule(new RulePrototype("any","String")); 
     47        ruleSet.addRule(new RulePrototype("eoi","bool")); 
    4348    } 
    4449     
     
    6974        ruleSet.semanticPass(attributes); 
    7075    } 
     76     
     77    public void runDirective(String name,String[] args){ 
     78        if(name == "include"){ 
     79            foreach(arg; args){ 
     80                includeFile(arg); 
     81            } 
     82        } 
     83        else{ 
     84            throw new Exception("Unknown directive '" ~ name ~ "'"); 
     85        } 
     86    } 
    7187 
    7288    public void toCode(Generator)(bool test=false){ 
  • trunk/enki2/enki/EnkiLexer.d

    r303 r305  
    3333class EnkiLexerT(CharT):EnkiLexerBase!(CharT){ 
    3434 
    35     /* 
    36     any = String; 
    37     */ 
    38  
    39     /* 
    40     eoi = bool; 
    41     */ 
     35 
     36 
    4237 
    4338    /* 
    4439    Tokens 
    4540        = EnkiToken[] tokens 
    46         ::= (Whitespace | SlashStarComment | SlashSlashComment | NestingComment | RegexLiteral:~tokens | StringLiteral:~tokens | Number:~tokens | Hex:~tokens | Identifier:~tokens | LiteralToken:~tokens | @err!("Unexpected char"))* eoi; 
     41        ::= (Whitespace | SlashStarComment | SlashSlashComment | NestingComment | RegexLiteral:~tokens | StringLiteral:~tokens | Number:~tokens | Hex:~tokens | SpecialToken:~tokens | Identifier:~tokens | LiteralToken:~tokens | @err!("Unexpected char"))* eoi; 
    4742    */ 
    4843    bool parse_Tokens(){ 
     
    5348        start2: 
    5449            // (terminator) 
    55             terminator5: 
    5650                // Production 
    5751                if(parse_eoi()){ 
     
    6559                        goto start2; 
    6660                    } 
     61                term5: 
     62                    // Production 
     63                    if(parse_SlashStarComment()){ 
     64                        goto start2; 
     65                    } 
    6766                term6: 
    6867                    // Production 
    69                     if(parse_SlashStarComment()){ 
     68                    if(parse_SlashSlashComment()){ 
    7069                        goto start2; 
    7170                    } 
    7271                term7: 
    7372                    // Production 
    74                     if(parse_SlashSlashComment()){ 
     73                    if(parse_NestingComment()){ 
    7574                        goto start2; 
    7675                    } 
    7776                term8: 
    78                     // Production 
    79                     if(parse_NestingComment()){ 
    80                         goto start2; 
    81                     } 
    82                 term9: 
    8377                    // Production 
    8478                    if(parse_RegexLiteral()){ 
     
    8680                        goto start2; 
    8781                    } 
    88                 term10
     82                term9
    8983                    // Production 
    9084                    if(parse_StringLiteral()){ 
     
    9286                        goto start2; 
    9387                    } 
    94                 term11
     88                term10
    9589                    // Production 
    9690                    if(parse_Number()){ 
     
    9892                        goto start2; 
    9993                    } 
    100                 term12
     94                term11
    10195                    // Production 
    10296                    if(parse_Hex()){ 
     
    10498                        goto start2; 
    10599                    } 
     100                term12: 
     101                    // Production 
     102                    if(parse_SpecialToken()){ 
     103                        smartAppend(var_tokens,getMatchValue!(EnkiToken)()); 
     104                        goto start2; 
     105                    } 
    106106                term13: 
    107107                    // Production 
     
    118118                term15: 
    119119                    // Literal 
    120                         auto literal16 = err("Unexpected char"); 
     120                        err("Unexpected char"); 
    121121            goto start2; 
    122122        end3: 
     
    139139        debug Stdout("parse_Whitespace").newline; 
    140140        // Iterator 
    141         size_t counter6 = 0; 
     141        size_t counter5 = 0; 
    142142        start2: 
    143143            // (terminator) 
    144             terminator5: 
    145144            if(!hasMore()){ 
    146145                goto end3; 
     
    148147            // (expression) 
    149148            expr4: 
    150                 // OrGroup increment7 
     149                // OrGroup increment6 
    151150                    // Terminal 
    152151                    if(match(" ")){ 
    153                         goto increment7; 
     152                        goto increment6; 
     153                    } 
     154                term7: 
     155                    // Terminal 
     156                    if(match("\t")){ 
     157                        goto increment6; 
    154158                    } 
    155159                term8: 
    156160                    // Terminal 
    157                     if(match("\t")){ 
    158                         goto increment7
     161                    if(match("\r")){ 
     162                        goto increment6
    159163                    } 
    160164                term9: 
    161                     // Terminal 
    162                     if(match("\r")){ 
    163                         goto increment7; 
    164                     } 
    165                 term10: 
    166165                    // Terminal 
    167166                    if(!match("\n")){ 
    168167                        goto end3; 
    169168                    } 
    170             increment7
     169            increment6
    171170            // (increment expr count) 
    172                 counter6 ++; 
     171                counter5 ++; 
    173172            goto start2; 
    174173        end3: 
    175174            // (range test) 
    176                 if(!((counter6 >= 1))){ 
     175                if(!((counter5 >= 1))){ 
    177176                    goto fail1; 
     177                    goto pass0; 
    178178                } 
    179179        // Rule 
     
    206206                    start7: 
    207207                        // (terminator) 
    208                         terminator10: 
    209208                            // Terminal 
    210209                            if(match("*/")){ 
     
    237236    SlashSlashComment 
    238237        $String err="Expected terminating newline" 
    239         ::= "//" ?!(err) any* "\n"
     238        ::= "//" ?!(err) any* "\n" | eoi
    240239    */ 
    241240    bool parse_SlashSlashComment(){ 
     
    254253                    start7: 
    255254                        // (terminator) 
    256                         terminator10: 
    257                             // Terminal 
    258                             if(match("\n")){ 
    259                                 goto end8; 
    260                             } 
     255                            // OrGroup end8 
     256                                // Terminal 
     257                                if(match("\n")){ 
     258                                    goto end8; 
     259                                } 
     260                            term10: 
     261                                // Production 
     262                                if(parse_eoi()){ 
     263                                    goto end8; 
     264                                } 
    261265                        // (expression) 
    262266                        expr9: 
     
    302306                    start7: 
    303307                        // (terminator) 
    304                         terminator10: 
    305308                            // Terminal 
    306309                            if(match("+/")){ 
     
    314317                                    goto start7; 
    315318                                } 
    316                             term11
     319                            term10
    317320                                // Production 
    318321                                if(!parse_any()){ 
     
    358361                    start7: 
    359362                        // (terminator) 
    360                         terminator10: 
    361363                            // Terminal 
    362364                            if(match("`")){ 
     
    416418                        start8: 
    417419                            // (terminator) 
    418                             terminator11: 
    419420                                // Terminal 
    420421                                if(match("\"\"\"")){ 
     
    437438        term2: 
    438439            // AndGroup 
    439                 auto position14 = getPos(); 
     440                auto position13 = getPos(); 
    440441                    // Terminal 
    441442                    if(!match("\"")){ 
    442                         goto fail15
    443                     } 
    444                 term16
     443                        goto fail14
     444                    } 
     445                term15
    445446                    // ErrorPoint 
    446447                        // Iterator 
    447                         start18
     448                        start17
    448449                            // (terminator) 
    449                             terminator21: 
    450450                                // Terminal 
    451451                                if(match("\"")){ 
    452                                     goto end19
     452                                    goto end18
    453453                                } 
    454454                            // (expression) 
    455                             expr20
     455                            expr19
    456456                                // Production 
    457457                                if(!parse_StringChar()){ 
    458                                     goto fail17
     458                                    goto fail16
    459459                                } 
    460460                                smartAppend(var_text,getMatchValue!(String)()); 
    461                             goto start18
    462                         end19
     461                            goto start17
     462                        end18
    463463                            goto pass0; 
    464                     fail17
     464                    fail16
    465465                        error(var_err2); 
    466                 fail15
    467                 setPos(position14); 
    468         term12
     466                fail14
     467                setPos(position13); 
     468        term11
    469469            // AndGroup 
    470                 auto position23 = getPos(); 
     470                auto position21 = getPos(); 
    471471                    // Terminal 
    472472                    if(!match("\'")){ 
    473                         goto fail24
    474                     } 
    475                 term25
     473                        goto fail22
     474                    } 
     475                term23
    476476                    // ErrorPoint 
    477477                        // Iterator 
    478                         start27
     478                        start25
    479479                            // (terminator) 
    480                             terminator30: 
    481480                                // Terminal 
    482481                                if(match("\'")){ 
    483                                     goto end28
     482                                    goto end26
    484483                                } 
    485484                            // (expression) 
    486                             expr29
     485                            expr27
    487486                                // Production 
    488487                                if(!parse_StringChar()){ 
    489                                     goto fail26
     488                                    goto fail24
    490489                                } 
    491490                                smartAppend(var_text,getMatchValue!(String)()); 
    492                             goto start27
    493                         end28
     491                            goto start25
     492                        end26
    494493                            goto pass0; 
    495                     fail26
     494                    fail24
    496495                        error(var_err2); 
    497                 fail24
    498                 setPos(position23); 
     496                fail22
     497                setPos(position21); 
    499498                goto fail1; 
    500499        // Rule 
     
    612611                    term37: 
    613612                        // Literal 
    614                             auto literal43 = err("Unexpected escape sequence"); 
     613                            err("Unexpected escape sequence"); 
    615614                            goto pass0; 
    616615                fail5: 
     
    636635    Hex 
    637636        = EnkiToken HexToken(String text) 
    638         $String err="Expected one, two, four or eight hex digits" 
    639         ::= "#" ?!(err) ({#30-#39 | #41-#46 | #61-#66}<1,2,4,8>):text; 
     637        $String err="Expected two, four or eight hex digits" 
     638        ::= "#" ?!(err) ({#30-#39 | #41-#46 | #61-#66}<2,4,8>):text; 
    640639    */ 
    641640    bool parse_Hex(){ 
    642641        debug Stdout("parse_Hex").newline; 
    643         String var_err = "Expected one, two, four or eight hex digits"; 
     642        String var_err = "Expected two, four or eight hex digits"; 
    644643        String var_text; 
    645644 
     
    655654                        auto position7 = getPos(); 
    656655                        // Iterator 
    657                         size_t counter13 = 0; 
     656                        size_t counter12 = 0; 
    658657                        start9: 
    659658                            // (terminator) 
    660                             terminator12: 
    661                             if(counter13 == 8){ 
     659                            if(counter12 == 8){ 
    662660                                goto end10; 
    663661                            } 
    664                             goto start9; 
    665662                            // (expression) 
    666663                            expr11: 
    667                                 // OrGroup increment14 
     664                                // OrGroup increment13 
    668665                                    // CharRange 
    669                                     if(match('\x30','\x39')){ 
    670                                         goto increment14; 
     666                                    if(match(0x30,0x39)){ 
     667                                        goto increment13; 
     668                                    } 
     669                                term14: 
     670                                    // CharRange 
     671                                    if(match(0x41,0x46)){ 
     672                                        goto increment13; 
    671673                                    } 
    672674                                term15: 
    673675                                    // CharRange 
    674                                     if(match('\x41','\x46')){ 
    675                                         goto increment14; 
    676                                     } 
    677                                 term16: 
    678                                     // CharRange 
    679                                     if(!match('\x61','\x66')){ 
     676                                    if(!match(0x61,0x66)){ 
    680677                                        goto end10; 
    681678                                    } 
    682                             increment14
     679                            increment13
    683680                            // (increment expr count) 
    684                                 counter13 ++; 
     681                                counter12 ++; 
    685682                            goto start9; 
    686683                        end10: 
    687684                            // (range test) 
    688                                 if(!((counter13 >= 1) || (counter13 == 1) || (counter13 == 2) || (counter13 == 4) || (counter13 == 8))){ 
     685                                if(!((counter12 >= 1) || (counter12 == 2) || (counter12 == 4) || (counter12 == 8))){ 
    689686                                    goto fail6; 
     687                                    goto pass8; 
    690688                                } 
    691689                        pass8: 
     
    718716 
    719717        // Iterator 
    720         size_t counter6 = 0; 
     718        size_t counter5 = 0; 
    721719        start2: 
    722720            // (terminator) 
    723             terminator5: 
    724721            if(!hasMore()){ 
    725722                goto end3; 
     
    728725            expr4: 
    729726                // CharRange 
    730                 if(!match('\x30','\x39')){ 
     727                if(!match(0x30,0x39)){ 
    731728                    goto end3; 
    732729                } 
    733730                smartAssign(var_text,getMatchValue!(String)()); 
    734             increment7
     731            increment6
    735732            // (increment expr count) 
    736                 counter6 ++; 
     733                counter5 ++; 
    737734            goto start2; 
    738735        end3: 
    739736            // (range test) 
    740                 if(!((counter6 >= 1))){ 
     737                if(!((counter5 >= 1))){ 
    741738                    goto fail1; 
     739                    goto pass0; 
    742740                } 
    743741        // Rule 
     
    767765                    // OrGroup term7 
    768766                        // CharRange 
    769                         if(match('\x41','\x5A')){ 
     767                        if(match(0x41,0x5A)){ 
    770768                            goto term7; 
    771769                        } 
    772770                    term8: 
    773771                        // CharRange 
    774                         if(match('\x61','\x7A')){ 
     772                        if(match(0x61,0x7A)){ 
    775773                            goto term7; 
    776774                        } 
     
    785783                        start10: 
    786784                            // (terminator) 
    787                             terminator13: 
    788785                            if(!hasMore()){ 
    789786                                goto end11; 
     
    793790                                // OrGroup start10 
    794791                                    // CharRange 
    795                                     if(match('\x30','\x39')){ 
     792                                    if(match(0x30,0x39)){ 
     793                                        goto start10; 
     794                                    } 
     795                                term13: 
     796                                    // CharRange 
     797                                    if(match(0x41,0x5A)){ 
    796798                                        goto start10; 
    797799                                    } 
    798800                                term14: 
    799801                                    // CharRange 
    800                                     if(match('\x41','\x5A')){ 
     802                                    if(match(0x61,0x7A)){ 
    801803                                        goto start10; 
    802804                                    } 
    803805                                term15: 
    804                                     // CharRange 
    805                                     if(match('\x61','\x7A')){ 
    806                                         goto start10; 
    807                                     } 
    808                                 term16: 
    809806                                    // Terminal 
    810807                                    if(!match("_")){ 
     
    832829 
    833830    /* 
     831    SpecialToken 
     832        = EnkiToken CreateToken(String text,EnkiToken.ValueType tok) 
     833        ::= "new" @TOK_NEW:tok | "::=" @TOK_RULEASSIGN:tok | "?!" @TOK_ERRORPOINT:tok | ".." @TOK_RANGE:tok; 
     834    */ 
     835    bool parse_SpecialToken(){ 
     836        debug Stdout("parse_SpecialToken").newline; 
     837        EnkiToken.ValueType var_tok; 
     838        String var_text; 
     839 
     840        // OrGroup pass0 
     841            // AndGroup 
     842                auto position4 = getPos(); 
     843                    // Terminal 
     844                    if(!match("new")){ 
     845                        goto fail5; 
     846                    } 
     847                term6: 
     848                    // Literal 
     849                        auto literal7 = TOK_NEW; 
     850                        smartAssign(var_tok,literal7); 
     851                        goto pass0; 
     852                fail5: 
     853                setPos(position4); 
     854        term2: 
     855            // AndGroup 
     856                auto position10 = getPos(); 
     857                    // Terminal 
     858                    if(!match("::=")){ 
     859                        goto fail11; 
     860                    } 
     861                term12: 
     862                    // Literal 
     863                        auto literal13 = TOK_RULEASSIGN; 
     864                        smartAssign(var_tok,literal13); 
     865                        goto pass0; 
     866                fail11: 
     867                setPos(position10); 
     868        term8: 
     869            // AndGroup 
     870                auto position16 = getPos(); 
     871                    // Terminal 
     872                    if(!match("?!")){ 
     873                        goto fail17; 
     874                    } 
     875                term18: 
     876                    // Literal 
     877                        auto literal19 = TOK_ERRORPOINT; 
     878                        smartAssign(var_tok,literal19); 
     879                        goto pass0; 
     880                fail17: 
     881                setPos(position16); 
     882        term14: 
     883            // AndGroup 
     884                auto position21 = getPos(); 
     885                    // Terminal 
     886                    if(!match("..")){ 
     887                        goto fail22; 
     888                    } 
     889                term23: 
     890                    // Literal 
     891                        auto literal24 = TOK_RANGE; 
     892                        smartAssign(var_tok,literal24); 
     893                        goto pass0; 
     894                fail22: 
     895                setPos(position21); 
     896                goto fail1; 
     897        // Rule 
     898        pass0: 
     899            setMatchValue(CreateToken(var_text,var_tok)); 
     900            debug Stdout.format("\tparse_SpecialToken passed: {0}",getMatchValue!(EnkiToken)).newline; 
     901            return true; 
     902        fail1: 
     903            setMatchValue((EnkiToken).init); 
     904            debug Stdout.format("\tparse_SpecialToken failed").newline; 
     905            return false; 
     906    } 
     907 
     908    /* 
    834909    LiteralToken 
    835910        = EnkiToken LiteralToken(String text) 
    836         ::= ("::=" | "!(" | "?!" | ".." | "," | ":" | "~" | ";" | "=" | "," | "{" | "}" | "(" | ")" | "[" | "]" | "<" | ">" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "!" | "?" | "/" | "-" | "+" | "|" | "."):text; 
     911        ::= (#21-#2F | #3A-#40 | #5B-#60 | #7B-#7E):text; 
    837912    */ 
    838913    bool parse_LiteralToken(){ 
     
    843918            auto position2 = getPos(); 
    844919            // OrGroup pass3 
    845                 // Terminal 
    846                 if(match("::=")){ 
     920                // CharRange 
     921                if(match(0x21,0x2F)){ 
    847922                    goto pass3; 
    848923                } 
    849924            term4: 
    850                 // Terminal 
    851                 if(match("!(")){ 
     925                // CharRange 
     926                if(match(0x3A,0x40)){ 
    852927                    goto pass3; 
    853928                } 
    854929            term5: 
    855                 // Terminal 
    856                 if(match("?!")){ 
     930                // CharRange 
     931                if(match(0x5B,0x60)){ 
    857932                    goto pass3; 
    858933                } 
    859934            term6: 
    860                 // Terminal 
    861                 if(match("..")){ 
    862                     goto pass3; 
    863                 } 
    864             term7: 
    865                 // Terminal 
    866                 if(match(",")){ 
    867                     goto pass3; 
    868                 } 
    869             term8: 
    870                 // Terminal 
    871                 if(match(":")){ 
    872                     goto pass3; 
    873                 } 
    874             term9: 
    875                 // Terminal 
    876                 if(match("~")){ 
    877                     goto pass3; 
    878                 } 
    879             term10: 
    880                 // Terminal 
    881                 if(match(";")){ 
    882                     goto pass3; 
    883                 } 
    884             term11: 
    885                 // Terminal 
    886                 if(match("=")){ 
    887                     goto pass3; 
    888                 } 
    889             term12: 
    890                 // Terminal 
    891                 if(match(",")){ 
    892                     goto pass3; 
    893                 } 
    894             term13: 
    895                 // Terminal 
    896                 if(match("{")){ 
    897                     goto pass3; 
    898                 } 
    899             term14: 
    900                 // Terminal 
    901                 if(match("}")){ 
    902                     goto pass3; 
    903                 } 
    904             term15: 
    905                 // Terminal 
    906                 if(match("(")){ 
    907                     goto pass3; 
    908                 } 
    909             term16: 
    910                 // Terminal 
    911                 if(match(")")){ 
    912                     goto pass3; 
    913                 } 
    914             term17: 
    915                 // Terminal 
    916                 if(match("[")){ 
    917                     goto pass3; 
    918                 } 
    919             term18: 
    920                 // Terminal 
    921                 if(match("]")){ 
    922                     goto pass3; 
    923                 } 
    924             term19: 
    925                 // Terminal 
    926                 if(match("<")){ 
    927                     goto pass3; 
    928                 } 
    929             term20: 
    930                 // Terminal 
    931                 if(match(">")){ 
    932                     goto pass3; 
    933                 } 
    934             term21: 
    935                 // Terminal 
    936                 if(match("@")){ 
    937                     goto pass3; 
    938                 } 
    939             term22: 
    940                 // Terminal 
    941                 if(match("#")){ 
    942                     goto pass3; 
    943                 } 
    944             term23: 
    945                 // Terminal 
    946                 if(match("$")){ 
    947                     goto pass3; 
    948                 } 
    949             term24: 
    950                 // Terminal 
    951                 if(match("%")){ 
    952                     goto pass3; 
    953                 } 
    954             term25: 
    955                 // Terminal 
    956                 if(match("^")){ 
    957                     goto pass3; 
    958                 } 
    959             term26: 
    960                 // Terminal 
    961                 if(match("&")){ 
    962                     goto pass3; 
    963                 } 
    964