[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.28

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

CVSweb <webmaster@jp.NetBSD.org>