xref: /inferno-os/utils/c2l/cc.y (revision 45a20ab721a513710138340faff3d59a31c3e01e)
1 %{
2 #include "cc.h"
3 %}
4 %union	{
5 	Node*	node;
6 	Sym*	sym;
7 	Type*	type;
8 	struct
9 	{
10 		Type*	t;
11 		char	c;
12 	} tycl;
13 	struct
14 	{
15 		Type*	t1;
16 		Type*	t2;
17 	} tyty;
18 	struct
19 	{
20 		char*	s;
21 		long	l;
22 	} sval;
23 	long	lval;
24 	double	dval;
25 	vlong	vval;
26 }
27 %type	<sym>	ltag
28 %type	<lval>	gctname cname gname tname
29 %type	<lval>	gctnlist zgnlist tnlist
30 %type	<type>	tlist etlist sbody complex
31 %type	<tycl>	types etypes
32 %type	<node>	zarglist arglist zcexpr
33 %type	<node>	name block stmnt cexpr expr xuexpr pexpr
34 %type	<node>	zelist elist adecl slist uexpr string lstring sstring slstring
35 %type	<node>	xdecor xdecor2 labels label ulstmnt
36 %type	<node>	adlist edecor tag qual qlist
37 %type	<node>	abdecor abdecor1 abdecor2 abdecor3
38 %type	<node>	zexpr lexpr init ilist
39 
40 %left	';'
41 %left	','
42 %right	'=' LPE LME LMLE LDVE LMDE LRSHE LLSHE LANDE LXORE LORE
43 %right	'?' ':'
44 %left	LOROR
45 %left	LANDAND
46 %left	'|'
47 %left	'^'
48 %left	'&'
49 %left	LEQ LNE
50 %left	'<' '>' LLE LGE
51 %left	LLSH LRSH
52 %left	'+' '-'
53 %left	'*' '/' '%'
54 %right	LMM LPP LMG '.' '[' '('
55 
56 %token	<sym>	LNAME LCTYPE LSTYPE
57 %token	<dval>	LFCONST LDCONST
58 %token	<vval>	LCHARACTER LCONST LLCONST LUCONST LULCONST LVLCONST LUVLCONST
59 %token	<sval>	LSTRING LLSTRING
60 %token		LAUTO LBREAK LCASE LCHAR LCONTINUE LDEFAULT LDO
61 %token		LDOUBLE LELSE LEXTERN LFLOAT LFOR LGOTO
62 %token	LIF LINT LLONG LREGISTER LRETURN LSHORT LSIZEOF LUSED
63 %token	LSTATIC LSTRUCT LSWITCH LTYPEDEF LUNION LUNSIGNED LWHILE
64 %token	LVOID LENUM LSIGNED LCONSTNT LVOLATILE LSET LSIGNOF LVLONG
65 %%
66 prog:
67 |	prog xdecl
68 
69 /*
70  * external declarator
71  */
72 xdecl:
73 	zctlist ';'
74 	{
75 		dodecl(xdecl, lastclass, lasttype, Z, 1);
76 	}
77 |	zctlist xdlist ';'
78 |	zctlist xdecor
79 	{
80 		lastdcl = T;
81 		dodecl(xdecl, lastclass, lasttype, $2, 0);
82 		if(lastdcl == T || lastdcl->etype != TFUNC) {
83 			diag($2, "not a function");
84 			lastdcl = types[TFUNC];
85 		}
86 		thisfn = lastdcl;
87 		markdcl();
88 		firstdcl = dclstack;
89 		argmark($2, 0);
90 	}
91 	pdecl
92 	{
93 		argmark($2, 1);
94 	}
95 	block
96 	{
97 		$6->blk = 0;
98 		codgen($6, $2, lineno);
99 		revertdcl();
100 	}
101 
102 xdlist:
103 	xdecor
104 	{
105 		dodecl(xdecl, lastclass, lasttype, $1, 1);
106 	}
107 |	xdecor
108 	{
109 		$1 = dodecl(xdecl, lastclass, lasttype, $1, 0);
110 	}
111 	'=' init
112 	{
113 		$4 = doinit($1->sym, $1->type, 0L, $4);
114 		$4 = new(ODAS, $1, $4);
115 		$4->type = $1->type;
116 		$4->lineno = $1->lineno;
117 		vtgen($4);
118 	}
119 |	xdlist ',' xdlist
120 
121 xdecor:
122 	xdecor2
123 |	'*' zgnlist xdecor
124 	{
125 		$$ = new(OIND, $3, Z);
126 		$$->garb = simpleg($2);
127 	}
128 
129 xdecor2:
130 	tag
131 |	'(' xdecor ')'
132 	{
133 		$$ = $2;
134 	}
135 |	xdecor2 '(' zarglist ')'
136 	{
137 		$$ = new(OFUNC, $1, $3);
138 		/* outfun($$); */
139 	}
140 |	xdecor2 '[' zexpr ']'
141 	{
142 		$$ = new(OARRAY, $1, $3);
143 	}
144 
145 /*
146  * automatic declarator
147  */
148 adecl:
149 	{
150 		$$ = Z;
151 	}
152 |	adecl ctlist ';'
153 	{
154 		$$ = dodecl(adecl, lastclass, lasttype, Z, 1);
155 		if($1 != Z)
156 			if($$ != Z)
157 				$$ = new(OLIST, $1, $$);
158 			else
159 				$$ = $1;
160 	}
161 |	adecl ctlist adlist ';'
162 	{
163 		$$ = $1;
164 		if($3 != Z) {
165 			$$ = $3;
166 			if($1 != Z)
167 				$$ = new(OLIST, $1, $3);
168 		}
169 	}
170 
171 adlist:
172 	xdecor
173 	{
174 		$$ = dodecl(adecl, lastclass, lasttype, $1, 1);
175 		if($$->sym->class == CSTATIC)
176 			$$ = Z;
177 	}
178 |	xdecor
179 	{
180 		$1 = dodecl(adecl, lastclass, lasttype, $1, 0);
181 	}
182 	'=' init
183 	{
184 		/* long w; */
185 
186 		/* w = $1->sym->type->width; */
187 		$$ = doinit($1->sym, $1->type, 0L, $4);
188 		/* $$ = contig($1->sym, $$, w); */
189 		$$ = new(ODAS, $1, $$);
190 		$$->type = $1->type;
191 		$$->lineno = $1->lineno;
192 		vtgen($$);
193 		if($1->sym->class == CSTATIC)
194 			$$ = Z;
195 	}
196 |	adlist ',' adlist
197 	{
198 		$$ = $1;
199 		if($3 != Z) {
200 			$$ = $3;
201 			if($1 != Z)
202 				$$ = new(OLIST, $1, $3);
203 		}
204 	}
205 
206 /*
207  * parameter declarator
208  */
209 pdecl:
210 |	pdecl ctlist pdlist ';'
211 
212 pdlist:
213 	xdecor
214 	{
215 		dodecl(pdecl, lastclass, lasttype, $1, 1);
216 	}
217 |	pdlist ',' pdlist
218 
219 /*
220  * structure element declarator
221  */
222 edecl:
223 	etlist
224 	{
225 		lasttype = $1;
226 	}
227 	zedlist ';'
228 |	edecl etlist
229 	{
230 		lasttype = $2;
231 	}
232 	zedlist ';'
233 
234 zedlist:					/* extension */
235 	{
236 		lastfield = 0;
237 		edecl(CXXX, lasttype, S);
238 	}
239 |	edlist
240 
241 edlist:
242 	edecor
243 	{
244 		dodecl(edecl, CXXX, lasttype, $1, 1);
245 	}
246 |	edlist ',' edlist
247 
248 edecor:
249 	xdecor
250 	{
251 		lastbit = 0;
252 		firstbit = 1;
253 	}
254 |	tag ':' lexpr
255 	{
256 		$$ = new(OBIT, $1, $3);
257 	}
258 |	':' lexpr
259 	{
260 		$$ = new(OBIT, Z, $2);
261 	}
262 
263 /*
264  * abstract declarator
265  */
266 abdecor:
267 	{
268 		$$ = (Z);
269 	}
270 |	abdecor1
271 
272 abdecor1:
273 	'*' zgnlist
274 	{
275 		$$ = new(OIND, (Z), Z);
276 		$$->garb = simpleg($2);
277 	}
278 |	'*' zgnlist abdecor1
279 	{
280 		$$ = new(OIND, $3, Z);
281 		$$->garb = simpleg($2);
282 	}
283 |	abdecor2
284 
285 abdecor2:
286 	abdecor3
287 |	abdecor2 '(' zarglist ')'
288 	{
289 		$$ = new(OFUNC, $1, $3);
290 	}
291 |	abdecor2 '[' zexpr ']'
292 	{
293 		$$ = new(OARRAY, $1, $3);
294 	}
295 
296 abdecor3:
297 	'(' ')'
298 	{
299 		$$ = new(OFUNC, (Z), Z);
300 	}
301 |	'[' zexpr ']'
302 	{
303 		$$ = new(OARRAY, (Z), $2);
304 	}
305 |	'(' abdecor1 ')'
306 	{
307 		$$ = $2;
308 	}
309 
310 init:
311 	expr
312 |	'{' ilist '}'
313 	{
314 		$$ = new(OINIT, invert($2), Z);
315 	}
316 
317 qual:
318 	'[' lexpr ']'
319 	{
320 		$$ = new(OARRAY, $2, Z);
321 	}
322 |	'.' ltag
323 	{
324 		$$ = new(OELEM, Z, Z);
325 		$$->sym = $2;
326 	}
327 |	qual '='
328 
329 qlist:
330 	init ','
331 |	qlist init ','
332 	{
333 		$$ = new(OLIST, $1, $2);
334 	}
335 |	qual
336 |	qlist qual
337 	{
338 		$$ = new(OLIST, $1, $2);
339 	}
340 
341 ilist:
342 	qlist
343 |	init
344 |	qlist init
345 	{
346 		$$ = new(OLIST, $1, $2);
347 	}
348 
349 zarglist:
350 	{
351 		$$ = Z;
352 	}
353 |	arglist
354 	{
355 		$$ = invert($1);
356 	}
357 
358 
359 arglist:
360 	name
361 |	tlist abdecor
362 	{
363 		$$ = new(OPROTO, $2, Z);
364 		$$->type = $1;
365 	}
366 |	tlist xdecor
367 	{
368 		$$ = new(OPROTO, $2, Z);
369 		$$->type = $1;
370 	}
371 |	'.' '.' '.'
372 	{
373 		$$ = new(ODOTDOT, Z, Z);
374 	}
375 |	arglist ',' arglist
376 	{
377 		$$ = new(OLIST, $1, $3);
378 	}
379 
380 block:
381 	'{' adecl slist '}'
382 	{
383 		$$ = invert($3);
384 		if($2 != Z)
385 			$$ = new(OLIST, $2, $$);
386 		if($$ == Z)
387 			$$ = new(ONUL, Z, Z);
388 		$$->blk = 1;
389 	}
390 
391 slist:
392 	{
393 		$$ = Z;
394 	}
395 |	slist stmnt
396 	{
397 		if($1 == Z)
398 			$$ = $2;
399 		else
400 			$$ = new(OLIST, $1, $2);
401 	}
402 
403 labels:
404 	label
405 |	labels label
406 	{
407 		$$ = new(OLIST, $1, $2);
408 	}
409 
410 label:
411 	LCASE expr ':'
412 	{
413 		$$ = new(OCASE, $2, Z);
414 		$$->lineno = $2->lineno;
415 	}
416 |	LDEFAULT ':'
417 	{
418 		$$ = new(OCASE, Z, Z);
419 	}
420 |	LNAME ':'
421 	{
422 		$$ = new(OLABEL, dcllabel($1, 1), Z);
423 		$1->lineno = lineno;
424 	}
425 
426 stmnt:
427 	error ';'
428 	{
429 		$$ = Z;
430 	}
431 |	ulstmnt
432 |	labels ulstmnt
433 	{
434 		$$ = new(OLIST, $1, $2);
435 	}
436 
437 ulstmnt:
438 	zcexpr ';'
439 	{
440 		if($$ == Z)
441 			$$ = new(ONUL, Z, Z);
442 		$$->kind = KEXP;
443 	}
444 |	{
445 		markdcl();
446 	}
447 	block
448 	{
449 		revertdcl();
450 		$$ = $2;
451 	}
452 |	LIF '(' cexpr ')' stmnt
453 	{
454 		$$ = new(OIF, $3, new(OLIST, $5, Z));
455 		$$->lineno = $3->lineno;
456 		$5->blk = 0;
457 	}
458 |	LIF '(' cexpr ')' stmnt LELSE stmnt
459 	{
460 		$$ = new(OIF, $3, new(OLIST, $5, $7));
461 		$$->lineno = $3->lineno;
462 		$5->blk = $7->blk = 0;
463 	}
464 |	LFOR '(' zcexpr ';' zcexpr ';' zcexpr ')' stmnt
465 	{
466 		$$ = new(OFOR, new(OLIST, $5, new(OLIST, $3, $7)), $9);
467 		if($3 != Z)
468 			$$->lineno = $3->lineno;
469 		else if($5 != Z)
470 			$$->lineno = $5->lineno;
471 		else if($7 != Z)
472 			$$->lineno = $7->lineno;
473 		else
474 			$$->lineno = line($9);
475 		$9->blk = 0;
476 	}
477 |	LWHILE '(' cexpr ')' stmnt
478 	{
479 		$$ = new(OWHILE, $3, $5);
480 		$$->lineno = $3->lineno;
481 		$5->blk = 0;
482 	}
483 |	LDO stmnt LWHILE '(' cexpr ')' ';'
484 	{
485 		$$ = new(ODWHILE, $5, $2);
486 		$$->lineno = line($2);
487 		$2->blk = 0;
488 	}
489 |	LRETURN zcexpr ';'
490 	{
491 		$$ = new(ORETURN, $2, Z);
492 		$$->type = thisfn->link;
493 		if($2 != Z)
494 			$$->lineno = $2->lineno;
495 	}
496 |	LSWITCH '(' cexpr ')' stmnt
497 	{
498 		$$ = new(OSWITCH, $3, $5);
499 		$$->lineno = $3->lineno;
500 		$5->blk = 0;
501 	}
502 |	LBREAK ';'
503 	{
504 		$$ = new(OBREAK, Z, Z);
505 	}
506 |	LCONTINUE ';'
507 	{
508 		$$ = new(OCONTINUE, Z, Z);
509 	}
510 |	LGOTO LNAME ';'
511 	{
512 		$$ = new(OGOTO, dcllabel($2, 0), Z);
513 		$2->lineno = lineno;
514 	}
515 |	LUSED '(' zelist ')' ';'
516 	{
517 		$$ = new(OUSED, $3, Z);
518 		$$->lineno = line($3);
519 	}
520 |	LSET '(' zelist ')' ';'
521 	{
522 		$$ = new(OSET, $3, Z);
523 		$$->lineno = line($3);
524 	}
525 
526 zcexpr:
527 	{
528 		$$ = Z;
529 	}
530 |	cexpr
531 
532 zexpr:
533 	{
534 		$$ = Z;
535 	}
536 |	lexpr
537 
538 lexpr:
539 	expr
540 	{
541 		$$ = new(OCAST, $1, Z);
542 		$$->type = types[TLONG];
543 	}
544 
545 cexpr:
546 	expr
547 |	cexpr ',' cexpr
548 	{
549 		$$ = new(OCOMMA, $1, $3);
550 	}
551 
552 expr:
553 	xuexpr
554 |	expr '*' expr
555 	{
556 		$$ = new(OMUL, $1, $3);
557 	}
558 |	expr '/' expr
559 	{
560 		$$ = new(ODIV, $1, $3);
561 	}
562 |	expr '%' expr
563 	{
564 		$$ = new(OMOD, $1, $3);
565 	}
566 |	expr '+' expr
567 	{
568 		$$ = new(OADD, $1, $3);
569 	}
570 |	expr '-' expr
571 	{
572 		$$ = new(OSUB, $1, $3);
573 	}
574 |	expr LRSH expr
575 	{
576 		$$ = new(OASHR, $1, $3);
577 	}
578 |	expr LLSH expr
579 	{
580 		$$ = new(OASHL, $1, $3);
581 	}
582 |	expr '<' expr
583 	{
584 		$$ = new(OLT, $1, $3);
585 	}
586 |	expr '>' expr
587 	{
588 		$$ = new(OGT, $1, $3);
589 	}
590 |	expr LLE expr
591 	{
592 		$$ = new(OLE, $1, $3);
593 	}
594 |	expr LGE expr
595 	{
596 		$$ = new(OGE, $1, $3);
597 	}
598 |	expr LEQ expr
599 	{
600 		$$ = new(OEQ, $1, $3);
601 	}
602 |	expr LNE expr
603 	{
604 		$$ = new(ONE, $1, $3);
605 	}
606 |	expr '&' expr
607 	{
608 		$$ = new(OAND, $1, $3);
609 	}
610 |	expr '^' expr
611 	{
612 		$$ = new(OXOR, $1, $3);
613 	}
614 |	expr '|' expr
615 	{
616 		$$ = new(OOR, $1, $3);
617 	}
618 |	expr LANDAND expr
619 	{
620 		$$ = new(OANDAND, $1, $3);
621 	}
622 |	expr LOROR expr
623 	{
624 		$$ = new(OOROR, $1, $3);
625 	}
626 |	expr '?' cexpr ':' expr
627 	{
628 		$$ = new(OCOND, $1, new(OLIST, $3, $5));
629 	}
630 |	expr '=' expr
631 	{
632 		$$ = new(OAS, $1, $3);
633 	}
634 |	expr LPE expr
635 	{
636 		$$ = new(OASADD, $1, $3);
637 	}
638 |	expr LME expr
639 	{
640 		$$ = new(OASSUB, $1, $3);
641 	}
642 |	expr LMLE expr
643 	{
644 		$$ = new(OASMUL, $1, $3);
645 	}
646 |	expr LDVE expr
647 	{
648 		$$ = new(OASDIV, $1, $3);
649 	}
650 |	expr LMDE expr
651 	{
652 		$$ = new(OASMOD, $1, $3);
653 	}
654 |	expr LLSHE expr
655 	{
656 		$$ = new(OASASHL, $1, $3);
657 	}
658 |	expr LRSHE expr
659 	{
660 		$$ = new(OASASHR, $1, $3);
661 	}
662 |	expr LANDE expr
663 	{
664 		$$ = new(OASAND, $1, $3);
665 	}
666 |	expr LXORE expr
667 	{
668 		$$ = new(OASXOR, $1, $3);
669 	}
670 |	expr LORE expr
671 	{
672 		$$ = new(OASOR, $1, $3);
673 	}
674 
675 xuexpr:
676 	uexpr
677 |	'(' tlist abdecor ')' xuexpr
678 	{
679 		$$ = new(OCAST, $5, Z);
680 		dodecl(NODECL, CXXX, $2, $3, 1);
681 		$$->type = lastdcl;
682 	}
683 |	'(' tlist abdecor ')' '{' ilist '}'	/* extension */
684 	{
685 		$$ = new(OSTRUCT, $6, Z);
686 		dodecl(NODECL, CXXX, $2, $3, 1);
687 		$$->type = lastdcl;
688 	}
689 
690 uexpr:
691 	pexpr
692 |	'*' xuexpr
693 	{
694 		$$ = new(OIND, $2, Z);
695 	}
696 |	'&' xuexpr
697 	{
698 		$$ = new(OADDR, $2, Z);
699 	}
700 |	'+' xuexpr
701 	{
702 		$$ = new(OPOS, $2, Z);
703 	}
704 |	'-' xuexpr
705 	{
706 		$$ = new(ONEG, $2, Z);
707 	}
708 |	'!' xuexpr
709 	{
710 		$$ = new(ONOT, $2, Z);
711 	}
712 |	'~' xuexpr
713 	{
714 		$$ = new(OCOM, $2, Z);
715 	}
716 |	LPP xuexpr
717 	{
718 		$$ = new(OPREINC, $2, Z);
719 	}
720 |	LMM xuexpr
721 	{
722 		$$ = new(OPREDEC, $2, Z);
723 	}
724 |	LSIZEOF uexpr
725 	{
726 		$$ = new(OSIZE, $2, Z);
727 	}
728 |	LSIGNOF uexpr
729 	{
730 		$$ = new(OSIGN, $2, Z);
731 	}
732 
733 pexpr:
734 	'(' cexpr ')'
735 	{
736 		$$ = $2;
737 	}
738 |	LSIZEOF '(' tlist abdecor ')'
739 	{
740 		$$ = new(OSIZE, Z, Z);
741 		dodecl(NODECL, CXXX, $3, $4, 1);
742 		$$->type = lastdcl;
743 	}
744 |	LSIGNOF '(' tlist abdecor ')'
745 	{
746 		$$ = new(OSIGN, Z, Z);
747 		dodecl(NODECL, CXXX, $3, $4, 1);
748 		$$->type = lastdcl;
749 	}
750 |	pexpr '(' zelist ')'
751 	{
752 		$$ = new(OFUNC, $1, Z);
753 		if($1->op == ONAME)
754 		if($1->type == T)
755 			dodecl(xdecl, CXXX, types[TINT], $$, 1);
756 		$$->right = invert($3);
757 		$$->kind = KEXP;
758 	}
759 |	pexpr '[' cexpr ']'
760 	{
761 		$$ = new(OARRIND, $1, $3);
762 	}
763 |	pexpr LMG ltag
764 	{
765 		$$ = new(ODOTIND, $1, Z);
766 		$$->sym = $3;
767 	}
768 |	pexpr '.' ltag
769 	{
770 		$$ = new(ODOT, $1, Z);
771 		$$->sym = $3;
772 	}
773 |	pexpr LPP
774 	{
775 		$$ = new(OPOSTINC, $1, Z);
776 	}
777 |	pexpr LMM
778 	{
779 		$$ = new(OPOSTDEC, $1, Z);
780 	}
781 |	name
782 |	LCHARACTER
783 	{
784 		$$ = new(OCONST, Z, Z);
785 		$$->type = types[TINT];
786 		$$->vconst = $1;
787 		$$->kind = KCHR;
788 	}
789 |	LCONST
790 	{
791 		$$ = new(OCONST, Z, Z);
792 		$$->type = types[TINT];
793 		$$->vconst = $1;
794 		$$->kind = lastnumbase;
795 	}
796 |	LLCONST
797 	{
798 		$$ = new(OCONST, Z, Z);
799 		$$->type = types[TLONG];
800 		$$->vconst = $1;
801 		$$->kind = lastnumbase;
802 	}
803 |	LUCONST
804 	{
805 		$$ = new(OCONST, Z, Z);
806 		$$->type = types[TUINT];
807 		$$->vconst = $1;
808 		$$->kind = lastnumbase;
809 	}
810 |	LULCONST
811 	{
812 		$$ = new(OCONST, Z, Z);
813 		$$->type = types[TULONG];
814 		$$->vconst = $1;
815 		$$->kind = lastnumbase;
816 	}
817 |	LDCONST
818 	{
819 		$$ = new(OCONST, Z, Z);
820 		$$->type = types[TDOUBLE];
821 		$$->fconst = $1;
822 		$$->cstring = strdup(symb);
823 		$$->kind = lastnumbase;
824 	}
825 |	LFCONST
826 	{
827 		$$ = new(OCONST, Z, Z);
828 		$$->type = types[TFLOAT];
829 		$$->fconst = $1;
830 		$$->cstring = strdup(symb);
831 		$$->kind = lastnumbase;
832 	}
833 |	LVLCONST
834 	{
835 		$$ = new(OCONST, Z, Z);
836 		$$->type = types[TVLONG];
837 		$$->vconst = $1;
838 		$$->kind = lastnumbase;
839 	}
840 |	LUVLCONST
841 	{
842 		$$ = new(OCONST, Z, Z);
843 		$$->type = types[TUVLONG];
844 		$$->vconst = $1;
845 		$$->kind = lastnumbase;
846 	}
847 |	string
848 |	lstring
849 
850 sstring:
851 	LSTRING
852 	{
853 		$$ = new(OSTRING, Z, Z);
854 		$$->type = typ(TARRAY, types[TCHAR]);
855 		$$->type->width = $1.l + 1;
856 		$$->cstring = $1.s;
857 		$$->sym = symstring;
858 	}
859 
860 string:
861 	sstring
862 	{
863 		$$ = $1;
864 	}
865 |	string sstring
866 	{
867 		char *s;
868 		int n1, n2;
869 
870 		n1 = $1->type->width - 1;
871 		n2 = $2->type->width - 1;
872 		s = alloc(n1+n2+MAXALIGN);
873 
874 		memcpy(s, $1->cstring, n1);
875 		memcpy(s+n1, $2->cstring, n2);
876 		s[n1+n2] = 0;
877 
878 		$1->left = new(OCAT, ncopy($1), $2);
879 
880 		$$ = $1;
881 		$$->type->width += n2;
882 		$$->cstring = s;
883 	}
884 
885 slstring:
886 	LLSTRING
887 	{
888 		$$ = new(OLSTRING, Z, Z);
889 		$$->type = typ(TARRAY, types[TUSHORT]);
890 		$$->type->width = $1.l + sizeof(TRune);
891 		$$->rstring = (TRune*)$1.s;
892 		$$->sym = symstring;
893 	}
894 
895 lstring:
896 	slstring
897 	{
898 		$$ = $1;
899 	}
900 |	lstring slstring
901 	{
902 		char *s;
903 		int n1, n2;
904 
905 		n1 = $1->type->width - sizeof(TRune);
906 		n2 = $2->type->width - sizeof(TRune);
907 		s = alloc(n1+n2+MAXALIGN);
908 
909 		memcpy(s, $1->rstring, n1);
910 		memcpy(s+n1, $2->rstring, n2);
911 		*(TRune*)(s+n1+n2) = 0;
912 
913 		$1->left = new(OCAT, ncopy($1), $2);
914 
915 		$$ = $1;
916 		$$->type->width += n2;
917 		$$->rstring = (TRune*)s;
918 	}
919 
920 zelist:
921 	{
922 		$$ = Z;
923 	}
924 |	elist
925 
926 elist:
927 	expr
928 |	elist ',' elist
929 	{
930 		$$ = new(OLIST, $1, $3);
931 	}
932 
933 sbody:
934 	'{'
935 	{
936 		$<tyty>$.t1 = strf;
937 		$<tyty>$.t2 = strl;
938 		strf = T;
939 		strl = T;
940 		lastbit = 0;
941 		firstbit = 1;
942 	}
943 	edecl '}'
944 	{
945 		$$ = strf;
946 		strf = $<tyty>2.t1;
947 		strl = $<tyty>2.t2;
948 	}
949 
950 zctlist:
951 	{
952 		lastclass = CXXX;
953 		lasttype = types[TINT];
954 	}
955 |	ctlist
956 
957 etypes:
958 	complex
959 	{
960 		$$.t = $1;
961 		$$.c = CXXX;
962 	}
963 |	tnlist
964 	{
965 		$$.t = simplet($1);
966 		$$.c = simplec($1);
967 	}
968 
969 types:
970 	complex
971 	{
972 		$$.t = $1;
973 		$$.c = CXXX;
974 	}
975 |	complex gctnlist
976 	{
977 		$$.t = $1;
978 		$$.c = simplec($2);
979 		if($2 & ~BCLASS & ~BGARB)
980 			diag(Z, "illegal combination of types 1: %Q/%T", $2, $1);
981 	}
982 |	gctnlist
983 	{
984 		$$.t = simplet($1);
985 		$$.c = simplec($1);
986 		$$.t = garbt($$.t, $1);
987 	}
988 |	gctnlist complex
989 	{
990 		$$.t = $2;
991 		$$.c = simplec($1);
992 		$$.t = garbt($$.t, $1);
993 		if($1 & ~BCLASS & ~BGARB)
994 			diag(Z, "illegal combination of types 2: %Q/%T", $1, $2);
995 	}
996 |	gctnlist complex gctnlist
997 	{
998 		$$.t = $2;
999 		$$.c = simplec($1|$3);
1000 		$$.t = garbt($$.t, $1|$3);
1001 		if(($1|$3) & ~BCLASS & ~BGARB || $3 & BCLASS)
1002 			diag(Z, "illegal combination of types 3: %Q/%T/%Q", $1, $2, $3);
1003 	}
1004 
1005 etlist:
1006 	zgnlist etypes
1007 	{
1008 		$$ = $2.t;
1009 		if($2.c != CXXX)
1010 			diag(Z, "illegal combination of class 4: %s", cnames[$2.c]);
1011 		$$ = garbt($$, $1);
1012 	}
1013 
1014 tlist:
1015 	types
1016 	{
1017 		$$ = $1.t;
1018 		if($1.c != CXXX)
1019 			diag(Z, "illegal combination of class 4: %s", cnames[$1.c]);
1020 	}
1021 
1022 ctlist:
1023 	types
1024 	{
1025 		lasttype = $1.t;
1026 		lastclass = $1.c;
1027 	}
1028 
1029 complex:
1030 	LSTRUCT ltag
1031 	{
1032 		dotag($2, TSTRUCT, 0);
1033 		$$ = $2->suetag;
1034 		$2->lineno = lineno;
1035 	}
1036 |	LSTRUCT ltag
1037 	{
1038 		dotag($2, TSTRUCT, autobn);
1039 		saveline = $2->lineno = lineno;
1040 	}
1041 	sbody
1042 	{
1043 		$$ = $2->suetag;
1044 		if($$->link != T)
1045 			diag(Z, "redeclare tag: %s", $2->name);
1046 		$$->link = $4;
1047 		$$->lineno = saveline;
1048 		suallign($$);
1049 	}
1050 |	LSTRUCT
1051 	{
1052 		saveline = lineno;
1053 	}
1054 	sbody
1055 	{
1056 		char buf[128];
1057 
1058 		taggen++;
1059 		sprint(symb, "%s_adt_%d", outmod(buf, -1), taggen);
1060 		$$ = dotag(lookup(), TSTRUCT, autobn);
1061 		$$->link = $3;
1062 		$$->lineno = saveline;
1063 		lookup()->lineno = saveline;
1064 		suallign($$);
1065 	}
1066 |	LUNION ltag
1067 	{
1068 		dotag($2, TUNION, 0);
1069 		$$ = $2->suetag;
1070 		$2->lineno = lineno;
1071 	}
1072 |	LUNION ltag
1073 	{
1074 		dotag($2, TUNION, autobn);
1075 		saveline = $2->lineno = lineno;
1076 	}
1077 	sbody
1078 	{
1079 		$$ = $2->suetag;
1080 		if($$->link != T)
1081 			diag(Z, "redeclare tag: %s", $2->name);
1082 		$$->link = $4;
1083 		$$->lineno = saveline;
1084 		suallign($$);
1085 	}
1086 |	LUNION
1087 	{
1088 		saveline = lineno;
1089 	}
1090 	sbody
1091 	{
1092 		char buf[128];
1093 
1094 		taggen++;
1095 		sprint(symb, "%s_adt_%d", outmod(buf, -1), taggen);
1096 		$$ = dotag(lookup(), TUNION, autobn);
1097 		$$->link = $3;
1098 		$$->lineno = saveline;
1099 		lookup()->lineno = saveline;
1100 		suallign($$);
1101 	}
1102 |	LENUM ltag
1103 	{
1104 		dotag($2, TENUM, 0);
1105 		$$ = $2->suetag;
1106 		if($$->link == T)
1107 			$$->link = types[TINT];
1108 		$$ = $$->link;
1109 		$2->lineno = lineno;
1110 	}
1111 |	LENUM ltag
1112 	{
1113 		dotag($2, TENUM, autobn);
1114 		$2->lineno = lineno;
1115 	}
1116 	'{'
1117 	{
1118 		en.tenum = T;
1119 		en.cenum = T;
1120 	}
1121 	enum '}'
1122 	{
1123 		$$ = $2->suetag;
1124 		if($$->link != T)
1125 			diag(Z, "redeclare tag: %s", $2->name);
1126 		if(en.tenum == T) {
1127 			diag(Z, "enum type ambiguous: %s", $2->name);
1128 			en.tenum = types[TINT];
1129 		}
1130 		$$->link = en.tenum;
1131 		$$ = en.tenum;
1132 		etgen(nil);
1133 	}
1134 |	LENUM '{'
1135 	{
1136 		en.tenum = T;
1137 		en.cenum = T;
1138 	}
1139 	enum '}'
1140 	{
1141 		$$ = en.tenum;
1142 		etgen(nil);
1143 	}
1144 |	LCTYPE
1145 	{
1146 		$$ = tcopy($1->type);
1147 	}
1148 |	LSTYPE
1149 	{
1150 		$$ = tcopy($1->type);
1151 	}
1152 
1153 tnlist:
1154 	tname
1155 |	tnlist tname
1156 	{
1157 		$$ = typebitor($1, $2);
1158 	}
1159 
1160 gctnlist:
1161 	gctname
1162 |	gctnlist gctname
1163 	{
1164 		$$ = typebitor($1, $2);
1165 	}
1166 
1167 zgnlist:
1168 	{
1169 		$$ = 0;
1170 	}
1171 |	zgnlist gname
1172 	{
1173 		$$ = typebitor($1, $2);
1174 	}
1175 
1176 gctname:
1177 	tname
1178 |	gname
1179 |	cname
1180 
1181 enum:
1182 	LNAME
1183 	{
1184 		doenum($1, Z);
1185 		$1->lineno = lineno;
1186 	}
1187 |	LNAME '=' expr
1188 	{
1189 		doenum($1, $3);
1190 		$1->lineno = lineno;
1191 	}
1192 |	enum ','
1193 |	enum ',' enum
1194 
1195 tname:	/* type words */
1196 	LCHAR { $$ = BCHAR; }
1197 |	LSHORT { $$ = BSHORT; }
1198 |	LINT { $$ = BINT; }
1199 |	LLONG { $$ = BLONG; }
1200 |	LSIGNED { $$ = BSIGNED; }
1201 |	LUNSIGNED { $$ = BUNSIGNED; }
1202 |	LFLOAT { $$ = BFLOAT; }
1203 |	LDOUBLE { $$ = BDOUBLE; }
1204 |	LVOID { $$ = BVOID; }
1205 |	LVLONG { $$ = BVLONG|BLONG; }
1206 
1207 cname:	/* class words */
1208 	LAUTO { $$ = BAUTO; }
1209 |	LSTATIC { $$ = BSTATIC; }
1210 |	LEXTERN { $$ = BEXTERN; }
1211 |	LTYPEDEF { $$ = BTYPEDEF; }
1212 |	LREGISTER { $$ = BREGISTER; }
1213 
1214 gname:
1215 	LCONSTNT { $$ = BCONSTNT; }
1216 |	LVOLATILE { $$ = BVOLATILE; }
1217 
1218 name:
1219 	LNAME
1220 	{
1221 		$$ = new(ONAME, Z, Z);
1222 		if($1->class == CLOCAL)
1223 			$1 = mkstatic($1);
1224 		$$->sym = $1;
1225 		$$->type = $1->type;
1226 	}
1227 tag:
1228 	ltag
1229 	{
1230 		$$ = new(ONAME, Z, Z);
1231 		$$->sym = $1;
1232 		$$->type = $1->type;
1233 	}
1234 ltag:
1235 	LNAME
1236 |	LCTYPE
1237 |	LSTYPE
1238 
1239 %%
1240