[BACK]Return to cgram.y CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / xlint / lint1

Annotation of src/usr.bin/xlint/lint1/cgram.y, Revision 1.41

1.2       cgd         1: %{
1.41    ! christos    2: /* $NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $ */
1.2       cgd         3:
1.1       cgd         4: /*
1.9       cgd         5:  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
1.1       cgd         6:  * Copyright (c) 1994, 1995 Jochen Pohl
                      7:  * All Rights Reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Jochen Pohl for
                     20:  *     The NetBSD Project.
                     21:  * 4. The name of the author may not be used to endorse or promote products
                     22:  *    derived from this software without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     27:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     28:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     29:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     30:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     32:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     33:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35:
1.13      christos   36: #include <sys/cdefs.h>
1.23      tv         37: #if defined(__RCSID) && !defined(lint)
1.41    ! christos   38: __RCSID("$NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $");
1.1       cgd        39: #endif
                     40:
                     41: #include <stdlib.h>
1.12      cjs        42: #include <string.h>
1.1       cgd        43: #include <limits.h>
                     44:
                     45: #include "lint1.h"
                     46:
1.41    ! christos   47: extern char *yytext;
1.1       cgd        48: /*
                     49:  * Contains the level of current declaration. 0 is extern.
                     50:  * Used for symbol table entries.
                     51:  */
                     52: int    blklev;
                     53:
                     54: /*
                     55:  * level for memory allocation. Normaly the same as blklev.
                     56:  * An exeption is the declaration of arguments in prototypes. Memory
                     57:  * for these can't be freed after the declaration, but symbols must
                     58:  * be removed from the symbol table after the declaration.
                     59:  */
                     60: int    mblklev;
                     61:
1.15      christos   62: /*
                     63:  * Save the no-warns state and restore it to avoid the problem where
                     64:  * if (expr) { stmt } / * NOLINT * / stmt;
                     65:  */
                     66: static int onowarn = -1;
                     67:
1.27      christos   68: static int     toicon(tnode_t *, int);
1.20      lukem      69: static void    idecl(sym_t *, int, sbuf_t *);
                     70: static void    ignuptorp(void);
1.1       cgd        71:
1.15      christos   72: #ifdef DEBUG
1.39      christos   73: static inline void CLRWFLGS(const char *file, size_t line);
                     74: static inline void CLRWFLGS(const char *file, size_t line)
1.15      christos   75: {
1.39      christos   76:        printf("%s, %d: clear flags %s %zu\n", curr_pos.p_file,
                     77:            curr_pos.p_line, file, line);
1.15      christos   78:        clrwflgs();
                     79:        onowarn = -1;
                     80: }
                     81:
1.39      christos   82: static inline void SAVE(const char *file, size_t line);
                     83: static inline void SAVE(const char *file, size_t line)
1.15      christos   84: {
                     85:        if (onowarn != -1)
                     86:                abort();
1.39      christos   87:        printf("%s, %d: save flags %s %zu = %d\n", curr_pos.p_file,
                     88:            curr_pos.p_line, file, line, nowarn);
1.15      christos   89:        onowarn = nowarn;
                     90: }
                     91:
1.39      christos   92: static inline void RESTORE(const char *file, size_t line);
                     93: static inline void RESTORE(const char *file, size_t line)
1.15      christos   94: {
                     95:        if (onowarn != -1) {
                     96:                nowarn = onowarn;
1.39      christos   97:                printf("%s, %d: restore flags %s %zu = %d\n", curr_pos.p_file,
                     98:                    curr_pos.p_line, file, line, nowarn);
1.15      christos   99:                onowarn = -1;
                    100:        } else
1.39      christos  101:                CLRWFLGS(file, line);
1.15      christos  102: }
                    103: #else
1.39      christos  104: #define CLRWFLGS(f, l) clrwflgs(), onowarn = -1
                    105: #define SAVE(f, l)     onowarn = nowarn
                    106: #define RESTORE(f, l) (void)(onowarn == -1 ? (clrwflgs(), 0) : (nowarn = onowarn))
1.15      christos  107: #endif
1.1       cgd       108: %}
                    109:
1.40      christos  110: %expect 1
                    111:
1.1       cgd       112: %union {
                    113:        int     y_int;
                    114:        val_t   *y_val;
                    115:        sbuf_t  *y_sb;
                    116:        sym_t   *y_sym;
                    117:        op_t    y_op;
                    118:        scl_t   y_scl;
                    119:        tspec_t y_tspec;
                    120:        tqual_t y_tqual;
                    121:        type_t  *y_type;
                    122:        tnode_t *y_tnode;
1.35      christos  123:        range_t y_range;
1.1       cgd       124:        strg_t  *y_strg;
                    125:        pqinf_t *y_pqinf;
                    126: };
                    127:
                    128: %token                 T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
                    129: %token <y_op>          T_STROP
                    130: %token <y_op>          T_UNOP
                    131: %token <y_op>          T_INCDEC
                    132: %token                 T_SIZEOF
                    133: %token <y_op>          T_MULT
                    134: %token <y_op>          T_DIVOP
                    135: %token <y_op>          T_ADDOP
                    136: %token <y_op>          T_SHFTOP
                    137: %token <y_op>          T_RELOP
                    138: %token <y_op>          T_EQOP
                    139: %token <y_op>          T_AND
                    140: %token <y_op>          T_XOR
                    141: %token <y_op>          T_OR
                    142: %token <y_op>          T_LOGAND
                    143: %token <y_op>          T_LOGOR
                    144: %token                 T_QUEST
                    145: %token                 T_COLON
                    146: %token <y_op>          T_ASSIGN
                    147: %token <y_op>          T_OPASS
                    148: %token                 T_COMMA
                    149: %token                 T_SEMI
                    150: %token                 T_ELLIPSE
1.41    ! christos  151: %token                 T_REAL
        !           152: %token                 T_IMAG
1.1       cgd       153:
                    154: /* storage classes (extern, static, auto, register and typedef) */
                    155: %token <y_scl>         T_SCLASS
                    156:
                    157: /* types (char, int, short, long, unsigned, signed, float, double, void) */
                    158: %token <y_tspec>       T_TYPE
                    159:
                    160: /* qualifiers (const, volatile) */
                    161: %token <y_tqual>       T_QUAL
                    162:
                    163: /* struct or union */
                    164: %token <y_tspec>       T_SOU
                    165:
                    166: /* enum */
                    167: %token                 T_ENUM
                    168:
                    169: /* remaining keywords */
                    170: %token                 T_CASE
                    171: %token                 T_DEFAULT
                    172: %token                 T_IF
                    173: %token                 T_ELSE
                    174: %token                 T_SWITCH
                    175: %token                 T_DO
                    176: %token                 T_WHILE
                    177: %token                 T_FOR
                    178: %token                 T_GOTO
                    179: %token                 T_CONTINUE
                    180: %token                 T_BREAK
                    181: %token                 T_RETURN
1.6       jpo       182: %token                 T_ASM
1.11      cgd       183: %token                 T_SYMBOLRENAME
1.1       cgd       184:
                    185: %left  T_COMMA
                    186: %right T_ASSIGN T_OPASS
                    187: %right T_QUEST T_COLON
                    188: %left  T_LOGOR
                    189: %left  T_LOGAND
                    190: %left  T_OR
                    191: %left  T_XOR
                    192: %left  T_AND
                    193: %left  T_EQOP
                    194: %left  T_RELOP
                    195: %left  T_SHFTOP
                    196: %left  T_ADDOP
                    197: %left  T_MULT T_DIVOP
