Changeset 303

Show
Ignore:
Timestamp:
05/19/08 23:58:18 (7 months ago)
Author:
pragma
Message:

Massive update for Enki V2.

  • Added Preliminary AST support (untested)
  • Added Positional support for better error messages
  • Added Include Directive support (untested)
  • Improved D codegen support with enhanced goto elimination, and smart iteration
  • D and BNF generators now properly handle string escape sequences
  • D-style \xHH sequences in BNF strings are deprecated (will re-visit these later)
  • Bugfixed BNF and Bootstrap generators to correctly round-trip the Enki lexer & parser
  • Dropped .bat files in favor of (portable) .sh files.
Files:

Legend:

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

    r302 r303  
    3232import tango.io.Stdout; 
    3333 
    34 class BackendT(CharT,BaseClass = Object) : BaseClass{ 
     34abstract class BackendT(CharT,BaseClass = Object) : BaseClass{ 
    3535    mixin AllTypesMixin!(CharT); 
    3636     
    3737    protected AttributeSet attributes; 
    38     protected RuleSet ruleSet; 
     38    public RuleSet ruleSet; 
    3939    protected String[] imports; 
    4040 
     
    4242        ruleSet = new RuleSet(); 
    4343    } 
    44  
    45  
    46     public void includeFile(String name){ 
    47         //TODO handle failure 
    48     /*  auto parser = new Backend(); 
    49         parser.parse(name); 
    50  
    51         // mesh data 
    52         foreach(aliasName,ruleName; parser.ruleAliases){ 
    53             ruleAliases[aliasName] = ruleName; 
    54         } 
    55         attributes.mesh(parser.attributes); 
    56         ruleSet.mesh(parser.ruleSet); 
    57  
    58         imports ~= name;*/ 
    59     } 
    60  
     44     
     45    abstract void includeFile(String filename); 
     46     
    6147    public void addRule(Rule rule){ 
    6248        ruleSet.addRule(rule); 
     
    8975 
    9076        //TODO: handle includes 
     77        //generator.visit(imports); 
    9178        generator.visit(attributes); 
    9279        generator.visit(ruleSet); 
  • trunk/enki2/enki/EnkiLexer.d

    r302 r303  
    4444    Tokens 
    4545        = EnkiToken[] tokens 
    46         ::= [{Whitespace | SlashStarComment | SlashSlashComment | NestingComment | RegexLiteral:~tokens | StringLiteral:~tokens | Number:~tokens | Hex:~tokens | Identifier:~tokens | LiteralToken:~tokens | @err!("Unexpected char {0}")}] eoi; 
     46        ::= (Whitespace | SlashStarComment | SlashSlashComment | NestingComment | RegexLiteral:~tokens | StringLiteral:~tokens | Number:~tokens | Hex:~tokens | Identifier:~tokens | LiteralToken:~tokens | @err!("Unexpected char"))* eoi; 
    4747    */ 
    4848    bool parse_Tokens(){ 
    49         debug Stdout("parse_Tokens ").newline; 
     49        debug Stdout("parse_Tokens").newline; 
    5050        EnkiToken[] var_tokens; 
    5151 
    5252        // Iterator 
    53         //0 ranges 
    54             start2: 
     53        start2: 
    5554            // (terminator) 
     55            terminator5: 
    5656                // Production 
    5757                if(parse_eoi()){ 
    5858                    goto end3; 
    5959                } 
    60                 else{ 
    61                     goto expr4; 
    62                 } 
    63             // (iterator expression) 
     60            // (expression) 
    6461            expr4: 
    65                 // OrGroup 
     62                // OrGroup start2 
    6663                    // Production 
    67                     auto position6 = getPos(); 
    6864                    if(parse_Whitespace()){ 
    6965                        goto start2; 
    7066                    } 
    71                     else{ 
    72                         goto term5; 
    73                     } 
    74                 term5: 
     67                term6: 
    7568                    // Production 
    76                     auto position8 = getPos(); 
    7769                    if(parse_SlashStarComment()){ 
    7870                        goto start2; 
    7971                    } 
    80                     else{ 
    81                         goto term7; 
    82                     } 
    8372                term7: 
    8473                    // Production 
    85                     auto position10 = getPos(); 
    8674                    if(parse_SlashSlashComment()){ 
    8775                        goto start2; 
    8876                    } 
    89                     else{ 
    90                         goto term9; 
    91                     } 
    92                 term9: 
     77                term8: 
    9378                    // Production 
    94                     auto position12 = getPos(); 
    9579                    if(parse_NestingComment()){ 
    9680                        goto start2; 
    9781                    } 
    98                     else{ 
    99                         goto term11; 
    100                     } 
    101                 term11: 
     82                term9: 
    10283                    // Production 
    10384                    if(parse_RegexLiteral()){ 
     
    10586                        goto start2; 
    10687                    } 
    107                     else{ 
    108                         goto term13; 
    109                     } 
    110                 term13: 
     88                term10: 
    11189                    // Production 
    11290                    if(parse_StringLiteral()){ 
     
    11492                        goto start2; 
    11593                    } 
    116                     else{ 
    117                         goto term14; 
    118                     } 
    119                 term14: 
     94                term11: 
    12095                    // Production 
    12196                    if(parse_Number()){ 
     
    12398                        goto start2; 
    12499                    } 
    125                     else{ 
    126                         goto term15; 
    127                     } 
    128                 term15: 
     100                term12: 
    129101                    // Production 
    130102                    if(parse_Hex()){ 
     
    132104                        goto start2; 
    133105                    } 
    134                     else{ 
    135                         goto term16; 
    136                     } 
    137                 term16: 
     106                term13: 
    138107                    // Production 
    139108                    if(parse_Identifier()){ 
     
    141110                        goto start2; 
    142111                    } 
    143                     else{ 
    144                         goto term17; 
    145                     } 
    146                 term17: 
     112                term14: 
    147113                    // Production 
    148114                    if(parse_LiteralToken()){ 
     
    150116                        goto start2; 
    151117                    } 
    152                     else{ 
    153                         goto term18; 
    154                     } 
    155                 term18: 
     118                term15: 
    156119                    // Literal 
    157                         auto literal19 = err("Unexpected char {0}"); 
    158                         goto start2; 
     120                        auto literal16 = err("Unexpected char"); 
    159121            goto start2; 
    160             end3: 
    161             goto pass0; 
     122        end3: 
    162123        // Rule 
    163124        pass0: 
     
    167128        fail1: 
    168129            setMatchValue((EnkiToken[]).init); 
    169             debug Stdout.format("\t parse_Tokens failed").newline; 
     130            debug Stdout.format("\tparse_Tokens failed").newline; 
    170131            return false; 
    171132    } 
     
    173134    /* 
    174135    Whitespace 
    175         ::= {" " | "\t" | "\r" | "\n"}<1..0>
     136        ::= {" " | "\t" | "\r" | "\n"}
    176137    */ 
    177138    bool parse_Whitespace(){ 
    178         debug Stdout("parse_Whitespace ").newline; 
     139        debug Stdout("parse_Whitespace").newline; 
    179140        // Iterator 
    180         //1 ranges 
    181             size_t counter6 = 0; 
    182             start2: 
    183             // (iterator expression) 
     141        size_t counter6 = 0; 
     142        start2: 
     143            // (terminator) 
     144            terminator5: 
     145            if(!hasMore()){ 
     146                goto end3; 
     147            } 
     148            // (expression) 
    184149            expr4: 
    185                 // OrGroup 
     150                // OrGroup increment7 
    186151                    // Terminal 
    187152                    if(match(" ")){ 
    188153                        goto increment7; 
    189                     } 
    190                     else{ 
    191                         goto term8; 
    192154                    } 
    193155                term8: 
     
    196158                        goto increment7; 
    197159                    } 
    198                     else{ 
    199                         goto term9; 
    200                     } 
    201160                term9: 
    202161                    // Terminal 
     
    204163                        goto increment7; 
    205164                    } 
    206                     else{ 
    207                         goto term10; 
    208                     } 
    209165                term10: 
    210166                    // Terminal 
    211                     if(match("\n")){ 
    212                         goto increment7; 
    213                     } 
    214                     else{ 
     167                    if(!match("\n")){ 
    215168                        goto end3; 
    216169                    } 
     170            increment7: 
    217171            // (increment expr count) 
    218             increment7: 
    219172                counter6 ++; 
    220173            goto start2; 
    221            end3: 
     174        end3: 
    222175            // (range test) 
    223                 if((counter6 >= 1)){ 
    224                     goto pass0; 
    225                 }else{ 
     176                if(!((counter6 >= 1))){ 
    226177                    goto fail1; 
    227178                } 
     
    231182            return true; 
    232183        fail1: 
    233             debug Stdout.format("\t parse_Whitespace failed").newline; 
     184            debug Stdout.format("\tparse_Whitespace failed").newline; 
    234185            return false; 
    235186    } 
     
    237188    /* 
    238189    SlashStarComment 
    239         $String err="Expected closing \x2A\x2F
    240         ::= "/*" ?!(err) [{any}] "\x2A\x2F"; 
     190        $String err="Expected closing *\/
     191        ::= "/*" ?!(err) any* "*\/"; 
    241192    */ 
    242193    bool parse_SlashStarComment(){ 
    243         debug Stdout("parse_SlashStarComment ").newline; 
    244         String var_err = "Expected closing \x2A\x2F"; 
     194        debug Stdout("parse_SlashStarComment").newline; 
     195        String var_err = "Expected closing */"; 
    245196 
    246197        // AndGroup 
    247             auto position2 = getPos(); 
    248                 // Terminal 
    249                 if(match("/*")){ 
    250                     goto term4; 
    251                 } 
    252                 else{ 
    253                     goto fail3; 
    254                 } 
    255             term4: 
     198            auto position3 = getPos(); 
     199                // Terminal 
     200                if(!match("/*")){ 
     201                    goto fail4; 
     202                } 
     203            term5: 
    256204                // ErrorPoint 
    257205                    // Iterator 
    258                     //0 ranges 
    259                         start6: 
     206                    start7: 
    260207                        // (terminator) 
     208                        terminator10: 
    261209                            // Terminal 
    262                             if(match("\x2A\x2F")){ 
    263                                 goto end7
     210                            if(match("*/")){ 
     211                                goto end8
    264212                            } 
    265                             else{ 
    266                                 goto expr8; 
     213                        // (expression) 
     214                        expr9: 
     215                            // Production 
     216                            if(!parse_any()){ 
     217                                goto fail6; 
    267218                            } 
    268                         // (iterator expression) 
    269                         expr8: 
    270                             // Production 
    271                             if(parse_any()){ 
    272                                 goto start6; 
    273                             } 
    274                             else{ 
    275                                 goto fail5; 
    276                             } 
    277                         goto start6; 
    278                         end7: 
     219                        goto start7; 
     220                    end8: 
    279221                        goto pass0; 
    280                 fail5
     222                fail6
    281223                    error(var_err); 
    282                     goto fail3; 
    283             fail3: 
    284             setPos(position2); 
     224            fail4: 
     225            setPos(position3); 
    285226            goto fail1; 
    286227        // Rule 
     
    289230            return true; 
    290231        fail1: 
    291             debug Stdout.format("\t parse_SlashStarComment failed").newline; 
     232            debug Stdout.format("\tparse_SlashStarComment failed").newline; 
    292233            return false; 
    293234    } 
     
    296237    SlashSlashComment 
    297238        $String err="Expected terminating newline" 
    298         ::= "//" ?!(err) [{any}] "\n"; 
     239        ::= "//" ?!(err) any* "\n"; 
    299240    */ 
    300241    bool parse_SlashSlashComment(){ 
    301         debug Stdout("parse_SlashSlashComment ").newline; 
     242        debug Stdout("parse_SlashSlashComment").newline; 
    302243        String var_err = "Expected terminating newline"; 
    303244 
    304245        // AndGroup 
    305             auto position2 = getPos(); 
    306                 // Terminal 
    307                 if(match("//")){ 
    308                     goto term4; 
    309                 } 
    310                 else{ 
    311                     goto fail3; 
    312                 } 
    313             term4: 
     246            auto position3 = getPos(); 
     247                // Terminal 
     248                if(!match("//")){ 
     249                    goto fail4; 
     250                } 
     251            term5: 
    314252                // ErrorPoint 
    315253                    // Iterator 
    316                     //0 ranges 
    317                         start6: 
     254                    start7: 
    318255                        // (terminator) 
     256                        terminator10: 
    319257                            // Terminal 
    320258                            if(match("\n")){ 
    321                                 goto end7
     259                                goto end8
    322260                            } 
    323                             else{ 
    324                                 goto expr8; 
     261                        // (expression) 
     262                        expr9: 
     263                            // Production 
     264                            if(!parse_any()){ 
     265                                goto fail6; 
    325266                            } 
    326                         // (iterator expression) 
    327                         expr8: 
    328                             // Production 
    329                             if(parse_any()){ 
    330                                 goto start6; 
    331                             } 
    332                             else{ 
    333                                 goto fail5; 
    334                             } 
    335                         goto start6; 
    336                         end7: 
     267                        goto start7; 
     268                    end8: 
    337269                        goto pass0; 
    338                 fail5
     270                fail6
    339271                    error(var_err); 
    340                     goto fail3; 
    341             fail3: 
    342             setPos(position2); 
     272            fail4: 
     273            setPos(position3); 
    343274            goto fail1; 
    344275        // Rule 
     
    347278            return true; 
    348279        fail1: 
    349             debug Stdout.format("\t parse_SlashSlashComment failed").newline; 
     280            debug Stdout.format("\tparse_SlashSlashComment failed").newline; 
    350281            return false; 
    351282    } 
     
    353284    /* 
    354285    NestingComment 
    355         $String err="Expected closing * /" 
    356         ::= "/+" ?!(err) [{NestingComment | any}] "\x2B\x2F"; 
     286        $String err="Expected closing +\/" 
     287        ::= "/+" ?!(err) (NestingComment | any)* "+\/"; 
    357288    */ 
    358289    bool parse_NestingComment(){ 
    359         debug Stdout("parse_NestingComment ").newline; 
    360         String var_err = "Expected closing * /"; 
     290        debug Stdout("parse_NestingComment").newline; 
     291        String var_err = "Expected closing +/"; 
    361292 
    362293        // AndGroup 
    363             auto position2 = getPos(); 
    364                 // Terminal 
    365                 if(match("/+")){ 
    366                     goto term4; 
    367                 } 
    368                 else{ 
    369                     goto fail3; 
    370                 } 
    371             term4: 
     294            auto position3 = getPos(); 
     295                // Terminal 
     296                if(!match("/+")){ 
     297                    goto fail4; 
     298                } 
     299            term5: 
    372300                // ErrorPoint 
    373301                    // Iterator 
    374                     //0 ranges 
    375                         start6: 
     302                    start7: 
    376303                        // (terminator) 
     304                        terminator10: 
    377305                            // Terminal 
    378306                            if(match("+/")){ 
    379                                 goto end7
     307                                goto end8
    380308                            } 
    381                             else{ 
    382                                 goto expr8; 
    383                             } 
    384                         // (iterator expression) 
    385                         expr8: 
    386                             // OrGroup 
     309                        // (expression) 
     310                        expr9: 
     311                            // OrGroup start7 
    387312                                // Production 
    388                                 auto position10 = getPos(); 
    389313                                if(parse_NestingComment()){ 
    390                                     goto start6; 
    391                                 } 
    392                                 else{ 
    393                                     goto term9; 
    394                                 } 
    395                             term9: 
     314                                    goto start7; 
     315                                } 
     316                            term11: 
    396317                                // Production 
    397                                 if(parse_any()){ 
    398                                     goto start6; 
    399                                 } 
    400                                 else{ 
    401                                     goto fail5; 
    402                                 } 
    403                         goto start6; 
    404                         end7: 
     318                                if(!parse_any()){ 
     319                                    goto fail6; 
     320                                } 
     321                        goto start7; 
     322                    end8: 
    405323                        goto pass0; 
    406                 fail5
     324                fail6
    407325                    error(var_err); 
    408                     goto fail3; 
    409             fail3: 
    410             setPos(position2); 
     326            fail4: 
     327            setPos(position3); 
    411328            goto fail1; 
    412329        // Rule 
     
    415332            return true; 
    416333        fail1: 
    417             debug Stdout.format("\t parse_NestingComment failed").newline; 
     334            debug Stdout.format("\tparse_NestingComment failed").newline; 
    418335            return false; 
    419336    } 
     
    423340        = EnkiToken RegexToken(String text) 
    424341        $String err="Expected closing `" 
    425         ::= "`" ?!(err) [{any:text}] "`"; 
     342        ::= "`" ?!(err) (any:text)* "`"; 
    426343    */ 
    427344    bool parse_RegexLiteral(){ 
    428         debug Stdout("parse_RegexLiteral ").newline; 
     345        debug Stdout("parse_RegexLiteral").newline; 
    429346        String var_err = "Expected closing `"; 
    430347        String var_text; 
    431348 
    432349        // AndGroup 
    433             auto position2 = getPos(); 
    434                 // Terminal 
    435                 if(match("`")){ 
    436                     goto term4; 
    437                 } 
    438                 else{ 
    439                     goto fail3; 
    440                 } 
    441             term4: 
     350            auto position3 = getPos(); 
     351                // Terminal 
     352                if(!match("`")){ 
     353                    goto fail4; 
     354                } 
     355            term5: 
    442356                // ErrorPoint 
    443357                    // Iterator 
    444                     //0 ranges 
    445                         start6: 
     358                    start7: 
    446359                        // (terminator) 
     360                        terminator10: 
    447361                            // Terminal 
    448362                            if(match("`")){ 
    449                                 goto end7
     363                                goto end8
    450364                            } 
    451                             else{ 
    452                                 goto expr8; 
     365                        // (expression) 
     366                        expr9: 
     367                            // Production 
     368                            if(!parse_any()){ 
     369                                goto fail6; 
    453370                            } 
    454                         // (iterator expression) 
    455                         expr8: 
    456                             // Production 
    457                             if(parse_any()){ 
    458                                 smartAssign(var_text,getMatchValue!(String)()); 
    459                                 goto start6; 
    460                             } 
    461                             else{ 
    462                                 goto fail5; 
    463                             } 
    464                         goto start6; 
    465                         end7: 
     371                            smartAssign(var_text,getMatchValue!(String)()); 
     372                        goto start7; 
     373                    end8: 
    466374                        goto pass0; 
    467                 fail5
     375                fail6
    468376                    error(var_err); 
    469                     goto fail3; 
    470             fail3: 
    471             setPos(position2); 
     377            fail4: 
     378            setPos(position3); 
    472379            goto fail1; 
    473380        // Rule 
     
    478385        fail1: 
    479386            setMatchValue((EnkiToken).init); 
    480             debug Stdout.format("\t parse_RegexLiteral failed").newline; 
     387            debug Stdout.format("\tparse_RegexLiteral failed").newline; 
    481388            return false; 
    482389    } 
     
    487394        $String err1="Expected closing \"\"\"" 
    488395        $String err2="Expected closing \"" 
    489         $String err3="Expected closing '" 
    490         ::= "\"\"\"" ?!(err1) ([{any}] "\"\"\""):text | "\"" ?!(err2) [{"\" any:~text | any:~text}] "\"" | "'" ?!(err3) [{"\" any:~text | any:~text}] "'"
     396        $String err3="Expected closing \'" 
     397        ::= ("\"\"\"" ?!(err1) (any:~text)* "\"\"\"") | ("\"" ?!(err2) (StringChar:~text)* "\"") | ("\'" ?!(err2) (StringChar:~text)* "\'")
    491398    */ 
    492399    bool parse_StringLiteral(){ 
    493         debug Stdout("parse_StringLiteral ").newline; 
     400        debug Stdout("parse_StringLiteral").newline; 
    494401        String var_text; 
    495402        String var_err1 = "Expected closing \"\"\""; 
    496403        String var_err2 = "Expected closing \""; 
    497         String var_err3 = "Expected closing '"; 
    498  
    499         // OrGroup 
     404        String var_err3 = "Expected closing \'"; 
     405 
     406        // OrGroup pass0 
    500407            // AndGroup 
    501                 auto position3 = getPos(); 
     408                auto position4 = getPos(); 
    502409                    // Terminal 
    503                     if(match("\"\"\"")){ 
    504                         goto term5; 
    505                     } 
    506                     else{ 
    507                         goto fail4; 
    508                     } 
    509                 term5: 
     410                    if(!match("\"\"\"")){ 
     411                        goto fail5; 
     412                    } 
     413                term6: 
    510414                    // ErrorPoint 
    511                         // Group 
    512                             auto position7 = getPos(); 
    513                             // Iterator 
    514                             //0 ranges 
    515                                 start9: 
    516                                 // (terminator) 
    517                                     // Terminal 
    518                                     if(match("\"\"\"")){ 
    519                                         goto end10; 
    520                                     } 
    521                                     else{ 
    522                                         goto expr11; 
    523                                     } 
    524                                 // (iterator expression) 
    525                                 expr11: 
    526                                     // Production 
    527                                     if(parse_any()){ 
    528                                         goto start9; 
    529                                     } 
    530                                     else{ 
    531                                         goto fail6; 
    532                                     } 
    533                                 goto start9; 
    534                                 end10: 
    535                                 goto pass8; 
    536                             pass8: 
    537                             smartAssign(var_text,slice(position7,getPos())); 
     415                        // Iterator 
     416                        start8: 
     417                            // (terminator) 
     418                            terminator11: 
     419                                // Terminal 
     420                                if(match("\"\"\"")){ 
     421                                    goto end9; 
     422                                } 
     423                            // (expression) 
     424                            expr10: 
     425                                // Production 
     426                                if(!parse_any()){ 
     427                                    goto fail7; 
     428                                } 
     429                                smartAppend(var_text,getMatchValue!(String)()); 
     430                            goto start8; 
     431                        end9: 
    538432                            goto pass0; 
    539                     fail6
     433                    fail7
    540434                        error(var_err1); 
    541                         goto fail4; 
    542                 fail4: 
    543                 setPos(position3); 
    544                 goto term2; 
     435                fail5: 
     436                setPos(position4); 
    545437        term2: 
    546438            // AndGroup 
    547                 auto position13 = getPos(); 
     439                auto position14 = getPos(); 
    548440                    // Terminal 
    549                     if(match("\"")){ 
    550                         goto term15; 
    551                     } 
    552                     else{ 
    553                         goto fail14; 
    554                     } 
    555                 term15: 
     441                    if(!match("\"")){ 
     442                        goto fail15; 
     443                    } 
     444                term16: 
    556445                    // ErrorPoint 
    557446                        // Iterator 
    558                         //0 ranges 
    559                             start17: 
     447                        start18: 
    560448                            // (terminator) 
     449                            terminator21: 
    561450                                // Terminal 
    562451                                if(match("\"")){ 
    563                                     goto end18; 
    564                                 } 
    565                                 else{ 
    566                                     goto expr19; 
    567                                 } 
    568                             // (iterator expression) 
    569                             expr19: 
    570                                 // OrGroup 
    571                                     // AndGroup 
    572                                         auto position21 = getPos(); 
    573                                             // Terminal 
    574                                             if(match("\\")){ 
    575                                                 goto term23; 
    576                                             } 
    577                                             else{ 
    578                                                 goto fail22; 
    579                                             } 
    580                                         term23: 
    581                                             // Production 
    582                                             if(parse_any()){ 
    583                                                 smartAppend(var_text,getMatchValue!(String)()); 
    584                                         &nbs