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