1.41    ! christos  198: %right T_UNOP T_INCDEC T_SIZEOF T_REAL T_IMAG
1.1       cgd       199: %left  T_LPARN T_LBRACK T_STROP
                    200:
                    201: %token <y_sb>          T_NAME
                    202: %token <y_sb>          T_TYPENAME
                    203: %token <y_val>         T_CON
                    204: %token <y_strg>        T_STRING
                    205:
                    206: %type  <y_sym>         func_decl
                    207: %type  <y_sym>         notype_decl
                    208: %type  <y_sym>         type_decl
                    209: %type  <y_type>        typespec
                    210: %type  <y_type>        clrtyp_typespec
                    211: %type  <y_type>        notype_typespec
                    212: %type  <y_type>        struct_spec
                    213: %type  <y_type>        enum_spec
                    214: %type  <y_sym>         struct_tag
                    215: %type  <y_sym>         enum_tag
                    216: %type  <y_tspec>       struct
                    217: %type  <y_sym>         struct_declaration
                    218: %type  <y_sb>          identifier
                    219: %type  <y_sym>         member_declaration_list_with_rbrace
                    220: %type  <y_sym>         member_declaration_list
                    221: %type  <y_sym>         member_declaration
                    222: %type  <y_sym>         notype_member_decls
                    223: %type  <y_sym>         type_member_decls
                    224: %type  <y_sym>         notype_member_decl
                    225: %type  <y_sym>         type_member_decl
                    226: %type  <y_tnode>       constant
                    227: %type  <y_sym>         enum_declaration
                    228: %type  <y_sym>         enums_with_opt_comma
                    229: %type  <y_sym>         enums
                    230: %type  <y_sym>         enumerator
                    231: %type  <y_sym>         ename
                    232: %type  <y_sym>         notype_direct_decl
                    233: %type  <y_sym>         type_direct_decl
                    234: %type  <y_pqinf>       pointer
                    235: %type  <y_pqinf>       asterisk
                    236: %type  <y_sym>         param_decl
                    237: %type  <y_sym>         param_list
                    238: %type  <y_sym>         abs_decl_param_list
                    239: %type  <y_sym>         direct_param_decl
                    240: %type  <y_sym>         notype_param_decl
                    241: %type  <y_sym>         direct_notype_param_decl
                    242: %type  <y_pqinf>       type_qualifier_list
                    243: %type  <y_pqinf>       type_qualifier
                    244: %type  <y_sym>         identifier_list
                    245: %type  <y_sym>         abs_decl
                    246: %type  <y_sym>         direct_abs_decl
                    247: %type  <y_sym>         vararg_parameter_type_list
                    248: %type  <y_sym>         parameter_type_list
                    249: %type  <y_sym>         parameter_declaration
                    250: %type  <y_tnode>       expr
1.29      christos  251: %type  <y_tnode>       expr_stmnt_val
                    252: %type  <y_tnode>       expr_stmnt_list
1.1       cgd       253: %type  <y_tnode>       term
                    254: %type  <y_tnode>       func_arg_list
                    255: %type  <y_op>          point_or_arrow
                    256: %type  <y_type>        type_name
                    257: %type  <y_sym>         abstract_declaration
                    258: %type  <y_tnode>       do_while_expr
                    259: %type  <y_tnode>       opt_expr
                    260: %type  <y_strg>        string
                    261: %type  <y_strg>        string2
1.11      cgd       262: %type  <y_sb>          opt_asm_or_symbolrename
1.35      christos  263: %type  <y_range>       range
                    264: %type  <y_range>       lorange
1.1       cgd       265:
                    266:
                    267: %%
                    268:
                    269: program:
                    270:          /* empty */ {
                    271:                if (sflag) {
                    272:                        /* empty translation unit */
                    273:                        error(272);
                    274:                } else if (!tflag) {
                    275:                        /* empty translation unit */
                    276:                        warning(272);
                    277:                }
                    278:          }
                    279:        | translation_unit
                    280:        ;
                    281:
                    282: translation_unit:
                    283:          ext_decl
                    284:        | translation_unit ext_decl
                    285:        ;
                    286:
                    287: ext_decl:
