cgram.y revision 1.27 1 %{
2 /* $NetBSD: cgram.y,v 1.27 2002/10/22 13:48:51 christos Exp $ */
3
4 /*
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
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
36 #include <sys/cdefs.h>
37 #if defined(__RCSID) && !defined(lint)
38 __RCSID("$NetBSD: cgram.y,v 1.27 2002/10/22 13:48:51 christos Exp $");
39 #endif
40
41 #include <stdlib.h>
42 #include <string.h>
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
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
67 static int toicon(tnode_t *, int);
68 static void idecl(sym_t *, int, sbuf_t *);
69 static void ignuptorp(void);
70
71 #ifdef DEBUG
72 static __inline void CLRWFLGS(void);
73 static __inline void CLRWFLGS(void)
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
81 static __inline void SAVE(void);
82 static __inline void SAVE(void)
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
91 static __inline void RESTORE(void);
92 static __inline void RESTORE(void)
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
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
176 %token T_ASM
177 %token T_SYMBOLRENAME
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
254 %type <y_sb> opt_asm_or_symbolrename
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:
278 asm_stmnt
279 | func_def {
280 glclup(0);
281 CLRWFLGS();
282 }
283 | data_def {
284 glclup(0);
285 CLRWFLGS();
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 {
309 if (dcs->d_scl == TYPEDEF) {
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 {
319 if (dcs->d_scl == TYPEDEF) {
320 /* typedef declares no type name */
321 warning(72);
322 } else if (!dcs->d_nedecl) {
323 /* empty declaration */
324 warning(2);
325 }
326 }
327 | declspecs deftyp type_init_decls T_SEMI
328 | error T_SEMI {
329 globclup();
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 {
398 if (!dcs->d_nedecl) {
399 /* empty declaration */
400 warning(2);
401 } else {
402 tspec_t ts = dcs->d_type->t_tspec;
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 {
409 if (dcs->d_nedecl) {
410 tspec_t ts = dcs->d_type->t_tspec;
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 {
422 if (dcs->d_scl == TYPEDEF) {
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 {
432 if (dcs->d_scl == TYPEDEF) {
433 /* typedef declares no type name */
434 warning(72);
435 } else if (!dcs->d_nedecl) {
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 *
526 * yychar is valid because otherwise the parser would
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 {
532 dcs->d_tagtyp = mktag($2, $1, 1, 0);
533 } struct_declaration {
534 $$ = compltag(dcs->d_tagtyp, $4);
535 }
536 | struct {
537 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
538 } struct_declaration {
539 $$ = compltag(dcs->d_tagtyp, $3);
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);
551 dcs->d_offset = 0;
552 dcs->d_stralign = CHAR_BIT;
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 {
684 $$ = bitfield($1, toicon($3, 1));
685 }
686 | {
687 symtyp = FVFT;
688 } T_COLON constant {
689 $$ = bitfield(NULL, toicon($3, 1));
690 }
691 ;
692
693 type_member_decl:
694 type_decl {
695 $$ = $1;
696 }
697 | type_decl T_COLON constant {
698 $$ = bitfield($1, toicon($3, 1));
699 }
700 | {
701 symtyp = FVFT;
702 } T_COLON constant {
703 $$ = bitfield(NULL, toicon($3, 1));
704 }
705 ;
706
707 enum_spec:
708 enum enum_tag {
709 $$ = mktag($2, ENUM, 0, 0);
710 }
711 | enum enum_tag {
712 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
713 } enum_declaration {
714 $$ = compltag(dcs->d_tagtyp, $4);
715 }
716 | enum {
717 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
718 } enum_declaration {
719 $$ = compltag(dcs->d_tagtyp, $3);
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 */
763 (void)gnuism(54);
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 {
786 $$ = ename($1, toicon($3, 1), 0);
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:
808 notype_decl opt_asm_or_symbolrename {
809 idecl($1, 0, $2);
810 chksz($1);
811 }
812 | notype_decl opt_asm_or_symbolrename {
813 idecl($1, 1, $2);
814 } T_ASSIGN initializer {
815 chksz($1);
816 }
817 ;
818
819 type_init_decl:
820 type_decl opt_asm_or_symbolrename {
821 idecl($1, 0, $2);
822 chksz($1);
823 }
824 | type_decl opt_asm_or_symbolrename {
825 idecl($1, 1, $2);
826 } T_ASSIGN initializer {
827 chksz($1);
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 {
851 $$ = addarray($1, 1, toicon($3, 0));
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 {
880 $$ = addarray($1, 1, toicon($3, 0));
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 {
916 $$ = addarray($1, 1, toicon($3, 0));
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 {
945 $$ = addarray($1, 1, toicon($3, 0));
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));
988 if ($1 == CONST) {
989 $$->p_const = 1;
990 } else {
991 $$->p_volatile = 1;
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 {
1029 dcs->d_proto = 1;
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 {
1049 dcs->d_vararg = 1;
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 }
1060 dcs->d_vararg = 1;
1061 $$ = NULL;
1062 }
1063 ;
1064
1065 parameter_type_list:
1066 parameter_declaration {
1067 $$ = $1;
1068 }
1069 | parameter_type_list T_COMMA parameter_declaration {
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
1102 opt_asm_or_symbolrename: /* expect only one */
1103 /* empty */ {
1104 $$ = NULL;
1105 }
1106 | T_ASM T_LPARN T_STRING T_RPARN {
1107 freeyyv(&$3, T_STRING);
1108 $$ = NULL;
1109 }
1110 | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN {
1111 $$ = $3;
1112 }
1113 ;
1114
1115 initializer:
1116 init_expr
1117 ;
1118
1119 init_expr:
1120 expr %prec T_COMMA {
1121 mkinit($1);
1122 }
1123 | init_by_name init_expr %prec T_COMMA
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
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
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 {
1203 $$ = addarray(aname(), 1, toicon($2, 0));
1204 }
1205 | direct_abs_decl T_LBRACK T_RBRACK {
1206 $$ = addarray($1, 0, 0);
1207 }
1208 | direct_abs_decl T_LBRACK constant T_RBRACK {
1209 $$ = addarray($1, 1, toicon($3, 0));
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 }
1232 | asm_stmnt
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:
1283 stmnt
1284 | stmnt_list stmnt {
1285 RESTORE();
1286 }
1287 | stmnt_list error T_SEMI
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 {
1302 SAVE();
1303 if2();
1304 if3(0);
1305 }
1306 | if_without_else T_ELSE {
1307 SAVE();
1308 if2();
1309 } stmnt {
1310 CLRWFLGS();
1311 if3(1);
1312 }
1313 | if_without_else T_ELSE error {
1314 CLRWFLGS();
1315 if3(0);
1316 }
1317 | switch_expr stmnt {
1318 CLRWFLGS();
1319 switch2();
1320 }
1321 | switch_expr error {
1322 CLRWFLGS();
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);
1335 CLRWFLGS();
1336 }
1337 ;
1338
1339 switch_expr:
1340 T_SWITCH T_LPARN expr T_RPARN {
1341 switch1($3);
1342 CLRWFLGS();
1343 }
1344 ;
1345
1346 do_stmnt:
1347 do stmnt {
1348 CLRWFLGS();
1349 }
1350 ;
1351
1352 iteration_stmnt:
1353 while_expr stmnt {
1354 CLRWFLGS();
1355 while2();
1356 }
1357 | while_expr error {
1358 CLRWFLGS();
1359 while2();
1360 }
1361 | do_stmnt do_while_expr {
1362 do2($2);
1363 ftflg = 0;
1364 }
1365 | do error {
1366 CLRWFLGS();
1367 do2(NULL);
1368 }
1369 | for_exprs stmnt {
1370 CLRWFLGS();
1371 for2();
1372 }
1373 | for_exprs error {
1374 CLRWFLGS();
1375 for2();
1376 }
1377 ;
1378
1379 while_expr:
1380 T_WHILE T_LPARN expr T_RPARN {
1381 while1($3);
1382 CLRWFLGS();
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);
1401 CLRWFLGS();
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
1441 asm_stmnt:
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
1449 ;
1450
1451 read_until_rparn:
1452 /* empty */ {
1453 ignuptorp();
1454 }
1455 ;
1456
1457 declaration_list:
1458 declaration {
1459 CLRWFLGS();
1460 }
1461 | declaration_list declaration {
1462 CLRWFLGS();
1463 }
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 {
1525 /* XXX really necessary? */
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 }
1596 ;
1597
1598 string:
1599 T_STRING {
1600 $$ = $1;
1601 }
1602 | T_STRING string2 {
1603 $$ = catstrg($1, $2);
1604 }
1605 ;
1606
1607 string2:
1608 T_STRING {
1609 if (tflag) {
1610 /* concatenated strings are illegal in traditional C */
1611 warning(219);
1612 }
1613 $$ = $1;
1614 }
1615 | string2 T_STRING {
1616 $$ = catstrg($1, $2);
1617 }
1618 ;
1619
1620 func_arg_list:
1621 expr %prec T_COMMA {
1622 $$ = funcarg(NULL, $1);
1623 }
1624 | func_arg_list T_COMMA expr {
1625 $$ = funcarg($1, $3);
1626 }
1627 ;
1628
1629 point_or_arrow:
1630 T_STROP {
1631 symtyp = FMOS;
1632 $$ = $1;
1633 }
1634 ;
1635
1636 point:
1637 T_STROP {
1638 if ($1 != POINT)
1639 error(249);
1640 }
1641 ;
1642
1643 identifier:
1644 T_NAME {
1645 $$ = $1;
1646 }
1647 | T_TYPENAME {
1648 $$ = $1;
1649 }
1650 ;
1651
1652 %%
1653
1654 /* ARGSUSED */
1655 int
1656 yyerror(char *msg)
1657 {
1658
1659 error(249);
1660 if (++sytxerr >= 5)
1661 norecover();
1662 return (0);
1663 }
1664
1665 static inline int uq_gt(uint64_t, uint64_t);
1666 static inline int q_gt(int64_t, int64_t);
1667
1668 static inline int
1669 uq_gt(uint64_t a, uint64_t b)
1670 {
1671
1672 return (a > b);
1673 }
1674
1675 static inline int
1676 q_gt(int64_t a, int64_t b)
1677 {
1678
1679 return (a > b);
1680 }
1681
1682 #define q_lt(a, b) q_gt(b, a)
1683
1684 /*
1685 * Gets a node for a constant and returns the value of this constant
1686 * as integer.
1687 * Is the node not constant or too large for int or of type float,
1688 * a warning will be printed.
1689 *
1690 * toicon() should be used only inside declarations. If it is used in
1691 * expressions, it frees the memory used for the expression.
1692 */
1693 static int
1694 toicon(tnode_t *tn, int required)
1695 {
1696 int i;
1697 tspec_t t;
1698 val_t *v;
1699
1700 v = constant(tn, required);
1701
1702 /*
1703 * Abstract declarations are used inside expression. To free
1704 * the memory would be a fatal error.
1705 */
1706 if (dcs->d_ctx != ABSTRACT)
1707 tfreeblk();
1708
1709 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1710 i = (int)v->v_ldbl;
1711 /* integral constant expression expected */
1712 error(55);
1713 } else {
1714 i = (int)v->v_quad;
1715 if (isutyp(t)) {
1716 if (uq_gt((uint64_t)v->v_quad,
1717 (uint64_t)INT_MAX)) {
1718 /* integral constant too large */
1719 warning(56);
1720 }
1721 } else {
1722 if (q_gt(v->v_quad, (int64_t)INT_MAX) ||
1723 q_lt(v->v_quad, (int64_t)INT_MIN)) {
1724 /* integral constant too large */
1725 warning(56);
1726 }
1727 }
1728 }
1729 free(v);
1730 return (i);
1731 }
1732
1733 static void
1734 idecl(sym_t *decl, int initflg, sbuf_t *rename)
1735 {
1736 char *s;
1737
1738 initerr = 0;
1739 initsym = decl;
1740
1741 switch (dcs->d_ctx) {
1742 case EXTERN:
1743 if (rename != NULL) {
1744 if (decl->s_rename != NULL)
1745 LERROR("idecl()");
1746
1747 s = getlblk(1, rename->sb_len + 1);
1748 (void)memcpy(s, rename->sb_name, rename->sb_len + 1);
1749 decl->s_rename = s;
1750 freeyyv(&rename, T_NAME);
1751 }
1752 decl1ext(decl, initflg);
1753 break;
1754 case ARG:
1755 if (rename != NULL) {
1756 /* symbol renaming can't be used on function arguments */
1757 error(310);
1758 freeyyv(&rename, T_NAME);
1759 break;
1760 }
1761 (void)decl1arg(decl, initflg);
1762 break;
1763 case AUTO:
1764 if (rename != NULL) {
1765 /* symbol renaming can't be used on automatic variables */
1766 error(311);
1767 freeyyv(&rename, T_NAME);
1768 break;
1769 }
1770 decl1loc(decl, initflg);
1771 break;
1772 default:
1773 LERROR("idecl()");
1774 }
1775
1776 if (initflg && !initerr)
1777 prepinit();
1778 }
1779
1780 /*
1781 * Discard all input tokens up to and including the next
1782 * unmatched right paren
1783 */
1784 static void
1785 ignuptorp(void)
1786 {
1787 int level;
1788
1789 if (yychar < 0)
1790 yychar = yylex();
1791 freeyyv(&yylval, yychar);
1792
1793 level = 1;
1794 while (yychar != T_RPARN || --level > 0) {
1795 if (yychar == T_LPARN) {
1796 level++;
1797 } else if (yychar <= 0) {
1798 break;
1799 }
1800 freeyyv(&yylval, yychar = yylex());
1801 }
1802
1803 yyclearin;
1804 }
1805