github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/cmd/cc/cc.y (about)

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