1.9       cgd       288:          asm_stmnt
                    289:        | func_def {
1.8       jpo       290:                glclup(0);
1.39      christos  291:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd       292:          }
                    293:        | data_def {
1.8       jpo       294:                glclup(0);
1.39      christos  295:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd       296:          }
                    297:        ;
                    298:
                    299: data_def:
                    300:          T_SEMI {
                    301:                if (sflag) {
                    302:                        /* syntax error: empty declaration */
                    303:                        error(0);
                    304:                } else if (!tflag) {
                    305:                        /* syntax error: empty declaration */
                    306:                        warning(0);
                    307:                }
                    308:          }
                    309:        | clrtyp deftyp notype_init_decls T_SEMI {
                    310:                if (sflag) {
                    311:                        /* old style declaration; add "int" */
                    312:                        error(1);
                    313:                } else if (!tflag) {
                    314:                        /* old style declaration; add "int" */
                    315:                        warning(1);
                    316:                }
                    317:          }
                    318:        | declmods deftyp T_SEMI {
1.3       jpo       319:                if (dcs->d_scl == TYPEDEF) {
1.1       cgd       320:                        /* typedef declares no type name */
                    321:                        warning(72);
                    322:                } else {
                    323:                        /* empty declaration */
                    324:                        warning(2);
                    325:                }
                    326:          }
                    327:        | declmods deftyp notype_init_decls T_SEMI
                    328:        | declspecs deftyp T_SEMI {
1.3       jpo       329:                if (dcs->d_scl == TYPEDEF) {
1.1       cgd       330:                        /* typedef declares no type name */
                    331:                        warning(72);
1.3       jpo       332:                } else if (!dcs->d_nedecl) {
1.1       cgd       333:                        /* empty declaration */
                    334:                        warning(2);
                    335:                }
                    336:          }
                    337:        | declspecs deftyp type_init_decls T_SEMI
                    338:        | error T_SEMI {
1.20      lukem     339:                globclup();
1.1       cgd       340:          }
                    341:        | error T_RBRACE {
                    342:                globclup();
                    343:          }
                    344:        ;
                    345:
                    346: func_def:
                    347:          func_decl {
                    348:                if ($1->s_type->t_tspec != FUNC) {
                    349:                        /* syntax error */
1.41    ! christos  350:                        error(249, yytext);
1.1       cgd       351:                        YYERROR;
                    352:                }
                    353:                if ($1->s_type->t_typedef) {
                    354:                        /* ()-less function definition */
                    355:                        error(64);
                    356:                        YYERROR;
                    357:                }
                    358:                funcdef($1);
                    359:                blklev++;
                    360:                pushdecl(ARG);
1.39      christos  361:                if (nowarn)
                    362:                        $1->s_used = 1;
1.1       cgd       363:          } opt_arg_declaration_list {
                    364:                popdecl();
                    365:                blklev--;
                    366:                cluparg();
                    367:                pushctrl(0);
                    368:          } comp_stmnt {
                    369:                funcend();
                    370:                popctrl(0);
                    371:          }
                    372:        ;
                    373:
                    374: func_decl:
                    375:          clrtyp deftyp notype_decl {
                    376:                $$ = $3;
                    377:          }
                    378:        | declmods deftyp notype_decl {
                    379:                $$ = $3;
                    380:          }
                    381:        | declspecs deftyp type_decl {
                    382:                $$ = $3;
                    383:          }
                    384:        ;
                    385:
                    386: opt_arg_declaration_list:
                    387:          /* empty */
                    388:        | arg_declaration_list
                    389:        ;
                    390:
                    391: arg_declaration_list:
                    392:          arg_declaration
                    393:        | arg_declaration_list arg_declaration
                    394:        /* XXX or better "arg_declaration error" ? */
                    395:        | error
                    396:        ;
                    397:
                    398: /*
                    399:  * "arg_declaration" is separated from "declaration" because it
                    400:  * needs other error handling.
                    401:  */
                    402:
                    403: arg_declaration:
                    404:          declmods deftyp T_SEMI {
                    405:                /* empty declaration */
                    406:                warning(2);
                    407:          }
                    408:        | declmods deftyp notype_init_decls T_SEMI
                    409:        | declspecs deftyp T_SEMI {
1.3       jpo       410:                if (!dcs->d_nedecl) {
1.1       cgd       411:                        /* empty declaration */
                    412:                        warning(2);
                    413:                } else {
1.3       jpo       414:                        tspec_t ts = dcs->d_type->t_tspec;
1.1       cgd       415:                        /* %s declared in argument declaration list */
                    416:                        warning(3, ts == STRUCT ? "struct" :
                    417:                                (ts == UNION ? "union" : "enum"));
                    418:                }
                    419:          }
                    420:        | declspecs deftyp type_init_decls T_SEMI {
1.3       jpo       421:                if (dcs->d_nedecl) {
                    422:                        tspec_t ts = dcs->d_type->t_tspec;
1.1       cgd       423:                        /* %s declared in argument declaration list */
                    424:                        warning(3, ts == STRUCT ? "struct" :
                    425:                                (ts == UNION ? "union" : "enum"));
                    426:                }
                    427:          }
                    428:        | declmods error
                    429:        | declspecs error
                    430:        ;
                    431:
                    432: declaration:
                    433:          declmods deftyp T_SEMI {
1.3       jpo       434:                if (dcs->d_scl == TYPEDEF) {
1.1       cgd       435:                        /* typedef declares no type name */
                    436:                        warning(72);
                    437:                } else {
                    438:                        /* empty declaration */
                    439:                        warning(2);
                    440:                }
                    441:          }
                    442:        | declmods deftyp notype_init_decls T_SEMI
                    443:        | declspecs deftyp T_SEMI {
1.3       jpo       444:                if (dcs->d_scl == TYPEDEF) {
1.1       cgd       445:                        /* typedef declares no type name */
                    446:                        warning(72);
1.3       jpo       447:                } else if (!dcs->d_nedecl) {
1.1       cgd       448:                        /* empty declaration */
                    449:                        warning(2);
                    450:                }
                    451:          }
                    452:        | declspecs deftyp type_init_decls T_SEMI
                    453:        | error T_SEMI
                    454:        ;
                    455:
                    456: clrtyp:
                    457:          {
                    458:                clrtyp();
                    459:          }
                    460:        ;
                    461:
                    462: deftyp:
                    463:          /* empty */ {
                    464:                deftyp();
                    465:          }
                    466:        ;
                    467:
                    468: declspecs:
                    469:          clrtyp_typespec {
                    470:                addtype($1);
                    471:          }
                    472:        | declmods typespec {
                    473:                addtype($2);
                    474:          }
                    475:        | declspecs declmod
                    476:        | declspecs notype_typespec {
                    477:                addtype($2);
                    478:          }
                    479:        ;
                    480:
                    481: declmods:
                    482:          clrtyp T_QUAL {
                    483:                addqual($2);
                    484:          }
                    485:        | clrtyp T_SCLASS {
                    486:                addscl($2);
                    487:          }
                    488:        | declmods declmod
                    489:        ;
                    490:
                    491: declmod:
                    492:          T_QUAL {
                    493:                addqual($1);
                    494:          }
                    495:        | T_SCLASS {
                    496:                addscl($1);
                    497:          }
                    498:        ;
                    499:
                    500: clrtyp_typespec:
                    501:          clrtyp notype_typespec {
                    502:                $$ = $2;
                    503:          }
                    504:        | T_TYPENAME clrtyp {
                    505:                $$ = getsym($1)->s_type;
                    506:          }
                    507:        ;
                    508:
                    509: typespec:
                    510:          notype_typespec {
                    511:                $$ = $1;
                    512:          }
                    513:        | T_TYPENAME {
                    514:                $$ = getsym($1)->s_type;
                    515:          }
                    516:        ;
                    517:
                    518: notype_typespec:
                    519:          T_TYPE {
                    520:                $$ = gettyp($1);
                    521:          }
                    522:        | struct_spec {
                    523:                popdecl();
                    524:                $$ = $1;
                    525:          }
                    526:        | enum_spec {
                    527:                popdecl();
                    528:                $$ = $1;
                    529:          }
                    530:        ;
                    531:
                    532: struct_spec:
                    533:          struct struct_tag {
                    534:                /*
                    535:                 * STDC requires that "struct a;" always introduces
                    536:                 * a new tag if "a" is not declared at current level
                    537:                 *
1.6       jpo       538:                 * yychar is valid because otherwise the parser would
1.1       cgd       539:                 * not been able to deceide if he must shift or reduce
                    540:                 */
                    541:                $$ = mktag($2, $1, 0, yychar == T_SEMI);
                    542:          }
                    543:        | struct struct_tag {
1.3       jpo       544:                dcs->d_tagtyp = mktag($2, $1, 1, 0);
1.1       cgd       545:          } struct_declaration {
1.3       jpo       546:                $$ = compltag(dcs->d_tagtyp, $4);
1.1       cgd       547:          }
                    548:        | struct {
1.3       jpo       549:                dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
1.1       cgd       550:          } struct_declaration {
1.3       jpo       551:                $$ = compltag(dcs->d_tagtyp, $3);
1.1       cgd       552:          }
                    553:        | struct error {
                    554:                symtyp = FVFT;
                    555:                $$ = gettyp(INT);
                    556:          }
                    557:        ;
                    558:
                    559: struct:
                    560:          T_SOU {
                    561:                symtyp = FTAG;
                    562:                pushdecl($1 == STRUCT ? MOS : MOU);
1.3       jpo       563:                dcs->d_offset = 0;
                    564:                dcs->d_stralign = CHAR_BIT;
1.1       cgd       565:                $$ = $1;
                    566:          }
                    567:        ;
                    568:
                    569: struct_tag:
                    570:          identifier {
                    571:                $$ = getsym($1);
                    572:          }
                    573:        ;
                    574:
                    575: struct_declaration:
                    576:          struct_decl_lbrace member_declaration_list_with_rbrace {
                    577:                $$ = $2;
                    578:          }
                    579:        ;
                    580:
                    581: struct_decl_lbrace:
                    582:          T_LBRACE {
                    583:                symtyp = FVFT;
                    584:          }
                    585:        ;
                    586:
                    587: member_declaration_list_with_rbrace:
                    588:          member_declaration_list T_SEMI T_RBRACE {
                    589:                $$ = $1;
                    590:          }
                    591:        | member_declaration_list T_RBRACE {
                    592:                if (sflag) {
                    593:                        /* syntax req. ";" after last struct/union member */
                    594:                        error(66);
                    595:                } else {
                    596:                        /* syntax req. ";" after last struct/union member */
                    597:                        warning(66);
                    598:                }
                    599:                $$ = $1;
                    600:          }
                    601:        | T_RBRACE {
                    602:                $$ = NULL;
                    603:          }
                    604:        ;
                    605:
                    606: member_declaration_list:
                    607:          member_declaration {
                    608:                $$ = $1;
                    609:          }
                    610:        | member_declaration_list T_SEMI member_declaration {
                    611:                $$ = lnklst($1, $3);
                    612:          }
                    613:        ;
                    614:
                    615: member_declaration:
                    616:          noclass_declmods deftyp {
                    617:                /* too late, i know, but getsym() compensates it */
                    618:                symtyp = FMOS;
                    619:          } notype_member_decls {
                    620:                symtyp = FVFT;
                    621:                $$ = $4;
                    622:          }
                    623:        | noclass_declspecs deftyp {
                    624:                symtyp = FMOS;
                    625:          } type_member_decls {
                    626:                symtyp = FVFT;
                    627:                $$ = $4;
                    628:          }
                    629:        | noclass_declmods deftyp {
                    630:                /* struct or union member must be named */
                    631:                warning(49);
                    632:                $$ = NULL;
                    633:          }
                    634:        | noclass_declspecs deftyp {
                    635:                /* struct or union member must be named */
                    636:                warning(49);
                    637:                $$ = NULL;
                    638:          }
                    639:        | error {
                    640:                symtyp = FVFT;
                    641:                $$ = NULL;
                    642:          }
                    643:        ;
                    644:
                    645: noclass_declspecs:
                    646:          clrtyp_typespec {
                    647:                addtype($1);
                    648:          }
                    649:        | noclass_declmods typespec {
                    650:                addtype($2);
                    651:          }
                    652:        | noclass_declspecs T_QUAL {
                    653:                addqual($2);
                    654:          }
                    655:        | noclass_declspecs notype_typespec {
                    656:                addtype($2);
                    657:          }
                    658:        ;
                    659:
                    660: noclass_declmods:
                    661:          clrtyp T_QUAL {
                    662:                addqual($2);
                    663:          }
                    664:        | noclass_declmods T_QUAL {
                    665:                addqual($2);
                    666:          }
                    667:        ;
                    668:
                    669: notype_member_decls:
                    670:          notype_member_decl {
                    671:                $$ = decl1str($1);
                    672:          }
                    673:        | notype_member_decls {
                    674:                symtyp = FMOS;
                    675:          } T_COMMA type_member_decl {
                    676:                $$ = lnklst($1, decl1str($4));
                    677:          }
                    678:        ;
                    679:
                    680: type_member_decls:
                    681:          type_member_decl {
                    682:                $$ = decl1str($1);
                    683:          }
                    684:        | type_member_decls {
                    685:                symtyp = FMOS;
                    686:          } T_COMMA type_member_decl {
                    687:                $$ = lnklst($1, decl1str($4));
                    688:          }
                    689:        ;
                    690:
                    691: notype_member_decl:
                    692:          notype_decl {
                    693:                $$ = $1;
                    694:          }
                    695:        | notype_decl T_COLON constant {
1.27      christos  696:                $$ = bitfield($1, toicon($3, 1));
1.1       cgd       697:          }
                    698:        | {
                    699:                symtyp = FVFT;
                    700:          } T_COLON constant {
1.27      christos  701:                $$ = bitfield(NULL, toicon($3, 1));
1.1       cgd       702:          }
                    703:        ;
                    704:
                    705: type_member_decl:
                    706:          type_decl {
                    707:                $$ = $1;
                    708:          }
                    709:        | type_decl T_COLON constant {
1.27      christos  710:                $$ = bitfield($1, toicon($3, 1));
1.1       cgd       711:          }
                    712:        | {
                    713:                symtyp = FVFT;
                    714:          } T_COLON constant {
1.27      christos  715:                $$ = bitfield(NULL, toicon($3, 1));
1.1       cgd       716:          }
                    717:        ;
                    718:
                    719: enum_spec:
                    720:          enum enum_tag {
                    721:                $$ = mktag($2, ENUM, 0, 0);
                    722:          }
                    723:        | enum enum_tag {
1.3       jpo       724:                dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
1.1       cgd       725:          } enum_declaration {
1.3       jpo       726:                $$ = compltag(dcs->d_tagtyp, $4);
1.1       cgd       727:          }
                    728:        | enum {
1.3       jpo       729:                dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
1.1       cgd       730:          } enum_declaration {
1.3       jpo       731:                $$ = compltag(dcs->d_tagtyp, $3);
1.1       cgd       732:          }
                    733:        | enum error {
                    734:                symtyp = FVFT;
                    735:                $$ = gettyp(INT);
                    736:          }
                    737:        ;
                    738:
                    739: enum:
                    740:          T_ENUM {
                    741:                symtyp = FTAG;
                    742:                pushdecl(ENUMCON);
                    743:          }
                    744:        ;
                    745:
                    746: enum_tag:
                    747:          identifier {
                    748:                $$ = getsym($1);
                    749:          }
                    750:        ;
                    751:
                    752: enum_declaration:
                    753:          enum_decl_lbrace enums_with_opt_comma T_RBRACE {
                    754:                $$ = $2;
                    755:          }
                    756:        ;
                    757:
                    758: enum_decl_lbrace:
                    759:          T_LBRACE {
                    760:                symtyp = FVFT;
                    761:                enumval = 0;
                    762:          }
                    763:        ;
                    764:
                    765: enums_with_opt_comma:
                    766:          enums {
                    767:                $$ = $1;
                    768:          }
                    769:        | enums T_COMMA {
                    770:                if (sflag) {
                    771:                        /* trailing "," prohibited in enum declaration */
                    772:                        error(54);
                    773:                } else {
                    774:                        /* trailing "," prohibited in enum declaration */
1.19      lukem     775:                        (void)gnuism(54);
1.1       cgd       776:                }
                    777:                $$ = $1;
                    778:          }
                    779:        ;
                    780:
                    781: enums:
                    782:          enumerator {
                    783:                $$ = $1;
                    784:          }
                    785:        | enums T_COMMA enumerator {
                    786:                $$ = lnklst($1, $3);
                    787:          }
                    788:        | error {
                    789:                $$ = NULL;
                    790:          }
                    791:        ;
                    792:
                    793: enumerator:
                    794:          ename {
                    795:                $$ = ename($1, enumval, 1);
                    796:          }
                    797:        | ename T_ASSIGN constant {
1.27      christos  798:                $$ = ename($1, toicon($3, 1), 0);
1.1       cgd       799:          }
                    800:        ;
                    801:
                    802: ename:
                    803:          identifier {
                    804:                $$ = getsym($1);
                    805:          }
                    806:        ;
                    807:
                    808:
                    809: notype_init_decls:
                    810:          notype_init_decl
                    811:        | notype_init_decls T_COMMA type_init_decl
                    812:        ;
                    813:
                    814: type_init_decls:
                    815:          type_init_decl
                    816:        | type_init_decls T_COMMA type_init_decl
                    817:        ;
                    818:
                    819: notype_init_decl:
