Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 644

Show
Ignore:
Timestamp:
08/28/10 20:38:24 (14 years ago)
Author:
walter
Message:

Issue 2477 - Trailing comma in array literal sometimes accepted, sometimes not

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/parse.c

    r633 r644  
    16891689 * Parse template parameter list. 
    16901690 * Input: 
    16911691 *      flag    0: parsing "( list )" 
    16921692 *              1: parsing non-empty "list )" 
    16931693 */ 
    16941694 
    16951695TemplateParameters *Parser::parseTemplateParameterList(int flag) 
    16961696{ 
    16971697    TemplateParameters *tpl = new TemplateParameters(); 
    16981698 
    16991699    if (!flag && token.value != TOKlparen) 
    17001700    {   error("parenthesized TemplateParameterList expected following TemplateIdentifier"); 
    17011701        goto Lerr; 
    17021702    } 
    17031703    nextToken(); 
    17041704 
    17051705    // Get array of TemplateParameters 
    17061706    if (flag || token.value != TOKrparen) 
    17071707    {   int isvariadic = 0; 
    17081708 
    1709         while (1
     1709        while (token.value != TOKrparen
    17101710        {   TemplateParameter *tp; 
    17111711            Identifier *tp_ident = NULL; 
    17121712            Type *tp_spectype = NULL; 
    17131713            Type *tp_valtype = NULL; 
    17141714            Type *tp_defaulttype = NULL; 
    17151715            Expression *tp_specvalue = NULL; 
    17161716            Expression *tp_defaultvalue = NULL; 
    17171717            Token *t; 
    17181718 
    17191719            // Get TemplateParameter 
    17201720 
    17211721            // First, look ahead to see if it is a TypeParameter or a ValueParameter 
    17221722            t = peek(&token); 
    17231723            if (token.value == TOKalias) 
    17241724            {   // AliasParameter 
    17251725                nextToken(); 
    17261726                Type *spectype = NULL; 
    17271727                if (isDeclaration(&token, 2, TOKreserved, NULL)) 
    17281728                { 
    17291729                    spectype = parseType(&tp_ident); 
     
    19421942 */ 
    19431943 
    19441944Objects *Parser::parseTemplateArgumentList() 
    19451945{ 
    19461946    //printf("Parser::parseTemplateArgumentList()\n"); 
    19471947    if (token.value != TOKlparen && token.value != TOKlcurly) 
    19481948    {   error("!(TemplateArgumentList) expected following TemplateIdentifier"); 
    19491949        return new Objects(); 
    19501950    } 
    19511951    return parseTemplateArgumentList2(); 
    19521952} 
    19531953 
    19541954Objects *Parser::parseTemplateArgumentList2() 
    19551955{ 
    19561956    //printf("Parser::parseTemplateArgumentList2()\n"); 
    19571957    Objects *tiargs = new Objects(); 
    19581958    enum TOK endtok = TOKrparen; 
    19591959    nextToken(); 
    19601960 
    19611961    // Get TemplateArgumentList 
    1962     if (token.value != endtok) 
    1963     { 
    1964         while (1) 
    1965         { 
     1962    while (token.value != endtok) 
     1963    { 
    19661964            // See if it is an Expression or a Type 
    19671965            if (isDeclaration(&token, 0, TOKreserved, NULL)) 
    19681966            {   // Template argument is a type 
    19691967                Type *ta = parseType(); 
    19701968                tiargs->push(ta); 
    19711969            } 
    19721970            else 
    19731971            {   // Template argument is an expression 
    19741972                Expression *ea = parseAssignExp(); 
    19751973 
    19761974                if (ea->op == TOKfunction) 
    19771975                {   FuncLiteralDeclaration *fd = ((FuncExp *)ea)->fd; 
    19781976                    if (fd->type->ty == Tfunction) 
    19791977                    { 
    19801978                        TypeFunction *tf = (TypeFunction *)fd->type; 
    19811979                        /* If there are parameters that consist of only an identifier, 
    19821980                         * rather than assuming the identifier is a type, as we would 
    19831981                         * for regular function declarations, assume the identifier 
    19841982                         * is the parameter name, and we're building a template with 
    19851983                         * a deduced type. 
     
    20092007 
    20102008                        if (tpl) 
    20112009                        {   // Wrap a template around function fd 
    20122010                            Dsymbols *decldefs = new Dsymbols(); 
    20132011                            decldefs->push(fd); 
    20142012                            TemplateDeclaration *tempdecl = 
    20152013                                new TemplateDeclaration(fd->loc, fd->ident, tpl, NULL, decldefs, 0); 
    20162014                            tempdecl->literal = 1;      // it's a template 'literal' 
    20172015                            tiargs->push(tempdecl); 
    20182016                            goto L1; 
    20192017                        } 
    20202018                    } 
    20212019                } 
    20222020 
    20232021                tiargs->push(ea); 
    20242022            } 
    20252023         L1: 
    20262024            if (token.value != TOKcomma) 
    20272025                break; 
    20282026            nextToken(); 
    2029         } 
    20302027    } 
    20312028    check(endtok, "template argument list"); 
    20322029    return tiargs; 
    20332030} 
    20342031 
    20352032/***************************** 
    20362033 * Parse single template argument, to support the syntax: 
    20372034 *      foo!arg 
    20382035 * Input: 
    20392036 *      current token is the arg 
    20402037 */ 
    20412038 
    20422039Objects *Parser::parseTemplateArgument() 
    20432040{ 
    20442041    //printf("parseTemplateArgument()\n"); 
    20452042    Objects *tiargs = new Objects(); 
    20462043    Type *ta; 
    20472044    switch (token.value) 
    20482045    { 
    20492046        case TOKidentifier: 
     
    52485245            {   // (arguments) { statements... } 
    52495246                save = TOKdelegate; 
    52505247                goto case_delegate; 
    52515248            } 
    52525249            // ( expression ) 
    52535250            nextToken(); 
    52545251            e = parseExpression(); 
    52555252            e->parens = 1; 
    52565253            check(loc, TOKrparen); 
    52575254            break; 
    52585255 
    52595256        case TOKlbracket: 
    52605257        {   /* Parse array literals and associative array literals: 
    52615258             *  [ value, value, value ... ] 
    52625259             *  [ key:value, key:value, key:value ... ] 
    52635260             */ 
    52645261            Expressions *values = new Expressions(); 
    52655262            Expressions *keys = NULL; 
    52665263 
    52675264            nextToken(); 
    5268             if (token.value != TOKrbracket) 
    5269             { 
    5270                 while (token.value != TOKeof) 
    5271                 { 
     5265            while (token.value != TOKrbracket && token.value != TOKeof) 
     5266            { 
    52725267                    Expression *e = parseAssignExp(); 
    52735268                    if (token.value == TOKcolon && (keys || values->dim == 0)) 
    52745269                    {   nextToken(); 
    52755270                        if (!keys) 
    52765271                            keys = new Expressions(); 
    52775272                        keys->push(e); 
    52785273                        e = parseAssignExp(); 
    52795274                    } 
    52805275                    else if (keys) 
    52815276                    {   error("'key:value' expected for associative array literal"); 
    52825277                        delete keys; 
    52835278                        keys = NULL; 
    52845279                    } 
    52855280                    values->push(e); 
    52865281                    if (token.value == TOKrbracket) 
    52875282                        break; 
    52885283                    check(TOKcomma); 
    5289                 } 
    5290             } 
    5291             check(TOKrbracket); 
     5284            } 
     5285            check(loc, TOKrbracket); 
    52925286 
    52935287            if (keys) 
    52945288                e = new AssocArrayLiteralExp(loc, keys, values); 
    52955289            else 
    52965290                e = new ArrayLiteralExp(loc, values); 
    52975291            break; 
    52985292        } 
    52995293 
    53005294        case TOKlcurly: 
    53015295            // { statements... } 
    53025296            save = TOKdelegate; 
    53035297            goto case_delegate; 
    53045298 
    53055299        case TOKfunction: 
    53065300        case TOKdelegate: 
    53075301            save = token.value; 
    53085302            nextToken(); 
    53095303        case_delegate: 
    53105304        { 
    53115305            /* function type(parameters) { body } pure nothrow 
     
    54265420                {   // array[] 
    54275421                    e = new SliceExp(loc, e, NULL, NULL); 
    54285422                    nextToken(); 
    54295423                } 
    54305424                else 
    54315425                { 
    54325426                    index = parseAssignExp(); 
    54335427                    if (token.value == TOKslice) 
    54345428                    {   // array[lwr .. upr] 
    54355429                        nextToken(); 
    54365430                        upr = parseAssignExp(); 
    54375431                        e = new SliceExp(loc, e, index, upr); 
    54385432                    } 
    54395433                    else 
    54405434                    {   // array[index, i2, i3, i4, ...] 
    54415435                        Expressions *arguments = new Expressions(); 
    54425436                        arguments->push(index); 
    54435437                        if (token.value == TOKcomma) 
    54445438                        { 
    54455439                            nextToken(); 
    5446                             while (1) 
    5447                             {   Expression *arg; 
    5448  
    5449                                 arg = parseAssignExp(); 
     5440                            while (token.value != TOKrbracket && token.value != TOKeof) 
     5441                            { 
     5442                                Expression *arg = parseAssignExp(); 
    54505443                                arguments->push(arg); 
    54515444                                if (token.value == TOKrbracket) 
    54525445                                    break; 
    54535446                                check(TOKcomma); 
    54545447                            } 
    54555448                        } 
    54565449                        e = new ArrayExp(loc, e, arguments); 
    54575450                    } 
    54585451                    check(TOKrbracket); 
    54595452                    inBrackets--; 
    54605453                } 
    54615454                continue; 
    54625455            } 
    54635456 
    54645457            default: 
    54655458                return e; 
    54665459        } 
    54675460        nextToken(); 
    54685461    } 
    54695462} 
     
    61286121 
    61296122/************************* 
    61306123 * Collect argument list. 
    61316124 * Assume current token is ',', '(' or '['. 
    61326125 */ 
    61336126 
    61346127Expressions *Parser::parseArguments() 
    61356128{   // function call 
    61366129    Expressions *arguments; 
    61376130    Expression *arg; 
    61386131    enum TOK endtok; 
    61396132 
    61406133    arguments = new Expressions(); 
    61416134    if (token.value == TOKlbracket) 
    61426135        endtok = TOKrbracket; 
    61436136    else 
    61446137        endtok = TOKrparen; 
    61456138 
    61466139    { 
    61476140        nextToken(); 
    6148         if (token.value != endtok) 
     6141        while (token.value != endtok) 
    61496142        { 
    6150             while (1) 
    6151             { 
    61526143                arg = parseAssignExp(); 
    61536144                arguments->push(arg); 
    61546145                if (token.value == endtok) 
    61556146                    break; 
    61566147                check(TOKcomma); 
    6157             } 
    61586148        } 
    61596149        check(endtok); 
    61606150    } 
    61616151    return arguments; 
    61626152} 
    61636153 
    61646154/******************************************* 
    61656155 */ 
    61666156 
    61676157Expression *Parser::parseNewExp(Expression *thisexp) 
    61686158{   Type *t; 
    61696159    Expressions *newargs; 
    61706160    Expressions *arguments = NULL; 
    61716161    Expression *e; 
    61726162    Loc loc = this->loc; 
    61736163 
    61746164    nextToken(); 
    61756165    newargs = NULL; 
    61766166    if (token.value == TOKlparen) 
    61776167    {