2 /* $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $ */
5 * Copyright (c) 1994, 1995 Jochen Pohl
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 static char rcsid[] = "$NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $";
45 * Contains the level of current declaration. 0 is extern.
46 * Used for symbol table entries.
51 * level for memory allocation. Normaly the same as blklev.
52 * An exeption is the declaration of arguments in prototypes. Memory
53 * for these can't be freed after the declaration, but symbols must
54 * be removed from the symbol table after the declaration.
58 static int toicon __P((tnode_t *));
59 static void idecl __P((sym_t *, int));
60 static void ignuptorp __P((void));
79 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
82 %token <y_op> T_INCDEC
87 %token <y_op> T_SHFTOP
93 %token <y_op> T_LOGAND
97 %token <y_op> T_ASSIGN
103 /* storage classes (extern, static, auto, register and typedef) */
104 %token <y_scl> T_SCLASS
106 /* types (char, int, short, long, unsigned, signed, float, double, void) */
107 %token <y_tspec> T_TYPE
109 /* qualifiers (const, volatile) */
110 %token <y_tqual> T_QUAL
112 /* struct or union */
113 %token <y_tspec> T_SOU
118 /* remaining keywords */
134 %right T_ASSIGN T_OPASS
135 %right T_QUEST T_COLON
146 %right T_UNOP T_INCDEC T_SIZEOF
147 %left T_LPARN T_LBRACK T_STROP
150 %token <y_sb> T_TYPENAME
152 %token <y_strg> T_STRING
154 %type <y_sym> func_decl
155 %type <y_sym> notype_decl
156 %type <y_sym> type_decl
157 %type <y_type> typespec
158 %type <y_type> clrtyp_typespec
159 %type <y_type> notype_typespec
160 %type <y_type> struct_spec
161 %type <y_type> enum_spec
162 %type <y_sym> struct_tag
163 %type <y_sym> enum_tag
164 %type <y_tspec> struct
165 %type <y_sym> struct_declaration
166 %type <y_sb> identifier
167 %type <y_sym> member_declaration_list_with_rbrace
168 %type <y_sym> member_declaration_list
169 %type <y_sym> member_declaration
170 %type <y_sym> notype_member_decls
171 %type <y_sym> type_member_decls
172 %type <y_sym> notype_member_decl
173 %type <y_sym> type_member_decl
174 %type <y_tnode> constant
175 %type <y_sym> enum_declaration
176 %type <y_sym> enums_with_opt_comma
178 %type <y_sym> enumerator
180 %type <y_sym> notype_direct_decl
181 %type <y_sym> type_direct_decl
182 %type <y_pqinf> pointer
183 %type <y_pqinf> asterisk
184 %type <y_sym> param_decl
185 %type <y_sym> param_list
186 %type <y_sym> abs_decl_param_list
187 %type <y_sym> direct_param_decl
188 %type <y_sym> notype_param_decl
189 %type <y_sym> direct_notype_param_decl
190 %type <y_pqinf> type_qualifier_list
191 %type <y_pqinf> type_qualifier
192 %type <y_sym> identifier_list
193 %type <y_sym> abs_decl
194 %type <y_sym> direct_abs_decl
195 %type <y_sym> vararg_parameter_type_list
196 %type <y_sym> parameter_type_list
197 %type <y_sym> parameter_declaration
200 %type <y_tnode> func_arg_list
201 %type <y_op> point_or_arrow
202 %type <y_type> type_name
203 %type <y_sym> abstract_declaration
204 %type <y_tnode> do_while_expr
205 %type <y_tnode> opt_expr
206 %type <y_strg> string
207 %type <y_strg> string2
215 /* empty translation unit */
218 /* empty translation unit */
227 | translation_unit ext_decl
244 /* syntax error: empty declaration */
247 /* syntax error: empty declaration */
251 | clrtyp deftyp notype_init_decls T_SEMI {
253 /* old style declaration; add "int" */
256 /* old style declaration; add "int" */
260 | declmods deftyp T_SEMI {
261 if (dcs->d_scl == TYPEDEF) {
262 /* typedef declares no type name */
265 /* empty declaration */
269 | declmods deftyp notype_init_decls T_SEMI
270 | declspecs deftyp T_SEMI {
271 if (dcs->d_scl == TYPEDEF) {
272 /* typedef declares no type name */
274 } else if (!dcs->d_nedecl) {
275 /* empty declaration */
279 | declspecs deftyp type_init_decls T_SEMI
290 if ($1->s_type->t_tspec != FUNC) {
295 if ($1->s_type->t_typedef) {
296 /* ()-less function definition */
303 } opt_arg_declaration_list {
315 clrtyp deftyp notype_decl {
318 | declmods deftyp notype_decl {
321 | declspecs deftyp type_decl {
326 opt_arg_declaration_list:
328 | arg_declaration_list
331 arg_declaration_list:
333 | arg_declaration_list arg_declaration
334 /* XXX or better "arg_declaration error" ? */
339 * "arg_declaration" is separated from "declaration" because it
340 * needs other error handling.
344 declmods deftyp T_SEMI {
345 /* empty declaration */
348 | declmods deftyp notype_init_decls T_SEMI
349 | declspecs deftyp T_SEMI {
350 if (!dcs->d_nedecl) {
351 /* empty declaration */
354 tspec_t ts = dcs->d_type->t_tspec;
355 /* %s declared in argument declaration list */
356 warning(3, ts == STRUCT ? "struct" :
357 (ts == UNION ? "union" : "enum"));
360 | declspecs deftyp type_init_decls T_SEMI {
362 tspec_t ts = dcs->d_type->t_tspec;
363 /* %s declared in argument declaration list */
364 warning(3, ts == STRUCT ? "struct" :
365 (ts == UNION ? "union" : "enum"));
373 declmods deftyp T_SEMI {
374 if (dcs->d_scl == TYPEDEF) {
375 /* typedef declares no type name */
378 /* empty declaration */
382 | declmods deftyp notype_init_decls T_SEMI
383 | declspecs deftyp T_SEMI {
384 if (dcs->d_scl == TYPEDEF) {
385 /* typedef declares no type name */
387 } else if (!dcs->d_nedecl) {
388 /* empty declaration */
392 | declspecs deftyp type_init_decls T_SEMI
412 | declmods typespec {
416 | declspecs notype_typespec {
441 clrtyp notype_typespec {
444 | T_TYPENAME clrtyp {
445 $$ = getsym($1)->s_type;
454 $$ = getsym($1)->s_type;
475 * STDC requires that "struct a;" always introduces
476 * a new tag if "a" is not declared at current level
478 * yychar is valid because otherwise the parser would
479 * not been able to deceide if he must shift or reduce
481 $$ = mktag($2, $1, 0, yychar == T_SEMI);
483 | struct struct_tag {
484 dcs->d_tagtyp = mktag($2, $1, 1, 0);
485 } struct_declaration {
486 $$ = compltag(dcs->d_tagtyp, $4);
489 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
490 } struct_declaration {
491 $$ = compltag(dcs->d_tagtyp, $3);
502 pushdecl($1 == STRUCT ? MOS : MOU);
504 dcs->d_stralign = CHAR_BIT;
516 struct_decl_lbrace member_declaration_list_with_rbrace {
527 member_declaration_list_with_rbrace:
528 member_declaration_list T_SEMI T_RBRACE {
531 | member_declaration_list T_RBRACE {
533 /* syntax req. ";" after last struct/union member */
536 /* syntax req. ";" after last struct/union member */
546 member_declaration_list:
550 | member_declaration_list T_SEMI member_declaration {
556 noclass_declmods deftyp {
557 /* too late, i know, but getsym() compensates it */
559 } notype_member_decls {
563 | noclass_declspecs deftyp {
565 } type_member_decls {
569 | noclass_declmods deftyp {
570 /* struct or union member must be named */
574 | noclass_declspecs deftyp {
575 /* struct or union member must be named */
589 | noclass_declmods typespec {
592 | noclass_declspecs T_QUAL {
595 | noclass_declspecs notype_typespec {
604 | noclass_declmods T_QUAL {
613 | notype_member_decls {
615 } T_COMMA type_member_decl {
616 $$ = lnklst($1, decl1str($4));
624 | type_member_decls {
626 } T_COMMA type_member_decl {
627 $$ = lnklst($1, decl1str($4));
635 | notype_decl T_COLON constant {
636 $$ = bitfield($1, toicon($3));
641 $$ = bitfield(NULL, toicon($3));
649 | type_decl T_COLON constant {
650 $$ = bitfield($1, toicon($3));
655 $$ = bitfield(NULL, toicon($3));
661 $$ = mktag($2, ENUM, 0, 0);
664 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
666 $$ = compltag(dcs->d_tagtyp, $4);
669 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
671 $$ = compltag(dcs->d_tagtyp, $3);
693 enum_decl_lbrace enums_with_opt_comma T_RBRACE {
705 enums_with_opt_comma:
711 /* trailing "," prohibited in enum declaration */
714 /* trailing "," prohibited in enum declaration */
725 | enums T_COMMA enumerator {
735 $$ = ename($1, enumval, 1);
737 | ename T_ASSIGN constant {
738 $$ = ename($1, toicon($3), 0);
751 | notype_init_decls T_COMMA type_init_decl
756 | type_init_decls T_COMMA type_init_decl
760 notype_decl opt_asm_spec {
764 | notype_decl opt_asm_spec {
766 } T_ASSIGN initializer {
772 type_decl opt_asm_spec {
776 | type_decl opt_asm_spec {
778 } T_ASSIGN initializer {
787 | pointer notype_direct_decl {
794 $$ = dname(getsym($1));
796 | T_LPARN type_decl T_RPARN {
799 | notype_direct_decl T_LBRACK T_RBRACK {
800 $$ = addarray($1, 0, 0);
802 | notype_direct_decl T_LBRACK constant T_RBRACK {
803 $$ = addarray($1, 1, toicon($3));
805 | notype_direct_decl param_list {
806 $$ = addfunc($1, $2);
816 | pointer type_direct_decl {
823 $$ = dname(getsym($1));
825 | T_LPARN type_decl T_RPARN {
828 | type_direct_decl T_LBRACK T_RBRACK {
829 $$ = addarray($1, 0, 0);
831 | type_direct_decl T_LBRACK constant T_RBRACK {
832 $$ = addarray($1, 1, toicon($3));
834 | type_direct_decl param_list {
835 $$ = addfunc($1, $2);
842 * param_decl and notype_param_decl exist to avoid a conflict in
843 * argument lists. A typename enclosed in parens should always be
844 * treated as a typename, not an argument.
845 * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
846 * not "typedef int a; f(int a);"
852 | pointer direct_param_decl {
859 $$ = dname(getsym($1));
861 | T_LPARN notype_param_decl T_RPARN {
864 | direct_param_decl T_LBRACK T_RBRACK {
865 $$ = addarray($1, 0, 0);
867 | direct_param_decl T_LBRACK constant T_RBRACK {
868 $$ = addarray($1, 1, toicon($3));
870 | direct_param_decl param_list {
871 $$ = addfunc($1, $2);
878 direct_notype_param_decl {
881 | pointer direct_notype_param_decl {
886 direct_notype_param_decl:
888 $$ = dname(getsym($1));
890 | T_LPARN notype_param_decl T_RPARN {
893 | direct_notype_param_decl T_LBRACK T_RBRACK {
894 $$ = addarray($1, 0, 0);
896 | direct_notype_param_decl T_LBRACK constant T_RBRACK {
897 $$ = addarray($1, 1, toicon($3));
899 | direct_notype_param_decl param_list {
900 $$ = addfunc($1, $2);
910 | asterisk type_qualifier_list {
911 $$ = mergepq($1, $2);
914 $$ = mergepq($1, $2);
916 | asterisk type_qualifier_list pointer {
917 $$ = mergepq(mergepq($1, $2), $3);
923 $$ = xcalloc(1, sizeof (pqinf_t));
932 | type_qualifier_list type_qualifier {
933 $$ = mergepq($1, $2);
939 $$ = xcalloc(1, sizeof (pqinf_t));
949 id_list_lparn identifier_list T_RPARN {
952 | abs_decl_param_list {
966 $$ = iname(getsym($1));
968 | identifier_list T_COMMA T_NAME {
969 $$ = lnklst($1, iname(getsym($3)));
971 | identifier_list error {
977 abs_decl_lparn T_RPARN {
980 | abs_decl_lparn vararg_parameter_type_list T_RPARN {
984 | abs_decl_lparn error T_RPARN {
996 vararg_parameter_type_list:
997 parameter_type_list {
1000 | parameter_type_list T_COMMA T_ELLIPSE {
1006 /* ANSI C requires formal parameter before "..." */
1008 } else if (!tflag) {
1009 /* ANSI C requires formal parameter before "..." */
1017 parameter_type_list:
1018 parameter_declaration opt_asm_spec {
1021 | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
1022 $$ = lnklst($1, $3);
1026 parameter_declaration:
1028 $$ = decl1arg(aname(), 0);
1030 | declspecs deftyp {
1031 $$ = decl1arg(aname(), 0);
1033 | declmods deftyp notype_param_decl {
1034 $$ = decl1arg($3, 0);
1037 * param_decl is needed because of following conflict:
1038 * "typedef int a; f(int (a));" could be parsed as
1039 * "function with argument a of type int", or
1040 * "function with an abstract argument of type function".
1041 * This grammar realizes the second case.
1043 | declspecs deftyp param_decl {
1044 $$ = decl1arg($3, 0);
1046 | declmods deftyp abs_decl {
1047 $$ = decl1arg($3, 0);
1049 | declspecs deftyp abs_decl {
1050 $$ = decl1arg($3, 0);
1056 | T_ASM T_LPARN T_STRING T_RPARN {
1057 freeyyv(&$3, T_STRING);
1066 expr %prec T_COMMA {
1069 | init_lbrace init_expr_list init_rbrace
1070 | init_lbrace init_expr_list T_COMMA init_rbrace
1075 init_expr %prec T_COMMA
1076 | init_expr_list T_COMMA init_expr
1094 } abstract_declaration {
1100 abstract_declaration:
1101 noclass_declmods deftyp {
1102 $$ = decl1abs(aname());
1104 | noclass_declspecs deftyp {
1105 $$ = decl1abs(aname());
1107 | noclass_declmods deftyp abs_decl {
1110 | noclass_declspecs deftyp abs_decl {
1117 $$ = addptr(aname(), $1);
1122 | pointer direct_abs_decl {
1123 $$ = addptr($2, $1);
1128 T_LPARN abs_decl T_RPARN {
1131 | T_LBRACK T_RBRACK {
1132 $$ = addarray(aname(), 0, 0);
1134 | T_LBRACK constant T_RBRACK {
1135 $$ = addarray(aname(), 1, toicon($2));
1137 | direct_abs_decl T_LBRACK T_RBRACK {
1138 $$ = addarray($1, 0, 0);
1140 | direct_abs_decl T_LBRACK constant T_RBRACK {
1141 $$ = addarray($1, 1, toicon($3));
1143 | abs_decl_param_list {
1144 $$ = addfunc(aname(), $1);
1148 | direct_abs_decl abs_decl_param_list {
1149 $$ = addfunc($1, $2);
1172 identifier T_COLON {
1174 label(T_NAME, getsym($1), NULL);
1176 | T_CASE constant T_COLON {
1177 label(T_CASE, NULL, $2);
1180 | T_DEFAULT T_COLON {
1181 label(T_DEFAULT, NULL, NULL);
1187 compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1188 | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1218 | stmnt_list stmnt {
1221 | stmnt_list error T_SEMI {
1241 | if_without_else T_ELSE {
1246 | if_without_else T_ELSE error {
1249 | switch_expr stmnt {
1252 | switch_expr error {
1263 T_IF T_LPARN expr T_RPARN {
1270 T_SWITCH T_LPARN expr T_RPARN {
1280 | while_expr error {
1283 | do stmnt do_while_expr {
1299 T_WHILE T_LPARN expr T_RPARN {
1312 T_WHILE T_LPARN expr T_RPARN T_SEMI {
1318 T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1334 goto identifier T_SEMI {
1337 | goto error T_SEMI {
1340 | T_CONTINUE T_SEMI {
1349 | T_RETURN expr T_SEMI {
1361 T_ASM T_LPARN read_until_rparn T_SEMI {
1364 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1380 | declaration_list declaration {
1386 expr %prec T_COMMA {
1393 $$ = build(MULT, $1, $3);
1395 | expr T_DIVOP expr {
1396 $$ = build($2, $1, $3);
1398 | expr T_ADDOP expr {
1399 $$ = build($2, $1, $3);
1401 | expr T_SHFTOP expr {
1402 $$ = build($2, $1, $3);
1404 | expr T_RELOP expr {
1405 $$ = build($2, $1, $3);
1407 | expr T_EQOP expr {
1408 $$ = build($2, $1, $3);
1411 $$ = build(AND, $1, $3);
1414 $$ = build(XOR, $1, $3);
1417 $$ = build(OR, $1, $3);
1419 | expr T_LOGAND expr {
1420 $$ = build(LOGAND, $1, $3);
1422 | expr T_LOGOR expr {
1423 $$ = build(LOGOR, $1, $3);
1425 | expr T_QUEST expr T_COLON expr {
1426 $$ = build(QUEST, $1, build(COLON, $3, $5));
1428 | expr T_ASSIGN expr {
1429 $$ = build(ASSIGN, $1, $3);
1431 | expr T_OPASS expr {
1432 $$ = build($2, $1, $3);
1434 | expr T_COMMA expr {
1435 $$ = build(COMMA, $1, $3);
1444 /* XXX realy neccessary? */
1447 $$ = getnnode(getsym($1), yychar);
1453 $$ = getcnode(gettyp($1->v_tspec), $1);
1455 | T_LPARN expr T_RPARN {
1461 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1464 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1467 $$ = build(STAR, $2, NULL);
1470 $$ = build(AMPER, $2, NULL);
1473 $$ = build($1, $2, NULL);
1476 if (tflag && $1 == PLUS) {
1477 /* unary + is illegal in traditional C */
1480 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1482 | term T_LBRACK expr T_RBRACK {
1483 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1485 | term T_LPARN T_RPARN {
1486 $$ = funccall($1, NULL);
1488 | term T_LPARN func_arg_list T_RPARN {
1489 $$ = funccall($1, $3);
1491 | term point_or_arrow T_NAME {
1494 /* XXX strmemb should be integrated in build() */
1496 /* must to this before strmemb is called */
1499 msym = strmemb($1, $2, getsym($3));
1500 $$ = build($2, $1, getnnode(msym, 0));
1505 | T_SIZEOF term %prec T_SIZEOF {
1506 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1507 chkmisc($2, 0, 0, 0, 0, 0, 1);
1509 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1512 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1521 | T_STRING string2 {
1522 $$ = catstrg($1, $2);
1529 /* concatenated strings are illegal in traditional C */
1534 | string2 T_STRING {
1535 $$ = catstrg($1, $2);
1540 expr %prec T_COMMA {
1541 $$ = funcarg(NULL, $1);
1543 | func_arg_list T_COMMA expr {
1544 $$ = funcarg($1, $3);
1578 * Gets a node for a constant and returns the value of this constant
1580 * Is the node not constant or too large for int or of type float,
1581 * a warning will be printed.
1583 * toicon() should be used only inside declarations. If it is used in
1584 * expressions, it frees the memory used for the expression.
1597 * Abstract declarations are used inside expression. To free
1598 * the memory would be a fatal error.
1600 if (dcs->d_ctx != ABSTRACT)
1603 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1605 /* integral constant expression expected */
1610 if ((u_quad_t)v->v_quad > INT_MAX) {
1611 /* integral constant too large */
1615 #ifdef XXX_BROKEN_GCC
1616 if (v->v_quad > INT_MAX) {
1617 /* integral constant too large */
1620 else if (v->v_quad < INT_MIN) {
1621 /* integral constant too large */
1625 if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1626 /* integral constant too large */
1637 idecl(decl, initflg)
1644 switch (dcs->d_ctx) {
1646 decl1ext(decl, initflg);
1649 (void)decl1arg(decl, initflg);
1652 decl1loc(decl, initflg);
1658 if (initflg && !initerr)
1663 * Discard all input tokens up to and including the next
1664 * unmatched right paren
1673 freeyyv(&yylval, yychar);
1676 while (yychar != T_RPARN || --level > 0) {
1677 if (yychar == T_LPARN) {
1679 } else if (yychar <= 0) {
1682 freeyyv(&yylval, yychar = yylex());