1.11      cgd       820:          notype_decl opt_asm_or_symbolrename {
                    821:                idecl($1, 0, $2);
1.1       cgd       822:                chksz($1);
                    823:          }
1.11      cgd       824:        | notype_decl opt_asm_or_symbolrename {
                    825:                idecl($1, 1, $2);
1.1       cgd       826:          } T_ASSIGN initializer {
1.4       jpo       827:                chksz($1);
1.1       cgd       828:          }
                    829:        ;
                    830:
                    831: type_init_decl:
1.11      cgd       832:          type_decl opt_asm_or_symbolrename {
                    833:                idecl($1, 0, $2);
1.1       cgd       834:                chksz($1);
                    835:          }
1.11      cgd       836:        | type_decl opt_asm_or_symbolrename {
                    837:                idecl($1, 1, $2);
1.1       cgd       838:          } T_ASSIGN initializer {
1.4       jpo       839:                chksz($1);
1.1       cgd       840:          }
                    841:        ;
                    842:
                    843: notype_decl:
                    844:          notype_direct_decl {
                    845:                $$ = $1;
                    846:          }
                    847:        | pointer notype_direct_decl {
                    848:                $$ = addptr($2, $1);
                    849:          }
                    850:        ;
                    851:
                    852: notype_direct_decl:
                    853:          T_NAME {
                    854:                $$ = dname(getsym($1));
                    855:          }
                    856:        | T_LPARN type_decl T_RPARN {
                    857:                $$ = $2;
                    858:          }
                    859:        | notype_direct_decl T_LBRACK T_RBRACK {
                    860:                $$ = addarray($1, 0, 0);
                    861:          }
                    862:        | notype_direct_decl T_LBRACK constant T_RBRACK {
1.27      christos  863:                $$ = addarray($1, 1, toicon($3, 0));
1.1       cgd       864:          }
                    865:        | notype_direct_decl param_list {
                    866:                $$ = addfunc($1, $2);
                    867:                popdecl();
                    868:                blklev--;
                    869:          }
                    870:        ;
                    871:
                    872: type_decl:
                    873:          type_direct_decl {
                    874:                $$ = $1;
                    875:          }
                    876:        | pointer type_direct_decl {
                    877:                $$ = addptr($2, $1);
                    878:          }
                    879:        ;
                    880:
                    881: type_direct_decl:
                    882:          identifier {
                    883:                $$ = dname(getsym($1));
                    884:          }
                    885:        | T_LPARN type_decl T_RPARN {
                    886:                $$ = $2;
                    887:          }
                    888:        | type_direct_decl T_LBRACK T_RBRACK {
                    889:                $$ = addarray($1, 0, 0);
                    890:          }
                    891:        | type_direct_decl T_LBRACK constant T_RBRACK {
1.27      christos  892:                $$ = addarray($1, 1, toicon($3, 0));
1.1       cgd       893:          }
                    894:        | type_direct_decl param_list {
                    895:                $$ = addfunc($1, $2);
                    896:                popdecl();
                    897:                blklev--;
                    898:          }
                    899:        ;
                    900:
                    901: /*
                    902:  * param_decl and notype_param_decl exist to avoid a conflict in
                    903:  * argument lists. A typename enclosed in parens should always be
                    904:  * treated as a typename, not an argument.
                    905:  * "typedef int a; f(int (a));" is  "typedef int a; f(int foo(a));"
                    906:  *                             not "typedef int a; f(int a);"
                    907:  */
                    908: param_decl:
                    909:          direct_param_decl {
                    910:                $$ = $1;
                    911:          }
                    912:        | pointer direct_param_decl {
                    913:                $$ = addptr($2, $1);
                    914:          }
                    915:        ;
                    916:
                    917: direct_param_decl:
                    918:          identifier {
                    919:                $$ = dname(getsym($1));
                    920:          }
                    921:        | T_LPARN notype_param_decl T_RPARN {
                    922:                $$ = $2;
                    923:          }
                    924:        | direct_param_decl T_LBRACK T_RBRACK {
                    925:                $$ = addarray($1, 0, 0);
                    926:          }
                    927:        | direct_param_decl T_LBRACK constant T_RBRACK {
1.27      christos  928:                $$ = addarray($1, 1, toicon($3, 0));
1.1       cgd       929:          }
                    930:        | direct_param_decl param_list {
                    931:                $$ = addfunc($1, $2);
                    932:                popdecl();
                    933:                blklev--;
                    934:          }
                    935:        ;
                    936:
                    937: notype_param_decl:
                    938:          direct_notype_param_decl {
                    939:                $$ = $1;
                    940:          }
                    941:        | pointer direct_notype_param_decl {
                    942:                $$ = addptr($2, $1);
                    943:          }
                    944:        ;
                    945:
                    946: direct_notype_param_decl:
                    947:          T_NAME {
                    948:                $$ = dname(getsym($1));
                    949:          }
                    950:        | T_LPARN notype_param_decl T_RPARN {
                    951:                $$ = $2;
                    952:          }
                    953:        | direct_notype_param_decl T_LBRACK T_RBRACK {
                    954:                $$ = addarray($1, 0, 0);
                    955:          }
                    956:        | direct_notype_param_decl T_LBRACK constant T_RBRACK {
1.27      christos  957:                $$ = addarray($1, 1, toicon($3, 0));
1.1       cgd       958:          }
                    959:        | direct_notype_param_decl param_list {
                    960:                $$ = addfunc($1, $2);
                    961:                popdecl();
                    962:                blklev--;
                    963:          }
                    964:        ;
                    965:
                    966: pointer:
                    967:          asterisk {
                    968:                $$ = $1;
                    969:          }
                    970:        | asterisk type_qualifier_list {
                    971:                $$ = mergepq($1, $2);
                    972:          }
                    973:        | asterisk pointer {
                    974:                $$ = mergepq($1, $2);
                    975:          }
                    976:        | asterisk type_qualifier_list pointer {
                    977:                $$ = mergepq(mergepq($1, $2), $3);
                    978:          }
                    979:        ;
                    980:
                    981: asterisk:
                    982:          T_MULT {
                    983:                $$ = xcalloc(1, sizeof (pqinf_t));
                    984:                $$->p_pcnt = 1;
                    985:          }
                    986:        ;
                    987:
                    988: type_qualifier_list:
                    989:          type_qualifier {
                    990:                $$ = $1;
                    991:          }
                    992:        | type_qualifier_list type_qualifier {
                    993:                $$ = mergepq($1, $2);
                    994:          }
                    995:        ;
                    996:
                    997: type_qualifier:
                    998:          T_QUAL {
                    999:                $$ = xcalloc(1, sizeof (pqinf_t));
1.5       jpo      1000:                if ($1 == CONST) {
                   1001:                        $$->p_const = 1;
1.1       cgd      1002:                } else {
1.5       jpo      1003:                        $$->p_volatile = 1;
1.1       cgd      1004:                }
                   1005:          }
                   1006:        ;
                   1007:
                   1008: param_list:
                   1009:          id_list_lparn identifier_list T_RPARN {
                   1010:                $$ = $2;
                   1011:          }
                   1012:        | abs_decl_param_list {
                   1013:                $$ = $1;
                   1014:          }
                   1015:        ;
                   1016:
                   1017: id_list_lparn:
                   1018:          T_LPARN {
                   1019:                blklev++;
                   1020:                pushdecl(PARG);
                   1021:          }
                   1022:        ;
                   1023:
                   1024: identifier_list:
                   1025:          T_NAME {
                   1026:                $$ = iname(getsym($1));
                   1027:          }
                   1028:        | identifier_list T_COMMA T_NAME {
                   1029:                $$ = lnklst($1, iname(getsym($3)));
                   1030:          }
                   1031:        | identifier_list error {
                   1032:                $$ = $1;
                   1033:          }
                   1034:        ;
                   1035:
                   1036: abs_decl_param_list:
                   1037:          abs_decl_lparn T_RPARN {
                   1038:                $$ = NULL;
                   1039:          }
                   1040:        | abs_decl_lparn vararg_parameter_type_list T_RPARN {
1.3       jpo      1041:                dcs->d_proto = 1;
1.1       cgd      1042:                $$ = $2;
                   1043:          }
                   1044:        | abs_decl_lparn error T_RPARN {
                   1045:                $$ = NULL;
                   1046:          }
                   1047:        ;
                   1048:
                   1049: abs_decl_lparn:
                   1050:          T_LPARN {
                   1051:                blklev++;
                   1052:                pushdecl(PARG);
                   1053:          }
                   1054:        ;
                   1055:
                   1056: vararg_parameter_type_list:
                   1057:          parameter_type_list {
                   1058:                $$ = $1;
                   1059:          }
                   1060:        | parameter_type_list T_COMMA T_ELLIPSE {
1.3       jpo      1061:                dcs->d_vararg = 1;
1.1       cgd      1062:                $$ = $1;
                   1063:          }
                   1064:        | T_ELLIPSE {
                   1065:                if (sflag) {
                   1066:                        /* ANSI C requires formal parameter before "..." */
                   1067:                        error(84);
                   1068:                } else if (!tflag) {
                   1069:                        /* ANSI C requires formal parameter before "..." */
                   1070:                        warning(84);
                   1071:                }
1.3       jpo      1072:                dcs->d_vararg = 1;
1.1       cgd      1073:                $$ = NULL;
                   1074:          }
                   1075:        ;
                   1076:
                   1077: parameter_type_list:
