Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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