1.11      cgd      1078:          parameter_declaration {
1.1       cgd      1079:                $$ = $1;
                   1080:          }
1.11      cgd      1081:        | parameter_type_list T_COMMA parameter_declaration {
1.1       cgd      1082:                $$ = lnklst($1, $3);
                   1083:          }
                   1084:        ;
                   1085:
                   1086: parameter_declaration:
                   1087:          declmods deftyp {
                   1088:                $$ = decl1arg(aname(), 0);
                   1089:          }
                   1090:        | declspecs deftyp {
                   1091:                $$ = decl1arg(aname(), 0);
                   1092:          }
                   1093:        | declmods deftyp notype_param_decl {
                   1094:                $$ = decl1arg($3, 0);
                   1095:          }
                   1096:        /*
                   1097:         * param_decl is needed because of following conflict:
                   1098:         * "typedef int a; f(int (a));" could be parsed as
                   1099:         * "function with argument a of type int", or
                   1100:         * "function with an abstract argument of type function".
                   1101:         * This grammar realizes the second case.
                   1102:         */
                   1103:        | declspecs deftyp param_decl {
                   1104:                $$ = decl1arg($3, 0);
                   1105:          }
                   1106:        | declmods deftyp abs_decl {
                   1107:                $$ = decl1arg($3, 0);
                   1108:          }
                   1109:        | declspecs deftyp abs_decl {
                   1110:                $$ = decl1arg($3, 0);
                   1111:          }
                   1112:        ;
                   1113:
1.11      cgd      1114: opt_asm_or_symbolrename:               /* expect only one */
                   1115:          /* empty */ {
                   1116:                $$ = NULL;
                   1117:          }
1.6       jpo      1118:        | T_ASM T_LPARN T_STRING T_RPARN {
                   1119:                freeyyv(&$3, T_STRING);
1.11      cgd      1120:                $$ = NULL;
                   1121:          }
                   1122:        | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN {
                   1123:                $$ = $3;
1.6       jpo      1124:          }
                   1125:        ;
                   1126:
1.1       cgd      1127: initializer:
                   1128:          init_expr
                   1129:        ;
                   1130:
                   1131: init_expr:
                   1132:          expr                          %prec T_COMMA {
                   1133:                mkinit($1);
                   1134:          }
1.26      christos 1135:        | init_by_name init_expr        %prec T_COMMA
1.1       cgd      1136:        | init_lbrace init_expr_list init_rbrace
                   1137:        | init_lbrace init_expr_list T_COMMA init_rbrace
                   1138:        | error
                   1139:        ;
                   1140:
                   1141: init_expr_list:
                   1142:          init_expr                     %prec T_COMMA
                   1143:        | init_expr_list T_COMMA init_expr
                   1144:        ;
                   1145:
1.35      christos 1146: lorange:
                   1147:          constant T_ELLIPSE {
                   1148:                $$.lo = toicon($1, 1);
                   1149:          }
                   1150:        ;
                   1151: range:
                   1152:        constant {
                   1153:                $$.lo = toicon($1, 1);
                   1154:                $$.hi = $$.lo + 1;
                   1155:          }
                   1156:        | lorange constant {
                   1157:                $$.lo = $1.lo;
                   1158:                $$.hi = toicon($2, 1);
                   1159:          }
                   1160:        ;
                   1161:
1.26      christos 1162: init_by_name:
1.35      christos 1163:          T_LBRACK range T_RBRACK T_ASSIGN {
1.34      yamt     1164:                if (!Sflag)
                   1165:                        warning(321);
                   1166:          }
1.37      christos 1167:        | point identifier T_ASSIGN {
1.26      christos 1168:                if (!Sflag)
                   1169:                        warning(313);
                   1170:                memberpush($2);
                   1171:          }
1.37      christos 1172:        | identifier T_COLON {
1.26      christos 1173:                gnuism(315);
                   1174:                memberpush($1);
                   1175:          }
                   1176:        ;
                   1177:
1.1       cgd      1178: init_lbrace:
                   1179:          T_LBRACE {
                   1180:                initlbr();
                   1181:          }
                   1182:        ;
                   1183:
                   1184: init_rbrace:
                   1185:          T_RBRACE {
                   1186:                initrbr();
                   1187:          }
                   1188:        ;
                   1189:
                   1190: type_name:
                   1191:          {
                   1192:                pushdecl(ABSTRACT);
                   1193:          } abstract_declaration {
                   1194:                popdecl();
                   1195:                $$ = $2->s_type;
                   1196:          }
                   1197:        ;
                   1198:
                   1199: abstract_declaration:
                   1200:          noclass_declmods deftyp {
                   1201:                $$ = decl1abs(aname());
                   1202:          }
                   1203:        | noclass_declspecs deftyp {
                   1204:                $$ = decl1abs(aname());
                   1205:          }
                   1206:        | noclass_declmods deftyp abs_decl {
                   1207:                $$ = decl1abs($3);
                   1208:          }
                   1209:        | noclass_declspecs deftyp abs_decl {
                   1210:                $$ = decl1abs($3);
                   1211:          }
                   1212:        ;
                   1213:
                   1214: abs_decl:
                   1215:          pointer {
                   1216:                $$ = addptr(aname(), $1);
                   1217:          }
                   1218:        | direct_abs_decl {
                   1219:                $$ = $1;
                   1220:          }
                   1221:        | pointer direct_abs_decl {
                   1222:                $$ = addptr($2, $1);
                   1223:          }
                   1224:        ;
                   1225:
                   1226: direct_abs_decl:
                   1227:          T_LPARN abs_decl T_RPARN {
                   1228:                $$ = $2;
                   1229:          }
                   1230:        | T_LBRACK T_RBRACK {
                   1231:                $$ = addarray(aname(), 0, 0);
                   1232:          }
                   1233:        | T_LBRACK constant T_RBRACK {
1.27      christos 1234:                $$ = addarray(aname(), 1, toicon($2, 0));
1.1       cgd      1235:          }
                   1236:        | direct_abs_decl T_LBRACK T_RBRACK {
                   1237:                $$ = addarray($1, 0, 0);
                   1238:          }
                   1239:        | direct_abs_decl T_LBRACK constant T_RBRACK {
1.27      christos 1240:                $$ = addarray($1, 1, toicon($3, 0));
1.1       cgd      1241:          }
                   1242:        | abs_decl_param_list {
                   1243:                $$ = addfunc(aname(), $1);
                   1244:                popdecl();
                   1245:                blklev--;
                   1246:          }
                   1247:        | direct_abs_decl abs_decl_param_list {
                   1248:                $$ = addfunc($1, $2);
                   1249:                popdecl();
                   1250:                blklev--;
                   1251:          }
                   1252:        ;
                   1253:
1.32      christos 1254: non_expr_stmnt:
1.1       cgd      1255:          labeled_stmnt
                   1256:        | comp_stmnt
                   1257:        | selection_stmnt
                   1258:        | iteration_stmnt
                   1259:        | jump_stmnt {
                   1260:                ftflg = 0;
                   1261:          }
1.6       jpo      1262:        | asm_stmnt
1.32      christos 1263:
                   1264: stmnt:
                   1265:          expr_stmnt
                   1266:        | non_expr_stmnt
1.1       cgd      1267:        ;
                   1268:
                   1269: labeled_stmnt:
                   1270:          label stmnt
                   1271:        ;
                   1272:
                   1273: label:
                   1274:          identifier T_COLON {
                   1275:                symtyp = FLAB;
                   1276:                label(T_NAME, getsym($1), NULL);
                   1277:          }
                   1278:        | T_CASE constant T_COLON {
                   1279:                label(T_CASE, NULL, $2);
                   1280:                ftflg = 1;
1.40      christos 1281:        }
                   1282:        | T_CASE constant T_ELLIPSE constant T_COLON {
                   1283:                /* XXX: We don't fill all cases */
                   1284:                label(T_CASE, NULL, $2);
                   1285:                ftflg = 1;
                   1286:        }
1.1       cgd      1287:        | T_DEFAULT T_COLON {
                   1288:                label(T_DEFAULT, NULL, NULL);
                   1289:                ftflg = 1;
                   1290:          }
                   1291:        ;
                   1292:
                   1293: comp_stmnt:
1.29      christos 1294:          comp_stmnt_lbrace declaration_list opt_stmnt_list comp_stmnt_rbrace
                   1295:        | comp_stmnt_lbrace opt_stmnt_list comp_stmnt_rbrace
1.1       cgd      1296:        ;
                   1297:
1.29      christos 1298: comp_stmnt_lbrace:
1.1       cgd      1299:          T_LBRACE {
                   1300:                blklev++;
                   1301:                mblklev++;
                   1302:                pushdecl(AUTO);
                   1303:          }
                   1304:        ;
                   1305:
1.29      christos 1306: comp_stmnt_rbrace:
1.1       cgd      1307:          T_RBRACE {
                   1308:                popdecl();
                   1309:                freeblk();
                   1310:                mblklev--;
                   1311:                blklev--;
                   1312:                ftflg = 0;
                   1313:          }
                   1314:        ;
                   1315:
                   1316: opt_stmnt_list:
                   1317:          /* empty */
                   1318:        | stmnt_list
                   1319:        ;
                   1320:
                   1321: stmnt_list:
1.14      christos 1322:          stmnt
1.7       jpo      1323:        | stmnt_list stmnt {
1.39      christos 1324:                RESTORE(__FILE__, __LINE__);
1.7       jpo      1325:          }
1.15      christos 1326:        | stmnt_list error T_SEMI
1.1       cgd      1327:        ;
                   1328:
                   1329: expr_stmnt:
                   1330:          expr T_SEMI {
1.29      christos 1331:                expr($1, 0, 0, 1);
1.1       cgd      1332:                ftflg = 0;
                   1333:          }
                   1334:        | T_SEMI {
                   1335:                ftflg = 0;
                   1336:          }
                   1337:        ;
                   1338:
1.30      christos 1339: /*
1.32      christos 1340:  * The following two productions are used to implement
                   1341:  * ({ [[decl-list] stmt-list] }).
                   1342:  * XXX: This is not well tested.
1.30      christos 1343:  */
1.29      christos 1344: expr_stmnt_val:
                   1345:          expr T_SEMI {
                   1346:                /* XXX: We should really do that only on the last name */
                   1347:                if ($1->tn_op == NAME)
                   1348:                        $1->tn_sym->s_used = 1;
                   1349:                $$ = $1;
                   1350:                expr($1, 0, 0, 0);
                   1351:                ftflg = 0;
                   1352:          }
1.33      christos 1353:        | non_expr_stmnt {
                   1354:                $$ = getnode();
                   1355:                $$->tn_type = gettyp(VOID);
                   1356:        }
1.29      christos 1357:        ;
                   1358:
                   1359: expr_stmnt_list:
1.32      christos 1360:          expr_stmnt_val
1.33      christos 1361:        | expr_stmnt_list expr_stmnt_val {
1.32      christos 1362:                $$ = $2;
                   1363:        }
1.29      christos 1364:        ;
                   1365:
1.1       cgd      1366: selection_stmnt:
                   1367:          if_without_else {
1.39      christos 1368:                SAVE(__FILE__, __LINE__);
1.1       cgd      1369:                if2();
                   1370:                if3(0);
                   1371:          }
                   1372:        | if_without_else T_ELSE {
1.39      christos 1373:                SAVE(__FILE__, __LINE__);
1.1       cgd      1374:                if2();
                   1375:          } stmnt {
1.39      christos 1376:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1377:                if3(1);
                   1378:          }
                   1379:        | if_without_else T_ELSE error {
1.39      christos 1380:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1381:                if3(0);
                   1382:          }
                   1383:        | switch_expr stmnt {
1.39      christos 1384:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1385:                switch2();
                   1386:          }
                   1387:        | switch_expr error {
1.39      christos 1388:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1389:                switch2();
                   1390:          }
                   1391:        ;
                   1392:
                   1393: if_without_else:
                   1394:          if_expr stmnt
                   1395:        | if_expr error
                   1396:        ;
                   1397:
                   1398: if_expr:
                   1399:          T_IF T_LPARN expr T_RPARN {
                   1400:                if1($3);
1.39      christos 1401:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1402:          }
                   1403:        ;
                   1404:
                   1405: switch_expr:
                   1406:          T_SWITCH T_LPARN expr T_RPARN {
                   1407:                switch1($3);
1.39      christos 1408:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1409:          }
                   1410:        ;
                   1411:
1.14      christos 1412: do_stmnt:
                   1413:          do stmnt {
1.39      christos 1414:                CLRWFLGS(__FILE__, __LINE__);
1.14      christos 1415:          }
                   1416:        ;
                   1417:
1.1       cgd      1418: iteration_stmnt:
                   1419:          while_expr stmnt {
1.39      christos 1420:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1421:                while2();
                   1422:          }
                   1423:        | while_expr error {
1.39      christos 1424:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1425:                while2();
                   1426:          }
1.14      christos 1427:        | do_stmnt do_while_expr {
                   1428:                do2($2);
1.1       cgd      1429:                ftflg = 0;
                   1430:          }
                   1431:        | do error {
1.39      christos 1432:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1433:                do2(NULL);
                   1434:          }
                   1435:        | for_exprs stmnt {
1.39      christos 1436:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1437:                for2();
                   1438:          }
                   1439:        | for_exprs error {
1.39      christos 1440:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1441:                for2();
                   1442:          }
                   1443:        ;
                   1444:
                   1445: while_expr:
                   1446:          T_WHILE T_LPARN expr T_RPARN {
                   1447:                while1($3);
1.39      christos 1448:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1449:          }
                   1450:        ;
                   1451:
                   1452: do:
                   1453:          T_DO {
                   1454:                do1();
                   1455:          }
                   1456:        ;
                   1457:
                   1458: do_while_expr:
                   1459:          T_WHILE T_LPARN expr T_RPARN T_SEMI {
                   1460:                $$ = $3;
                   1461:          }
                   1462:        ;
                   1463:
                   1464: for_exprs:
                   1465:          T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
                   1466:                for1($3, $5, $7);
1.39      christos 1467:                CLRWFLGS(__FILE__, __LINE__);
1.1       cgd      1468:          }
                   1469:        ;
                   1470:
                   1471: opt_expr:
                   1472:          /* empty */ {
                   1473:                $$ = NULL;
                   1474:          }
                   1475:        | expr {
                   1476:                $$ = $1;
                   1477:          }
                   1478:        ;
                   1479:
                   1480: jump_stmnt:
                   1481:          goto identifier T_SEMI {
                   1482:                dogoto(getsym($2));
                   1483:          }
                   1484:        | goto error T_SEMI {
                   1485:                symtyp = FVFT;
                   1486:          }
                   1487:        | T_CONTINUE T_SEMI {
                   1488:                docont();
                   1489:          }
                   1490:        | T_BREAK T_SEMI {
                   1491:                dobreak();
                   1492:          }
                   1493:        | T_RETURN T_SEMI {
                   1494:                doreturn(NULL);
                   1495:          }
                   1496:        | T_RETURN expr T_SEMI {
                   1497:                doreturn($2);
                   1498:          }
                   1499:        ;
                   1500:
                   1501: goto:
                   1502:          T_GOTO {
                   1503:                symtyp = FLAB;
                   1504:          }
                   1505:        ;
                   1506:
1.6       jpo      1507: asm_stmnt:
1.8       jpo      1508:          T_ASM T_LPARN read_until_rparn T_SEMI {
                   1509:                setasm();
                   1510:          }
                   1511:        | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
                   1512:                setasm();
                   1513:          }
                   1514:        | T_ASM error
1.6       jpo      1515:        ;
                   1516:
                   1517: read_until_rparn:
                   1518:          /* empty */ {
                   1519:                ignuptorp();
                   1520:          }
                   1521:        ;
                   1522:
1.1       cgd      1523: declaration_list:
1.7       jpo      1524:          declaration {
1.39      christos 1525:                CLRWFLGS(__FILE__, __LINE__);
1.7       jpo      1526:          }
                   1527:        | declaration_list declaration {
1.39      christos 1528:                CLRWFLGS(__FILE__, __LINE__);
1.7       jpo      1529:          }
1.1       cgd      1530:        ;
                   1531:
                   1532: constant:
                   1533:          expr                          %prec T_COMMA {
                   1534:                  $$ = $1;
                   1535:          }
                   1536:        ;
                   1537:
                   1538: expr:
                   1539:          expr T_MULT expr {
                   1540:                $$ = build(MULT, $1, $3);
                   1541:          }
                   1542:        | expr T_DIVOP expr {
                   1543:                $$ = build($2, $1, $3);
                   1544:          }
                   1545:        | expr T_ADDOP expr {
                   1546:                $$ = build($2, $1, $3);
                   1547:          }
                   1548:        | expr T_SHFTOP expr {
                   1549:                $$ = build($2, $1, $3);
                   1550:          }
                   1551:        | expr T_RELOP expr {
                   1552:                $$ = build($2, $1, $3);
                   1553:          }
                   1554:        | expr T_EQOP expr {
                   1555:                $$ = build($2, $1, $3);
                   1556:          }
                   1557:        | expr T_AND expr {
                   1558:                $$ = build(AND, $1, $3);
                   1559:          }
                   1560:        | expr T_XOR expr {
                   1561:                $$ = build(XOR, $1, $3);
                   1562:          }
                   1563:        | expr T_OR expr {
                   1564:                $$ = build(OR, $1, $3);
                   1565:          }
                   1566:        | expr T_LOGAND expr {
                   1567:                $$ = build(LOGAND, $1, $3);
                   1568:          }
                   1569:        | expr T_LOGOR expr {
                   1570:                $$ = build(LOGOR, $1, $3);
                   1571:          }
                   1572:        | expr T_QUEST expr T_COLON expr {
                   1573:                $$ = build(QUEST, $1, build(COLON, $3, $5));
                   1574:          }
                   1575:        | expr T_ASSIGN expr {
                   1576:                $$ = build(ASSIGN, $1, $3);
                   1577:          }
                   1578:        | expr T_OPASS expr {
                   1579:                $$ = build($2, $1, $3);
                   1580:          }
                   1581:        | expr T_COMMA expr {
                   1582:                $$ = build(COMMA, $1, $3);
                   1583:          }
                   1584:        | term {
                   1585:                $$ = $1;
                   1586:          }
                   1587:        ;
                   1588:
                   1589: term:
                   1590:          T_NAME {
1.21      wiz      1591:                /* XXX really necessary? */
1.1       cgd      1592:                if (yychar < 0)
                   1593:                        yychar = yylex();
                   1594:                $$ = getnnode(getsym($1), yychar);
                   1595:          }
                   1596:        | string {
                   1597:                $$ = getsnode($1);
                   1598:          }
                   1599:        | T_CON {
                   1600:                $$ = getcnode(gettyp($1->v_tspec), $1);
                   1601:          }
                   1602:        | T_LPARN expr T_RPARN {
                   1603:                if ($2 != NULL)
                   1604:                        $2->tn_parn = 1;
                   1605:                $$ = $2;
                   1606:          }
1.29      christos 1607:        | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list {
                   1608:                blklev--;
                   1609:                mblklev--;
1.31      kristerw 1610:                initsym = mktempsym(duptyp($4->tn_type));
1.29      christos 1611:                mblklev++;
                   1612:                blklev++;
                   1613:                gnuism(320);
                   1614:        } comp_stmnt_rbrace T_RPARN {
                   1615:                $$ = getnnode(initsym, 0);
                   1616:        }
                   1617:        | T_LPARN comp_stmnt_lbrace expr_stmnt_list {
                   1618:                blklev--;
                   1619:                mblklev--;
                   1620:                initsym = mktempsym($3->tn_type);
                   1621:                mblklev++;
                   1622:                blklev++;
                   1623:                gnuism(320);
                   1624:        } comp_stmnt_rbrace T_RPARN {
                   1625:                $$ = getnnode(initsym, 0);
                   1626:        }
1.1       cgd      1627:        | term T_INCDEC {
                   1628:                $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
                   1629:          }
                   1630:        | T_INCDEC term {
                   1631:                $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
                   1632:          }
                   1633:        | T_MULT term {
                   1634:                $$ = build(STAR, $2, NULL);
                   1635:          }
                   1636:        | T_AND term {
                   1637:                $$ = build(AMPER, $2, NULL);
                   1638:          }
                   1639:        | T_UNOP term {
                   1640:                $$ = build($1, $2, NULL);
                   1641:          }
                   1642:        | T_ADDOP term {
                   1643:                if (tflag && $1 == PLUS) {
                   1644:                        /* unary + is illegal in traditional C */
                   1645:                        warning(100);
                   1646:                }
                   1647:                $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
                   1648:          }
                   1649:        | term T_LBRACK expr T_RBRACK {
                   1650:                $$ = build(STAR, build(PLUS, $1, $3), NULL);
                   1651:          }
                   1652:        | term T_LPARN T_RPARN {
                   1653:                $$ = funccall($1, NULL);
                   1654:          }
                   1655:        | term T_LPARN func_arg_list T_RPARN {
                   1656:                $$ = funccall($1, $3);
                   1657:          }
                   1658:        | term point_or_arrow T_NAME {
                   1659:                if ($1 != NULL) {
                   1660:                        sym_t   *msym;
                   1661:                        /* XXX strmemb should be integrated in build() */
                   1662:                        if ($2 == ARROW) {
                   1663:                                /* must to this before strmemb is called */
                   1664:                                $1 = cconv($1);
                   1665:                        }
                   1666:                        msym = strmemb($1, $2, getsym($3));
                   1667:                        $$ = build($2, $1, getnnode(msym, 0));
                   1668:                } else {
                   1669:                        $$ = NULL;
                   1670:                }
                   1671:          }
1.41    ! christos 1672:        | T_REAL term {
        !          1673:                $$ = build(REAL, $2, NULL);
        !          1674:          }
        !          1675:        | T_IMAG term {
        !          1676:                $$ = build(IMAG, $2, NULL);
        !          1677:          }
        !          1678:        | T_REAL T_LPARN term T_RPARN {
        !          1679:                $$ = build(REAL, $3, NULL);
        !          1680:          }
        !          1681:        | T_IMAG T_LPARN term T_RPARN {
        !          1682:                $$ = build(IMAG, $3, NULL);
        !          1683:          }
1.1       cgd      1684:        | T_SIZEOF term                                 %prec T_SIZEOF {
                   1685:                if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
                   1686:                        chkmisc($2, 0, 0, 0, 0, 0, 1);
                   1687:          }
                   1688:        | T_SIZEOF T_LPARN type_name T_RPARN            %prec T_SIZEOF {
                   1689:                $$ = bldszof($3);
                   1690:          }
                   1691:        | T_LPARN type_name T_RPARN term                %prec T_UNOP {
                   1692:                $$ = cast($4, $2);
                   1693:          }
1.28      christos 1694:        | T_LPARN type_name T_RPARN                     %prec T_UNOP {
                   1695:                sym_t *tmp = mktempsym($2);
                   1696:                idecl(tmp, 1, NULL);
                   1697:          } init_lbrace init_expr_list init_rbrace {
                   1698:                if (!Sflag)
                   1699:                        gnuism(319);
                   1700:                $$ = getnnode(initsym, 0);
                   1701:          }
1.1       cgd      1702:        ;
                   1703:
                   1704: string:
                   1705:          T_STRING {
                   1706:                $$ = $1;
                   1707:          }
                   1708:        | T_STRING string2 {
                   1709:                $$ = catstrg($1, $2);
                   1710:          }
                   1711:        ;
                   1712:
                   1713: string2:
                   1714:         T_STRING {
                   1715:                if (tflag) {
                   1716:                        /* concatenated strings are illegal in traditional C */
                   1717:                        warning(219);
                   1718:                }
                   1719:                $$ = $1;
                   1720:          }
                   1721:        | string2 T_STRING {
                   1722:                $$ = catstrg($1, $2);
                   1723:          }
                   1724:        ;
                   1725:
                   1726: func_arg_list:
                   1727:          expr                                          %prec T_COMMA {
                   1728:                $$ = funcarg(NULL, $1);
                   1729:          }
                   1730:        | func_arg_list T_COMMA expr {
                   1731:                $$ = funcarg($1, $3);
                   1732:          }
                   1733:        ;
                   1734:
                   1735: point_or_arrow:
                   1736:          T_STROP {
                   1737:                symtyp = FMOS;
                   1738:                $$ = $1;
1.26      christos 1739:          }
                   1740:        ;
                   1741:
                   1742: point:
                   1743:          T_STROP {
                   1744:                if ($1 != POINT)
1.41    ! christos 1745:                        error(249, yytext);
1.1       cgd      1746:          }
                   1747:        ;
                   1748:
                   1749: identifier:
                   1750:          T_NAME {
                   1751:                $$ = $1;
                   1752:          }
                   1753:        | T_TYPENAME {
                   1754:                $$ = $1;
                   1755:          }
                   1756:        ;
                   1757:
                   1758: %%
                   1759:
                   1760: /* ARGSUSED */
                   1761: int
1.20      lukem    1762: yyerror(char *msg)
1.1       cgd      1763: {
1.41    ! christos 1764:        error(249, yytext);
1.1       cgd      1765:        if (++sytxerr >= 5)
                   1766:                norecover();
                   1767:        return (0);
                   1768: }
                   1769:
1.38      he       1770: static __inline int uq_gt(uint64_t, uint64_t);
                   1771: static __inline int q_gt(int64_t, int64_t);
1.10      mycroft  1772:
1.38      he       1773: static __inline int
1.24      thorpej  1774: uq_gt(uint64_t a, uint64_t b)
1.10      mycroft  1775: {
                   1776:
                   1777:        return (a > b);
                   1778: }
                   1779:
1.38      he       1780: static __inline int
1.24      thorpej  1781: q_gt(int64_t a, int64_t b)
1.10      mycroft  1782: {
                   1783:
                   1784:        return (a > b);
                   1785: }
                   1786:
                   1787: #define        q_lt(a, b)      q_gt(b, a)
                   1788:
1.1       cgd      1789: /*
                   1790:  * Gets a node for a constant and returns the value of this constant
                   1791:  * as integer.
                   1792:  * Is the node not constant or too large for int or of type float,
                   1793:  * a warning will be printed.
                   1794:  *
                   1795:  * toicon() should be used only inside declarations. If it is used in
                   1796:  * expressions, it frees the memory used for the expression.
                   1797:  */
                   1798: static int
1.27      christos 1799: toicon(tnode_t *tn, int required)
1.1       cgd      1800: {
                   1801:        int     i;
                   1802:        tspec_t t;
                   1803:        val_t   *v;
                   1804:
1.27      christos 1805:        v = constant(tn, required);
1.1       cgd      1806:
                   1807:        /*
                   1808:         * Abstract declarations are used inside expression. To free
                   1809:         * the memory would be a fatal error.
                   1810:         */
1.3       jpo      1811:        if (dcs->d_ctx != ABSTRACT)
1.1       cgd      1812:                tfreeblk();
                   1813:
                   1814:        if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
                   1815:                i = (int)v->v_ldbl;
                   1816:                /* integral constant expression expected */
                   1817:                error(55);
                   1818:        } else {
                   1819:                i = (int)v->v_quad;
                   1820:                if (isutyp(t)) {
1.24      thorpej  1821:                        if (uq_gt((uint64_t)v->v_quad,
                   1822:                                  (uint64_t)INT_MAX)) {
1.1       cgd      1823:                                /* integral constant too large */
                   1824:                                warning(56);
                   1825:                        }
                   1826:                } else {
1.24      thorpej  1827:                        if (q_gt(v->v_quad, (int64_t)INT_MAX) ||
                   1828:                            q_lt(v->v_quad, (int64_t)INT_MIN)) {
1.1       cgd      1829:                                /* integral constant too large */
                   1830:                                warning(56);
                   1831:                        }
                   1832:                }
                   1833:        }
                   1834:        free(v);
                   1835:        return (i);
                   1836: }
                   1837:
                   1838: static void
1.20      lukem    1839: idecl(sym_t *decl, int initflg, sbuf_t *rename)
1.1       cgd      1840: {
1.11      cgd      1841:        char *s;
                   1842:
1.1       cgd      1843:        initerr = 0;
                   1844:        initsym = decl;
                   1845:
1.3       jpo      1846:        switch (dcs->d_ctx) {
1.1       cgd      1847:        case EXTERN:
1.11      cgd      1848:                if (rename != NULL) {
                   1849:                        if (decl->s_rename != NULL)
1.25      christos 1850:                                LERROR("idecl()");
1.11      cgd      1851:
                   1852:                        s = getlblk(1, rename->sb_len + 1);
                   1853:                        (void)memcpy(s, rename->sb_name, rename->sb_len + 1);
                   1854:                        decl->s_rename = s;
                   1855:                        freeyyv(&rename, T_NAME);
                   1856:                }
1.1       cgd      1857:                decl1ext(decl, initflg);
                   1858:                break;
                   1859:        case ARG:
1.11      cgd      1860:                if (rename != NULL) {
                   1861:                        /* symbol renaming can't be used on function arguments */
                   1862:                        error(310);
                   1863:                        freeyyv(&rename, T_NAME);
                   1864:                        break;
                   1865:                }
1.1       cgd      1866:                (void)decl1arg(decl, initflg);
                   1867:                break;
                   1868:        case AUTO:
1.11      cgd      1869:                if (rename != NULL) {
                   1870:                        /* symbol renaming can't be used on automatic variables */
                   1871:                        error(311);
                   1872:                        freeyyv(&rename, T_NAME);
                   1873:                        break;
                   1874:                }
1.1       cgd      1875:                decl1loc(decl, initflg);
                   1876:                break;
                   1877:        default:
1.25      christos 1878:                LERROR("idecl()");
1.1       cgd      1879:        }
                   1880:
                   1881:        if (initflg && !initerr)
                   1882:                prepinit();
1.6       jpo      1883: }
                   1884:
                   1885: /*
                   1886:  * Discard all input tokens up to and including the next
                   1887:  * unmatched right paren
                   1888:  */
1.22      thorpej  1889: static void
1.20      lukem    1890: ignuptorp(void)
1.6       jpo      1891: {
                   1892:        int     level;
                   1893:
                   1894:        if (yychar < 0)
                   1895:                yychar = yylex();
                   1896:        freeyyv(&yylval, yychar);
                   1897:
                   1898:        level = 1;
                   1899:        while (yychar != T_RPARN || --level > 0) {
                   1900:                if (yychar == T_LPARN) {
                   1901:                        level++;
                   1902:                } else if (yychar <= 0) {
                   1903:                        break;
                   1904:                }
                   1905:                freeyyv(&yylval, yychar = yylex());
                   1906:        }
                   1907:
                   1908:        yyclearin;
1.1       cgd      1909: }

CVSweb <webmaster@jp.NetBSD.org>