github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/src/cmd/compile/internal/gc/go.y (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6   * Go language grammar.
     7   *
     8   * The Go semicolon rules are:
     9   *
    10   *  1. all statements and declarations are terminated by semicolons.
    11   *  2. semicolons can be omitted before a closing ) or }.
    12   *  3. semicolons are inserted by the lexer before a newline
    13   *      following a specific list of tokens.
    14   *
    15   * Rules #1 and #2 are accomplished by writing the lists as
    16   * semicolon-separated lists with an optional trailing semicolon.
    17   * Rule #3 is implemented in yylex.
    18   */
    19  
    20  %{
    21  package gc
    22  
    23  import (
    24  	"fmt"
    25  	"strings"
    26  )
    27  %}
    28  %union	{
    29  	node *Node
    30  	list *NodeList
    31  	typ *Type
    32  	sym *Sym
    33  	val Val
    34  	i int
    35  }
    36  
    37  // |sed 's/.*	//' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx		/'
    38  
    39  %token	<val>	LLITERAL
    40  %token	<i>	LASOP LCOLAS
    41  %token	<sym>	LBREAK LCASE LCHAN LCONST LCONTINUE LDDD
    42  %token	<sym>	LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO
    43  %token	<sym>	LIF LIMPORT LINTERFACE LMAP LNAME
    44  %token	<sym>	LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH
    45  %token	<sym>	LTYPE LVAR
    46  
    47  %token		LANDAND LANDNOT LBODY LCOMM LDEC LEQ LGE LGT
    48  %token		LIGNORE LINC LLE LLSH LLT LNE LOROR LRSH
    49  
    50  %type	<i>	lbrace import_here
    51  %type	<sym>	sym packname
    52  %type	<val>	oliteral
    53  
    54  %type	<node>	stmt ntype
    55  %type	<node>	arg_type
    56  %type	<node>	case caseblock
    57  %type	<node>	compound_stmt dotname embed expr complitexpr bare_complitexpr
    58  %type	<node>	expr_or_type
    59  %type	<node>	fndcl hidden_fndcl fnliteral
    60  %type	<node>	for_body for_header for_stmt if_header if_stmt non_dcl_stmt
    61  %type	<node>	interfacedcl keyval labelname name
    62  %type	<node>	name_or_type non_expr_type
    63  %type	<node>	new_name dcl_name oexpr typedclname
    64  %type	<node>	onew_name
    65  %type	<node>	osimple_stmt pexpr pexpr_no_paren
    66  %type	<node>	pseudocall range_stmt select_stmt
    67  %type	<node>	simple_stmt
    68  %type	<node>	switch_stmt uexpr
    69  %type	<node>	xfndcl typedcl start_complit
    70  
    71  %type	<list>	xdcl fnbody fnres loop_body dcl_name_list
    72  %type	<list>	new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
    73  %type	<list>	oexpr_list caseblock_list elseif elseif_list else stmt_list oarg_type_list_ocomma arg_type_list
    74  %type	<list>	interfacedcl_list vardcl vardcl_list structdcl structdcl_list
    75  %type	<list>	common_dcl constdcl constdcl1 constdcl_list typedcl_list
    76  
    77  %type	<node>	convtype comptype dotdotdot
    78  %type	<node>	indcl interfacetype structtype ptrtype
    79  %type	<node>	recvchantype non_recvchantype othertype fnret_type fntype
    80  
    81  %type	<sym>	hidden_importsym hidden_pkg_importsym
    82  
    83  %type	<node>	hidden_constant hidden_literal hidden_funarg
    84  %type	<node>	hidden_interfacedcl hidden_structdcl
    85  
    86  %type	<list>	hidden_funres
    87  %type	<list>	ohidden_funres
    88  %type	<list>	hidden_funarg_list ohidden_funarg_list
    89  %type	<list>	hidden_interfacedcl_list ohidden_interfacedcl_list
    90  %type	<list>	hidden_structdcl_list ohidden_structdcl_list
    91  
    92  %type	<typ>	hidden_type hidden_type_misc hidden_pkgtype
    93  %type	<typ>	hidden_type_func
    94  %type	<typ>	hidden_type_recv_chan hidden_type_non_recv_chan
    95  
    96  %left		LCOMM	/* outside the usual hierarchy; here for good error messages */
    97  
    98  %left		LOROR
    99  %left		LANDAND
   100  %left		LEQ LNE LLE LGE LLT LGT
   101  %left		'+' '-' '|' '^'
   102  %left		'*' '/' '%' '&' LLSH LRSH LANDNOT
   103  
   104  /*
   105   * manual override of shift/reduce conflicts.
   106   * the general form is that we assign a precedence
   107   * to the token being shifted and then introduce
   108   * NotToken with lower precedence or PreferToToken with higher
   109   * and annotate the reducing rule accordingly.
   110   */
   111  %left		NotPackage
   112  %left		LPACKAGE
   113  
   114  %left		NotParen
   115  %left		'('
   116  
   117  %left		')'
   118  %left		PreferToRightParen
   119  
   120  %error loadsys package LIMPORT '(' LLITERAL import_package import_there ',':
   121  	"unexpected comma during import block"
   122  
   123  %error loadsys package LIMPORT LNAME ';':
   124  	"missing import path; require quoted string"
   125  
   126  %error loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header ';':
   127  	"missing { after if clause"
   128  
   129  %error loadsys package imports LFUNC LNAME '(' ')' '{' LSWITCH if_header ';':
   130  	"missing { after switch clause"
   131  
   132  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFOR for_header ';':
   133  	"missing { after for clause"
   134  
   135  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFOR ';' LBODY:
   136  	"missing { after for clause"
   137  
   138  %error loadsys package imports LFUNC LNAME '(' ')' ';' '{':
   139  	"unexpected semicolon or newline before {"
   140  
   141  %error loadsys package imports LTYPE LNAME ';':
   142  	"unexpected semicolon or newline in type declaration"
   143  
   144  %error loadsys package imports LCHAN '}':
   145  	"unexpected } in channel type"
   146  
   147  %error loadsys package imports LCHAN ')':
   148  	"unexpected ) in channel type"
   149  
   150  %error loadsys package imports LCHAN ',':
   151  	"unexpected comma in channel type"
   152  
   153  %error loadsys package imports LFUNC LNAME '(' ')' '{' if_stmt ';' LELSE:
   154  	"unexpected semicolon or newline before else"
   155  
   156  %error loadsys package imports LTYPE LNAME LINTERFACE '{' LNAME ',' LNAME:
   157  	"name list not allowed in interface type"
   158  
   159  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFOR LVAR LNAME '=' LNAME:
   160  	"var declaration not allowed in for initializer"
   161  
   162  %error loadsys package imports LVAR LNAME '[' ']' LNAME '{':
   163  	"unexpected { at end of statement"
   164  
   165  %error loadsys package imports LFUNC LNAME '(' ')' '{' LVAR LNAME '[' ']' LNAME '{':
   166  	"unexpected { at end of statement"
   167  
   168  %error loadsys package imports LFUNC LNAME '(' ')' '{' LDEFER LNAME ';':
   169  	"argument to go/defer must be function call"
   170  
   171  %error loadsys package imports LVAR LNAME '=' LNAME '{' LNAME ';':
   172  	"need trailing comma before newline in composite literal"
   173  
   174  %error loadsys package imports LVAR LNAME '=' comptype '{' LNAME ';':
   175  	"need trailing comma before newline in composite literal"
   176  
   177  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFUNC LNAME:
   178  	"nested func not allowed"
   179  
   180  %error loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header loop_body LELSE ';':
   181  	"else must be followed by if or statement block"
   182  
   183  %%
   184  file:
   185  	loadsys
   186  	package
   187  	imports
   188  	xdcl_list
   189  	{
   190  		xtop = concat(xtop, $4);
   191  	}
   192  
   193  package:
   194  	%prec NotPackage
   195  	{
   196  		prevlineno = lineno;
   197  		Yyerror("package statement must be first");
   198  		errorexit();
   199  	}
   200  |	LPACKAGE sym ';'
   201  	{
   202  		mkpackage($2.Name);
   203  	}
   204  
   205  /*
   206   * this loads the definitions for the low-level runtime functions,
   207   * so that the compiler can generate calls to them,
   208   * but does not make the name "runtime" visible as a package.
   209   */
   210  loadsys:
   211  	{
   212  		importpkg = Runtimepkg;
   213  
   214  		if Debug['A'] != 0 {
   215  			cannedimports("runtime.Builtin", "package runtime\n\n$$\n\n");
   216  		} else {
   217  			cannedimports("runtime.Builtin", runtimeimport);
   218  		}
   219  		curio.importsafe = true
   220  	}
   221  	import_package
   222  	import_there
   223  	{
   224  		importpkg = nil;
   225  	}
   226  
   227  imports:
   228  |	imports import ';'
   229  
   230  import:
   231  	LIMPORT import_stmt
   232  |	LIMPORT '(' import_stmt_list osemi ')'
   233  |	LIMPORT '(' ')'
   234  
   235  import_stmt:
   236  	import_here import_package import_there
   237  	{
   238  		ipkg := importpkg;
   239  		my := importmyname;
   240  		importpkg = nil;
   241  		importmyname = nil;
   242  
   243  		if my == nil {
   244  			my = Lookup(ipkg.Name);
   245  		}
   246  
   247  		pack := Nod(OPACK, nil, nil);
   248  		pack.Sym = my;
   249  		pack.Name.Pkg = ipkg;
   250  		pack.Lineno = int32($1);
   251  
   252  		if strings.HasPrefix(my.Name, ".") {
   253  			importdot(ipkg, pack);
   254  			break;
   255  		}
   256  		if my.Name == "init" {
   257  			Yyerror("cannot import package as init - init must be a func");
   258  			break;
   259  		}
   260  		if my.Name == "_" {
   261  			break;
   262  		}
   263  		if my.Def != nil {
   264  			lineno = int32($1);
   265  			redeclare(my, "as imported package name");
   266  		}
   267  		my.Def = pack;
   268  		my.Lastlineno = int32($1);
   269  		my.Block = 1;	// at top level
   270  	}
   271  |	import_here import_there
   272  	{
   273  		// When an invalid import path is passed to importfile,
   274  		// it calls Yyerror and then sets up a fake import with
   275  		// no package statement. This allows us to test more
   276  		// than one invalid import statement in a single file.
   277  		if nerrors == 0 {
   278  			Fatal("phase error in import");
   279  		}
   280  	}
   281  
   282  import_stmt_list:
   283  	import_stmt
   284  |	import_stmt_list ';' import_stmt
   285  
   286  import_here:
   287  	LLITERAL
   288  	{
   289  		// import with original name
   290  		$$ = parserline();
   291  		importmyname = nil;
   292  		importfile(&$1, $$);
   293  	}
   294  |	sym LLITERAL
   295  	{
   296  		// import with given name
   297  		$$ = parserline();
   298  		importmyname = $1;
   299  		importfile(&$2, $$);
   300  	}
   301  |	'.' LLITERAL
   302  	{
   303  		// import into my name space
   304  		$$ = parserline();
   305  		importmyname = Lookup(".");
   306  		importfile(&$2, $$);
   307  	}
   308  
   309  import_package:
   310  	LPACKAGE LNAME import_safety ';'
   311  	{
   312  		if importpkg.Name == "" {
   313  			importpkg.Name = $2.Name;
   314  			numImport[$2.Name]++
   315  		} else if importpkg.Name != $2.Name {
   316  			Yyerror("conflicting names %s and %s for package %q", importpkg.Name, $2.Name, importpkg.Path);
   317  		}
   318  		importpkg.Direct = 1;
   319  		importpkg.Safe = curio.importsafe
   320  
   321  		if safemode != 0 && !curio.importsafe {
   322  			Yyerror("cannot import unsafe package %q", importpkg.Path);
   323  		}
   324  	}
   325  
   326  import_safety:
   327  |	LNAME
   328  	{
   329  		if $1.Name == "safe" {
   330  			curio.importsafe = true
   331  		}
   332  	}
   333  
   334  import_there:
   335  	{
   336  		defercheckwidth();
   337  	}
   338  	hidden_import_list '$' '$'
   339  	{
   340  		resumecheckwidth();
   341  		unimportfile();
   342  	}
   343  
   344  /*
   345   * declarations
   346   */
   347  xdcl:
   348  	{
   349  		Yyerror("empty top-level declaration");
   350  		$$ = nil;
   351  	}
   352  |	common_dcl
   353  |	xfndcl
   354  	{
   355  		$$ = list1($1);
   356  	}
   357  |	non_dcl_stmt
   358  	{
   359  		Yyerror("non-declaration statement outside function body");
   360  		$$ = nil;
   361  	}
   362  |	error
   363  	{
   364  		$$ = nil;
   365  	}
   366  
   367  common_dcl:
   368  	LVAR vardcl
   369  	{
   370  		$$ = $2;
   371  	}
   372  |	LVAR '(' vardcl_list osemi ')'
   373  	{
   374  		$$ = $3;
   375  	}
   376  |	LVAR '(' ')'
   377  	{
   378  		$$ = nil;
   379  	}
   380  |	lconst constdcl
   381  	{
   382  		$$ = $2;
   383  		iota_ = -100000;
   384  		lastconst = nil;
   385  	}
   386  |	lconst '(' constdcl osemi ')'
   387  	{
   388  		$$ = $3;
   389  		iota_ = -100000;
   390  		lastconst = nil;
   391  	}
   392  |	lconst '(' constdcl ';' constdcl_list osemi ')'
   393  	{
   394  		$$ = concat($3, $5);
   395  		iota_ = -100000;
   396  		lastconst = nil;
   397  	}
   398  |	lconst '(' ')'
   399  	{
   400  		$$ = nil;
   401  		iota_ = -100000;
   402  	}
   403  |	LTYPE typedcl
   404  	{
   405  		$$ = list1($2);
   406  	}
   407  |	LTYPE '(' typedcl_list osemi ')'
   408  	{
   409  		$$ = $3;
   410  	}
   411  |	LTYPE '(' ')'
   412  	{
   413  		$$ = nil;
   414  	}
   415  
   416  lconst:
   417  	LCONST
   418  	{
   419  		iota_ = 0;
   420  	}
   421  
   422  vardcl:
   423  	dcl_name_list ntype
   424  	{
   425  		$$ = variter($1, $2, nil);
   426  	}
   427  |	dcl_name_list ntype '=' expr_list
   428  	{
   429  		$$ = variter($1, $2, $4);
   430  	}
   431  |	dcl_name_list '=' expr_list
   432  	{
   433  		$$ = variter($1, nil, $3);
   434  	}
   435  
   436  constdcl:
   437  	dcl_name_list ntype '=' expr_list
   438  	{
   439  		$$ = constiter($1, $2, $4);
   440  	}
   441  |	dcl_name_list '=' expr_list
   442  	{
   443  		$$ = constiter($1, nil, $3);
   444  	}
   445  
   446  constdcl1:
   447  	constdcl
   448  |	dcl_name_list ntype
   449  	{
   450  		$$ = constiter($1, $2, nil);
   451  	}
   452  |	dcl_name_list
   453  	{
   454  		$$ = constiter($1, nil, nil);
   455  	}
   456  
   457  typedclname:
   458  	sym
   459  	{
   460  		// different from dclname because the name
   461  		// becomes visible right here, not at the end
   462  		// of the declaration.
   463  		$$ = typedcl0($1);
   464  	}
   465  
   466  typedcl:
   467  	typedclname ntype
   468  	{
   469  		$$ = typedcl1($1, $2, true);
   470  	}
   471  
   472  simple_stmt:
   473  	expr
   474  	{
   475  		$$ = $1;
   476  
   477  		// These nodes do not carry line numbers.
   478  		// Since a bare name used as an expression is an error,
   479  		// introduce a wrapper node to give the correct line.
   480  		switch($$.Op) {
   481  		case ONAME, ONONAME, OTYPE, OPACK, OLITERAL:
   482  			$$ = Nod(OPAREN, $$, nil);
   483  			$$.Implicit = true;
   484  			break;
   485  		}
   486  	}
   487  |	expr LASOP expr
   488  	{
   489  		$$ = Nod(OASOP, $1, $3);
   490  		$$.Etype = uint8($2);			// rathole to pass opcode
   491  	}
   492  |	expr_list '=' expr_list
   493  	{
   494  		if $1.Next == nil && $3.Next == nil {
   495  			// simple
   496  			$$ = Nod(OAS, $1.N, $3.N);
   497  			break;
   498  		}
   499  		// multiple
   500  		$$ = Nod(OAS2, nil, nil);
   501  		$$.List = $1;
   502  		$$.Rlist = $3;
   503  	}
   504  |	expr_list LCOLAS expr_list
   505  	{
   506  		if $3.N.Op == OTYPESW {
   507  			$$ = Nod(OTYPESW, nil, $3.N.Right);
   508  			if $3.Next != nil {
   509  				Yyerror("expr.(type) must be alone in list");
   510  			}
   511  			if $1.Next != nil {
   512  				Yyerror("argument count mismatch: %d = %d", count($1), 1);
   513  			} else if ($1.N.Op != ONAME && $1.N.Op != OTYPE && $1.N.Op != ONONAME) || isblank($1.N) {
   514  				Yyerror("invalid variable name %s in type switch", $1.N);
   515  			} else {
   516  				$$.Left = dclname($1.N.Sym);
   517  			}  // it's a colas, so must not re-use an oldname.
   518  			break;
   519  		}
   520  		$$ = colas($1, $3, int32($2));
   521  	}
   522  |	expr LINC
   523  	{
   524  		$$ = Nod(OASOP, $1, Nodintconst(1));
   525  		$$.Implicit = true;
   526  		$$.Etype = OADD;
   527  	}
   528  |	expr LDEC
   529  	{
   530  		$$ = Nod(OASOP, $1, Nodintconst(1));
   531  		$$.Implicit = true;
   532  		$$.Etype = OSUB;
   533  	}
   534  
   535  case:
   536  	LCASE expr_or_type_list ':'
   537  	{
   538  		var n, nn *Node
   539  
   540  		// will be converted to OCASE
   541  		// right will point to next case
   542  		// done in casebody()
   543  		markdcl();
   544  		$$ = Nod(OXCASE, nil, nil);
   545  		$$.List = $2;
   546  		if typesw != nil && typesw.Right != nil {
   547  			n = typesw.Right.Left
   548  			if n != nil {
   549  				// type switch - declare variable
   550  				nn = newname(n.Sym);
   551  				declare(nn, dclcontext);
   552  				$$.Rlist = list1(nn);
   553  	
   554  				// keep track of the instances for reporting unused
   555  				nn.Name.Defn = typesw.Right;
   556  			}
   557  		}
   558  	}
   559  |	LCASE expr_or_type_list '=' expr ':'
   560  	{
   561  		var n *Node
   562  
   563  		// will be converted to OCASE
   564  		// right will point to next case
   565  		// done in casebody()
   566  		markdcl();
   567  		$$ = Nod(OXCASE, nil, nil);
   568  		if $2.Next == nil {
   569  			n = Nod(OAS, $2.N, $4);
   570  		} else {
   571  			n = Nod(OAS2, nil, nil);
   572  			n.List = $2;
   573  			n.Rlist = list1($4);
   574  		}
   575  		$$.List = list1(n);
   576  	}
   577  |	LCASE expr_or_type_list LCOLAS expr ':'
   578  	{
   579  		// will be converted to OCASE
   580  		// right will point to next case
   581  		// done in casebody()
   582  		markdcl();
   583  		$$ = Nod(OXCASE, nil, nil);
   584  		$$.List = list1(colas($2, list1($4), int32($3)));
   585  	}
   586  |	LDEFAULT ':'
   587  	{
   588  		var n, nn *Node
   589  
   590  		markdcl();
   591  		$$ = Nod(OXCASE, nil, nil);
   592  		if typesw != nil && typesw.Right != nil {
   593  			n = typesw.Right.Left
   594  			if n != nil {
   595  				// type switch - declare variable
   596  				nn = newname(n.Sym);
   597  				declare(nn, dclcontext);
   598  				$$.Rlist = list1(nn);
   599  	
   600  				// keep track of the instances for reporting unused
   601  				nn.Name.Defn = typesw.Right;
   602  			}
   603  		}
   604  	}
   605  
   606  compound_stmt:
   607  	'{'
   608  	{
   609  		markdcl();
   610  	}
   611  	stmt_list '}'
   612  	{
   613  		if $3 == nil {
   614  			$$ = Nod(OEMPTY, nil, nil);
   615  		} else {
   616  			$$ = liststmt($3);
   617  		}
   618  		popdcl();
   619  	}
   620  
   621  caseblock:
   622  	case
   623  	{
   624  		// If the last token read by the lexer was consumed
   625  		// as part of the case, clear it (parser has cleared yychar).
   626  		// If the last token read by the lexer was the lookahead
   627  		// leave it alone (parser has it cached in yychar).
   628  		// This is so that the stmt_list action doesn't look at
   629  		// the case tokens if the stmt_list is empty.
   630  		yylast = yychar;
   631  		$1.Xoffset = int64(block);
   632  	}
   633  	stmt_list
   634  	{
   635  		// This is the only place in the language where a statement
   636  		// list is not allowed to drop the final semicolon, because
   637  		// it's the only place where a statement list is not followed 
   638  		// by a closing brace.  Handle the error for pedantry.
   639  
   640  		// Find the final token of the statement list.
   641  		// yylast is lookahead; yyprev is last of stmt_list
   642  		last := yyprev;
   643  
   644  		if last > 0 && last != ';' && yychar != '}' {
   645  			Yyerror("missing statement after label");
   646  		}
   647  		$$ = $1;
   648  		$$.Nbody = $3;
   649  		popdcl();
   650  	}
   651  
   652  caseblock_list:
   653  	{
   654  		$$ = nil;
   655  	}
   656  |	caseblock_list caseblock
   657  	{
   658  		$$ = list($1, $2);
   659  	}
   660  
   661  loop_body:
   662  	LBODY
   663  	{
   664  		markdcl();
   665  	}
   666  	stmt_list '}'
   667  	{
   668  		$$ = $3;
   669  		popdcl();
   670  	}
   671  
   672  range_stmt:
   673  	expr_list '=' LRANGE expr
   674  	{
   675  		$$ = Nod(ORANGE, nil, $4);
   676  		$$.List = $1;
   677  		$$.Etype = 0;	// := flag
   678  	}
   679  |	expr_list LCOLAS LRANGE expr
   680  	{
   681  		$$ = Nod(ORANGE, nil, $4);
   682  		$$.List = $1;
   683  		$$.Colas = true;
   684  		colasdefn($1, $$);
   685  	}
   686  |	LRANGE expr
   687  	{
   688  		$$ = Nod(ORANGE, nil, $2);
   689  		$$.Etype = 0; // := flag
   690  	}
   691  
   692  for_header:
   693  	osimple_stmt ';' osimple_stmt ';' osimple_stmt
   694  	{
   695  		// init ; test ; incr
   696  		if $5 != nil && $5.Colas {
   697  			Yyerror("cannot declare in the for-increment");
   698  		}
   699  		$$ = Nod(OFOR, nil, nil);
   700  		if $1 != nil {
   701  			$$.Ninit = list1($1);
   702  		}
   703  		$$.Left = $3;
   704  		$$.Right = $5;
   705  	}
   706  |	osimple_stmt
   707  	{
   708  		// normal test
   709  		$$ = Nod(OFOR, nil, nil);
   710  		$$.Left = $1;
   711  	}
   712  |	range_stmt
   713  
   714  for_body:
   715  	for_header loop_body
   716  	{
   717  		$$ = $1;
   718  		$$.Nbody = concat($$.Nbody, $2);
   719  	}
   720  
   721  for_stmt:
   722  	LFOR
   723  	{
   724  		markdcl();
   725  	}
   726  	for_body
   727  	{
   728  		$$ = $3;
   729  		popdcl();
   730  	}
   731  
   732  if_header:
   733  	osimple_stmt
   734  	{
   735  		// test
   736  		$$ = Nod(OIF, nil, nil);
   737  		$$.Left = $1;
   738  	}
   739  |	osimple_stmt ';' osimple_stmt
   740  	{
   741  		// init ; test
   742  		$$ = Nod(OIF, nil, nil);
   743  		if $1 != nil {
   744  			$$.Ninit = list1($1);
   745  		}
   746  		$$.Left = $3;
   747  	}
   748  
   749  /* IF cond body (ELSE IF cond body)* (ELSE block)? */
   750  if_stmt:
   751  	LIF
   752  	{
   753  		markdcl();
   754  	}
   755  	if_header
   756  	{
   757  		if $3.Left == nil {
   758  			Yyerror("missing condition in if statement");
   759  		}
   760  	}
   761  	loop_body
   762  	{
   763  		$3.Nbody = $5;
   764  	}
   765  	elseif_list else
   766  	{
   767  		var n *Node
   768  		var nn *NodeList
   769  
   770  		$$ = $3;
   771  		n = $3;
   772  		popdcl();
   773  		for nn = concat($7, $8); nn != nil; nn = nn.Next {
   774  			if nn.N.Op == OIF {
   775  				popdcl();
   776  			}
   777  			n.Rlist = list1(nn.N);
   778  			n = nn.N;
   779  		}
   780  	}
   781  
   782  elseif:
   783  	LELSE LIF 
   784  	{
   785  		markdcl();
   786  	}
   787  	if_header loop_body
   788  	{
   789  		if $4.Left == nil {
   790  			Yyerror("missing condition in if statement");
   791  		}
   792  		$4.Nbody = $5;
   793  		$$ = list1($4);
   794  	}
   795  
   796  elseif_list:
   797  	{
   798  		$$ = nil;
   799  	}
   800  |	elseif_list elseif
   801  	{
   802  		$$ = concat($1, $2);
   803  	}
   804  
   805  else:
   806  	{
   807  		$$ = nil;
   808  	}
   809  |	LELSE compound_stmt
   810  	{
   811  		l := &NodeList{N: $2}
   812  		l.End = l
   813  		$$ = l;
   814  	}
   815  
   816  switch_stmt:
   817  	LSWITCH
   818  	{
   819  		markdcl();
   820  	}
   821  	if_header
   822  	{
   823  		var n *Node
   824  		n = $3.Left;
   825  		if n != nil && n.Op != OTYPESW {
   826  			n = nil;
   827  		}
   828  		typesw = Nod(OXXX, typesw, n);
   829  	}
   830  	LBODY caseblock_list '}'
   831  	{
   832  		$$ = $3;
   833  		$$.Op = OSWITCH;
   834  		$$.List = $6;
   835  		typesw = typesw.Left;
   836  		popdcl();
   837  	}
   838  
   839  select_stmt:
   840  	LSELECT
   841  	{
   842  		typesw = Nod(OXXX, typesw, nil);
   843  	}
   844  	LBODY caseblock_list '}'
   845  	{
   846  		$$ = Nod(OSELECT, nil, nil);
   847  		$$.Lineno = typesw.Lineno;
   848  		$$.List = $4;
   849  		typesw = typesw.Left;
   850  	}
   851  
   852  /*
   853   * expressions
   854   */
   855  expr:
   856  	uexpr
   857  |	expr LOROR expr
   858  	{
   859  		$$ = Nod(OOROR, $1, $3);
   860  	}
   861  |	expr LANDAND expr
   862  	{
   863  		$$ = Nod(OANDAND, $1, $3);
   864  	}
   865  |	expr LEQ expr
   866  	{
   867  		$$ = Nod(OEQ, $1, $3);
   868  	}
   869  |	expr LNE expr
   870  	{
   871  		$$ = Nod(ONE, $1, $3);
   872  	}
   873  |	expr LLT expr
   874  	{
   875  		$$ = Nod(OLT, $1, $3);
   876  	}
   877  |	expr LLE expr
   878  	{
   879  		$$ = Nod(OLE, $1, $3);
   880  	}
   881  |	expr LGE expr
   882  	{
   883  		$$ = Nod(OGE, $1, $3);
   884  	}
   885  |	expr LGT expr
   886  	{
   887  		$$ = Nod(OGT, $1, $3);
   888  	}
   889  |	expr '+' expr
   890  	{
   891  		$$ = Nod(OADD, $1, $3);
   892  	}
   893  |	expr '-' expr
   894  	{
   895  		$$ = Nod(OSUB, $1, $3);
   896  	}
   897  |	expr '|' expr
   898  	{
   899  		$$ = Nod(OOR, $1, $3);
   900  	}
   901  |	expr '^' expr
   902  	{
   903  		$$ = Nod(OXOR, $1, $3);
   904  	}
   905  |	expr '*' expr
   906  	{
   907  		$$ = Nod(OMUL, $1, $3);
   908  	}
   909  |	expr '/' expr
   910  	{
   911  		$$ = Nod(ODIV, $1, $3);
   912  	}
   913  |	expr '%' expr
   914  	{
   915  		$$ = Nod(OMOD, $1, $3);
   916  	}
   917  |	expr '&' expr
   918  	{
   919  		$$ = Nod(OAND, $1, $3);
   920  	}
   921  |	expr LANDNOT expr
   922  	{
   923  		$$ = Nod(OANDNOT, $1, $3);
   924  	}
   925  |	expr LLSH expr
   926  	{
   927  		$$ = Nod(OLSH, $1, $3);
   928  	}
   929  |	expr LRSH expr
   930  	{
   931  		$$ = Nod(ORSH, $1, $3);
   932  	}
   933  	/* not an expression anymore, but left in so we can give a good error */
   934  |	expr LCOMM expr
   935  	{
   936  		$$ = Nod(OSEND, $1, $3);
   937  	}
   938  
   939  uexpr:
   940  	pexpr
   941  |	'*' uexpr
   942  	{
   943  		$$ = Nod(OIND, $2, nil);
   944  	}
   945  |	'&' uexpr
   946  	{
   947  		if $2.Op == OCOMPLIT {
   948  			// Special case for &T{...}: turn into (*T){...}.
   949  			$$ = $2;
   950  			$$.Right = Nod(OIND, $$.Right, nil);
   951  			$$.Right.Implicit = true;
   952  		} else {
   953  			$$ = Nod(OADDR, $2, nil);
   954  		}
   955  	}
   956  |	'+' uexpr
   957  	{
   958  		$$ = Nod(OPLUS, $2, nil);
   959  	}
   960  |	'-' uexpr
   961  	{
   962  		$$ = Nod(OMINUS, $2, nil);
   963  	}
   964  |	'!' uexpr
   965  	{
   966  		$$ = Nod(ONOT, $2, nil);
   967  	}
   968  |	'~' uexpr
   969  	{
   970  		Yyerror("the bitwise complement operator is ^");
   971  		$$ = Nod(OCOM, $2, nil);
   972  	}
   973  |	'^' uexpr
   974  	{
   975  		$$ = Nod(OCOM, $2, nil);
   976  	}
   977  |	LCOMM uexpr
   978  	{
   979  		$$ = Nod(ORECV, $2, nil);
   980  	}
   981  
   982  /*
   983   * call-like statements that
   984   * can be preceded by 'defer' and 'go'
   985   */
   986  pseudocall:
   987  	pexpr '(' ')'
   988  	{
   989  		$$ = Nod(OCALL, $1, nil);
   990  	}
   991  |	pexpr '(' expr_or_type_list ocomma ')'
   992  	{
   993  		$$ = Nod(OCALL, $1, nil);
   994  		$$.List = $3;
   995  	}
   996  |	pexpr '(' expr_or_type_list LDDD ocomma ')'
   997  	{
   998  		$$ = Nod(OCALL, $1, nil);
   999  		$$.List = $3;
  1000  		$$.Isddd = true;
  1001  	}
  1002  
  1003  pexpr_no_paren:
  1004  	LLITERAL
  1005  	{
  1006  		$$ = nodlit($1);
  1007  	}
  1008  |	name
  1009  |	pexpr '.' sym
  1010  	{
  1011  		if $1.Op == OPACK {
  1012  			var s *Sym
  1013  			s = restrictlookup($3.Name, $1.Name.Pkg);
  1014  			$1.Used = true;
  1015  			$$ = oldname(s);
  1016  			break;
  1017  		}
  1018  		$$ = Nod(OXDOT, $1, newname($3));
  1019  	}
  1020  |	pexpr '.' '(' expr_or_type ')'
  1021  	{
  1022  		$$ = Nod(ODOTTYPE, $1, $4);
  1023  	}
  1024  |	pexpr '.' '(' LTYPE ')'
  1025  	{
  1026  		$$ = Nod(OTYPESW, nil, $1);
  1027  	}
  1028  |	pexpr '[' expr ']'
  1029  	{
  1030  		$$ = Nod(OINDEX, $1, $3);
  1031  	}
  1032  |	pexpr '[' oexpr ':' oexpr ']'
  1033  	{
  1034  		$$ = Nod(OSLICE, $1, Nod(OKEY, $3, $5));
  1035  	}
  1036  |	pexpr '[' oexpr ':' oexpr ':' oexpr ']'
  1037  	{
  1038  		if $5 == nil {
  1039  			Yyerror("middle index required in 3-index slice");
  1040  		}
  1041  		if $7 == nil {
  1042  			Yyerror("final index required in 3-index slice");
  1043  		}
  1044  		$$ = Nod(OSLICE3, $1, Nod(OKEY, $3, Nod(OKEY, $5, $7)));
  1045  	}
  1046  |	pseudocall
  1047  |	convtype '(' expr ocomma ')'
  1048  	{
  1049  		// conversion
  1050  		$$ = Nod(OCALL, $1, nil);
  1051  		$$.List = list1($3);
  1052  	}
  1053  |	comptype lbrace start_complit braced_keyval_list '}'
  1054  	{
  1055  		$$ = $3;
  1056  		$$.Right = $1;
  1057  		$$.List = $4;
  1058  		fixlbrace($2);
  1059  	}
  1060  |	pexpr_no_paren '{' start_complit braced_keyval_list '}'
  1061  	{
  1062  		$$ = $3;
  1063  		$$.Right = $1;
  1064  		$$.List = $4;
  1065  	}
  1066  |	'(' expr_or_type ')' '{' start_complit braced_keyval_list '}'
  1067  	{
  1068  		Yyerror("cannot parenthesize type in composite literal");
  1069  		$$ = $5;
  1070  		$$.Right = $2;
  1071  		$$.List = $6;
  1072  	}
  1073  |	fnliteral
  1074  
  1075  start_complit:
  1076  	{
  1077  		// composite expression.
  1078  		// make node early so we get the right line number.
  1079  		$$ = Nod(OCOMPLIT, nil, nil);
  1080  	}
  1081  
  1082  keyval:
  1083  	complitexpr ':' complitexpr
  1084  	{
  1085  		$$ = Nod(OKEY, $1, $3);
  1086  	}
  1087  
  1088  bare_complitexpr:
  1089  	expr
  1090  	{
  1091  		// These nodes do not carry line numbers.
  1092  		// Since a composite literal commonly spans several lines,
  1093  		// the line number on errors may be misleading.
  1094  		// Introduce a wrapper node to give the correct line.
  1095  		$$ = $1;
  1096  		switch($$.Op) {
  1097  		case ONAME, ONONAME, OTYPE, OPACK, OLITERAL:
  1098  			$$ = Nod(OPAREN, $$, nil);
  1099  			$$.Implicit = true;
  1100  		}
  1101  	}
  1102  |	'{' start_complit braced_keyval_list '}'
  1103  	{
  1104  		$$ = $2;
  1105  		$$.List = $3;
  1106  	}
  1107  
  1108  complitexpr:
  1109  	expr
  1110  |	'{' start_complit braced_keyval_list '}'
  1111  	{
  1112  		$$ = $2;
  1113  		$$.List = $3;
  1114  	}
  1115  
  1116  pexpr:
  1117  	pexpr_no_paren
  1118  |	'(' expr_or_type ')'
  1119  	{
  1120  		$$ = $2;
  1121  		
  1122  		// Need to know on lhs of := whether there are ( ).
  1123  		// Don't bother with the OPAREN in other cases:
  1124  		// it's just a waste of memory and time.
  1125  		switch($$.Op) {
  1126  		case ONAME, ONONAME, OPACK, OTYPE, OLITERAL, OTYPESW:
  1127  			$$ = Nod(OPAREN, $$, nil);
  1128  		}
  1129  	}
  1130  
  1131  expr_or_type:
  1132  	expr
  1133  |	non_expr_type	%prec PreferToRightParen
  1134  
  1135  name_or_type:
  1136  	ntype
  1137  
  1138  lbrace:
  1139  	LBODY
  1140  	{
  1141  		$$ = LBODY;
  1142  	}
  1143  |	'{'
  1144  	{
  1145  		$$ = '{';
  1146  	}
  1147  
  1148  /*
  1149   * names and types
  1150   *	newname is used before declared
  1151   *	oldname is used after declared
  1152   */
  1153  new_name:
  1154  	sym
  1155  	{
  1156  		if $1 == nil {
  1157  			$$ = nil;
  1158  		} else {
  1159  			$$ = newname($1);
  1160  		}
  1161  	}
  1162  
  1163  dcl_name:
  1164  	sym
  1165  	{
  1166  		$$ = dclname($1);
  1167  	}
  1168  
  1169  onew_name:
  1170  	{
  1171  		$$ = nil;
  1172  	}
  1173  |	new_name
  1174  
  1175  sym:
  1176  	LNAME
  1177  	{
  1178  		$$ = $1;
  1179  		// during imports, unqualified non-exported identifiers are from builtinpkg
  1180  		if importpkg != nil && !exportname($1.Name) {
  1181  			$$ = Pkglookup($1.Name, builtinpkg);
  1182  		}
  1183  	}
  1184  |	hidden_importsym
  1185  |	'?'
  1186  	{
  1187  		$$ = nil;
  1188  	}
  1189  
  1190  hidden_importsym:
  1191  	'@' LLITERAL '.' LNAME
  1192  	{
  1193  		var p *Pkg
  1194  
  1195  		if $2.U.(string) == "" {
  1196  			p = importpkg;
  1197  		} else {
  1198  			if isbadimport($2.U.(string)) {
  1199  				errorexit();
  1200  			}
  1201  			p = mkpkg($2.U.(string));
  1202  		}
  1203  		$$ = Pkglookup($4.Name, p);
  1204  	}
  1205  |	'@' LLITERAL '.' '?'
  1206  	{
  1207  		var p *Pkg
  1208  
  1209  		if $2.U.(string) == "" {
  1210  			p = importpkg;
  1211  		} else {
  1212  			if isbadimport($2.U.(string)) {
  1213  				errorexit();
  1214  			}
  1215  			p = mkpkg($2.U.(string));
  1216  		}
  1217  		$$ = Pkglookup("?", p);
  1218  	}
  1219  
  1220  name:
  1221  	sym	%prec NotParen
  1222  	{
  1223  		$$ = oldname($1);
  1224  		if $$.Name != nil && $$.Name.Pack != nil {
  1225  			$$.Name.Pack.Used = true;
  1226  		}
  1227  	}
  1228  
  1229  labelname:
  1230  	new_name
  1231  
  1232  /*
  1233   * to avoid parsing conflicts, type is split into
  1234   *	channel types
  1235   *	function types
  1236   *	parenthesized types
  1237   *	any other type
  1238   * the type system makes additional restrictions,
  1239   * but those are not implemented in the grammar.
  1240   */
  1241  dotdotdot:
  1242  	LDDD
  1243  	{
  1244  		Yyerror("final argument in variadic function missing type");
  1245  		$$ = Nod(ODDD, typenod(typ(TINTER)), nil);
  1246  	}
  1247  |	LDDD ntype
  1248  	{
  1249  		$$ = Nod(ODDD, $2, nil);
  1250  	}
  1251  
  1252  ntype:
  1253  	recvchantype
  1254  |	fntype
  1255  |	othertype
  1256  |	ptrtype
  1257  |	dotname
  1258  |	'(' ntype ')'
  1259  	{
  1260  		$$ = $2;
  1261  	}
  1262  
  1263  non_expr_type:
  1264  	recvchantype
  1265  |	fntype
  1266  |	othertype
  1267  |	'*' non_expr_type
  1268  	{
  1269  		$$ = Nod(OIND, $2, nil);
  1270  	}
  1271  
  1272  non_recvchantype:
  1273  	fntype
  1274  |	othertype
  1275  |	ptrtype
  1276  |	dotname
  1277  |	'(' ntype ')'
  1278  	{
  1279  		$$ = $2;
  1280  	}
  1281  
  1282  convtype:
  1283  	fntype
  1284  |	othertype
  1285  
  1286  comptype:
  1287  	othertype
  1288  
  1289  fnret_type:
  1290  	recvchantype
  1291  |	fntype
  1292  |	othertype
  1293  |	ptrtype
  1294  |	dotname
  1295  
  1296  dotname:
  1297  	name
  1298  |	name '.' sym
  1299  	{
  1300  		if $1.Op == OPACK {
  1301  			var s *Sym
  1302  			s = restrictlookup($3.Name, $1.Name.Pkg);
  1303  			$1.Used = true;
  1304  			$$ = oldname(s);
  1305  			break;
  1306  		}
  1307  		$$ = Nod(OXDOT, $1, newname($3));
  1308  	}
  1309  
  1310  othertype:
  1311  	'[' oexpr ']' ntype
  1312  	{
  1313  		$$ = Nod(OTARRAY, $2, $4);
  1314  	}
  1315  |	'[' LDDD ']' ntype
  1316  	{
  1317  		// array literal of nelem
  1318  		$$ = Nod(OTARRAY, Nod(ODDD, nil, nil), $4);
  1319  	}
  1320  |	LCHAN non_recvchantype
  1321  	{
  1322  		$$ = Nod(OTCHAN, $2, nil);
  1323  		$$.Etype = Cboth;
  1324  	}
  1325  |	LCHAN LCOMM ntype
  1326  	{
  1327  		$$ = Nod(OTCHAN, $3, nil);
  1328  		$$.Etype = Csend;
  1329  	}
  1330  |	LMAP '[' ntype ']' ntype
  1331  	{
  1332  		$$ = Nod(OTMAP, $3, $5);
  1333  	}
  1334  |	structtype
  1335  |	interfacetype
  1336  
  1337  ptrtype:
  1338  	'*' ntype
  1339  	{
  1340  		$$ = Nod(OIND, $2, nil);
  1341  	}
  1342  
  1343  recvchantype:
  1344  	LCOMM LCHAN ntype
  1345  	{
  1346  		$$ = Nod(OTCHAN, $3, nil);
  1347  		$$.Etype = Crecv;
  1348  	}
  1349  
  1350  structtype:
  1351  	LSTRUCT lbrace structdcl_list osemi '}'
  1352  	{
  1353  		$$ = Nod(OTSTRUCT, nil, nil);
  1354  		$$.List = $3;
  1355  		fixlbrace($2);
  1356  	}
  1357  |	LSTRUCT lbrace '}'
  1358  	{
  1359  		$$ = Nod(OTSTRUCT, nil, nil);
  1360  		fixlbrace($2);
  1361  	}
  1362  
  1363  interfacetype:
  1364  	LINTERFACE lbrace interfacedcl_list osemi '}'
  1365  	{
  1366  		$$ = Nod(OTINTER, nil, nil);
  1367  		$$.List = $3;
  1368  		fixlbrace($2);
  1369  	}
  1370  |	LINTERFACE lbrace '}'
  1371  	{
  1372  		$$ = Nod(OTINTER, nil, nil);
  1373  		fixlbrace($2);
  1374  	}
  1375  
  1376  /*
  1377   * function stuff
  1378   * all in one place to show how crappy it all is
  1379   */
  1380  xfndcl:
  1381  	LFUNC fndcl fnbody
  1382  	{
  1383  		$$ = $2;
  1384  		if $$ == nil {
  1385  			break;
  1386  		}
  1387  		if noescape && $3 != nil {
  1388  			Yyerror("can only use //go:noescape with external func implementations");
  1389  		}
  1390  		$$.Nbody = $3;
  1391  		$$.Func.Endlineno = lineno;
  1392  		$$.Noescape = noescape;
  1393  		$$.Func.Norace = norace;
  1394  		$$.Func.Nosplit = nosplit;
  1395  		$$.Func.Nowritebarrier = nowritebarrier;
  1396  		$$.Func.Systemstack = systemstack;
  1397  		funcbody($$);
  1398  	}
  1399  
  1400  fndcl:
  1401  	sym '(' oarg_type_list_ocomma ')' fnres
  1402  	{
  1403  		var t *Node
  1404  
  1405  		$$ = nil;
  1406  		$3 = checkarglist($3, 1);
  1407  
  1408  		if $1.Name == "init" {
  1409  			$1 = renameinit();
  1410  			if $3 != nil || $5 != nil {
  1411  				Yyerror("func init must have no arguments and no return values");
  1412  			}
  1413  		}
  1414  		if localpkg.Name == "main" && $1.Name == "main" {
  1415  			if $3 != nil || $5 != nil {
  1416  				Yyerror("func main must have no arguments and no return values");
  1417  			}
  1418  		}
  1419  
  1420  		t = Nod(OTFUNC, nil, nil);
  1421  		t.List = $3;
  1422  		t.Rlist = $5;
  1423  
  1424  		$$ = Nod(ODCLFUNC, nil, nil);
  1425  		$$.Func.Nname = newfuncname($1);
  1426  		$$.Func.Nname.Name.Defn = $$;
  1427  		$$.Func.Nname.Name.Param.Ntype = t;		// TODO: check if nname already has an ntype
  1428  		declare($$.Func.Nname, PFUNC);
  1429  
  1430  		funchdr($$);
  1431  	}
  1432  |	'(' oarg_type_list_ocomma ')' sym '(' oarg_type_list_ocomma ')' fnres
  1433  	{
  1434  		var rcvr, t *Node
  1435  
  1436  		$$ = nil;
  1437  		$2 = checkarglist($2, 0);
  1438  		$6 = checkarglist($6, 1);
  1439  
  1440  		if $2 == nil {
  1441  			Yyerror("method has no receiver");
  1442  			break;
  1443  		}
  1444  		if $2.Next != nil {
  1445  			Yyerror("method has multiple receivers");
  1446  			break;
  1447  		}
  1448  		rcvr = $2.N;
  1449  		if rcvr.Op != ODCLFIELD {
  1450  			Yyerror("bad receiver in method");
  1451  			break;
  1452  		}
  1453  
  1454  		t = Nod(OTFUNC, rcvr, nil);
  1455  		t.List = $6;
  1456  		t.Rlist = $8;
  1457  
  1458  		$$ = Nod(ODCLFUNC, nil, nil);
  1459  		$$.Func.Shortname = newfuncname($4);
  1460  		$$.Func.Nname = methodname1($$.Func.Shortname, rcvr.Right);
  1461  		$$.Func.Nname.Name.Defn = $$;
  1462  		$$.Func.Nname.Name.Param.Ntype = t;
  1463  		$$.Func.Nname.Nointerface = nointerface;
  1464  		declare($$.Func.Nname, PFUNC);
  1465  
  1466  		funchdr($$);
  1467  	}
  1468  
  1469  hidden_fndcl:
  1470  	hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres
  1471  	{
  1472  		var s *Sym
  1473  		var t *Type
  1474  
  1475  		$$ = nil;
  1476  
  1477  		s = $1;
  1478  		t = functype(nil, $3, $5);
  1479  
  1480  		importsym(s, ONAME);
  1481  		if s.Def != nil && s.Def.Op == ONAME {
  1482  			if Eqtype(t, s.Def.Type) {
  1483  				dclcontext = PDISCARD;  // since we skip funchdr below
  1484  				break;
  1485  			}
  1486  			Yyerror("inconsistent definition for func %v during import\n\t%v\n\t%v", s, s.Def.Type, t);
  1487  		}
  1488  
  1489  		$$ = newfuncname(s);
  1490  		$$.Type = t;
  1491  		declare($$, PFUNC);
  1492  
  1493  		funchdr($$);
  1494  	}
  1495  |	'(' hidden_funarg_list ')' sym '(' ohidden_funarg_list ')' ohidden_funres
  1496  	{
  1497  		$$ = methodname1(newname($4), $2.N.Right); 
  1498  		$$.Type = functype($2.N, $6, $8);
  1499  
  1500  		checkwidth($$.Type);
  1501  		addmethod($4, $$.Type, false, nointerface);
  1502  		nointerface = false
  1503  		funchdr($$);
  1504  		
  1505  		// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
  1506  		// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
  1507  		// out by typecheck's lookdot as this $$.ttype.  So by providing
  1508  		// this back link here we avoid special casing there.
  1509  		$$.Type.Nname = $$;
  1510  	}
  1511  
  1512  fntype:
  1513  	LFUNC '(' oarg_type_list_ocomma ')' fnres
  1514  	{
  1515  		$3 = checkarglist($3, 1);
  1516  		$$ = Nod(OTFUNC, nil, nil);
  1517  		$$.List = $3;
  1518  		$$.Rlist = $5;
  1519  	}
  1520  
  1521  fnbody:
  1522  	{
  1523  		$$ = nil;
  1524  	}
  1525  |	'{' stmt_list '}'
  1526  	{
  1527  		$$ = $2;
  1528  		if $$ == nil {
  1529  			$$ = list1(Nod(OEMPTY, nil, nil));
  1530  		}
  1531  	}
  1532  
  1533  fnres:
  1534  	%prec NotParen
  1535  	{
  1536  		$$ = nil;
  1537  	}
  1538  |	fnret_type
  1539  	{
  1540  		$$ = list1(Nod(ODCLFIELD, nil, $1));
  1541  	}
  1542  |	'(' oarg_type_list_ocomma ')'
  1543  	{
  1544  		$2 = checkarglist($2, 0);
  1545  		$$ = $2;
  1546  	}
  1547  
  1548  fnlitdcl:
  1549  	fntype
  1550  	{
  1551  		closurehdr($1);
  1552  	}
  1553  
  1554  fnliteral:
  1555  	fnlitdcl lbrace stmt_list '}'
  1556  	{
  1557  		$$ = closurebody($3);
  1558  		fixlbrace($2);
  1559  	}
  1560  |	fnlitdcl error
  1561  	{
  1562  		$$ = closurebody(nil);
  1563  	}
  1564  
  1565  /*
  1566   * lists of things
  1567   * note that they are left recursive
  1568   * to conserve yacc stack. they need to
  1569   * be reversed to interpret correctly
  1570   */
  1571  xdcl_list:
  1572  	{
  1573  		$$ = nil;
  1574  	}
  1575  |	xdcl_list xdcl ';'
  1576  	{
  1577  		$$ = concat($1, $2);
  1578  		if nsyntaxerrors == 0 {
  1579  			testdclstack();
  1580  		}
  1581  		nointerface = false
  1582  		noescape = false
  1583  		norace = false
  1584  		nosplit = false
  1585  		nowritebarrier = false
  1586  		systemstack = false
  1587  	}
  1588  
  1589  vardcl_list:
  1590  	vardcl
  1591  |	vardcl_list ';' vardcl
  1592  	{
  1593  		$$ = concat($1, $3);
  1594  	}
  1595  
  1596  constdcl_list:
  1597  	constdcl1
  1598  |	constdcl_list ';' constdcl1
  1599  	{
  1600  		$$ = concat($1, $3);
  1601  	}
  1602  
  1603  typedcl_list:
  1604  	typedcl
  1605  	{
  1606  		$$ = list1($1);
  1607  	}
  1608  |	typedcl_list ';' typedcl
  1609  	{
  1610  		$$ = list($1, $3);
  1611  	}
  1612  
  1613  structdcl_list:
  1614  	structdcl
  1615  |	structdcl_list ';' structdcl
  1616  	{
  1617  		$$ = concat($1, $3);
  1618  	}
  1619  
  1620  interfacedcl_list:
  1621  	interfacedcl
  1622  	{
  1623  		$$ = list1($1);
  1624  	}
  1625  |	interfacedcl_list ';' interfacedcl
  1626  	{
  1627  		$$ = list($1, $3);
  1628  	}
  1629  
  1630  structdcl:
  1631  	new_name_list ntype oliteral
  1632  	{
  1633  		var l *NodeList
  1634  
  1635  		var n *Node
  1636  		l = $1;
  1637  		if l == nil || l.N.Sym.Name == "?" {
  1638  			// ? symbol, during import (list1(nil) == nil)
  1639  			n = $2;
  1640  			if n.Op == OIND {
  1641  				n = n.Left;
  1642  			}
  1643  			n = embedded(n.Sym, importpkg);
  1644  			n.Right = $2;
  1645  			n.SetVal($3)
  1646  			$$ = list1(n);
  1647  			break;
  1648  		}
  1649  
  1650  		for l=$1; l != nil; l=l.Next {
  1651  			l.N = Nod(ODCLFIELD, l.N, $2);
  1652  			l.N.SetVal($3)
  1653  		}
  1654  	}
  1655  |	embed oliteral
  1656  	{
  1657  		$1.SetVal($2)
  1658  		$$ = list1($1);
  1659  	}
  1660  |	'(' embed ')' oliteral
  1661  	{
  1662  		$2.SetVal($4)
  1663  		$$ = list1($2);
  1664  		Yyerror("cannot parenthesize embedded type");
  1665  	}
  1666  |	'*' embed oliteral
  1667  	{
  1668  		$2.Right = Nod(OIND, $2.Right, nil);
  1669  		$2.SetVal($3)
  1670  		$$ = list1($2);
  1671  	}
  1672  |	'(' '*' embed ')' oliteral
  1673  	{
  1674  		$3.Right = Nod(OIND, $3.Right, nil);
  1675  		$3.SetVal($5)
  1676  		$$ = list1($3);
  1677  		Yyerror("cannot parenthesize embedded type");
  1678  	}
  1679  |	'*' '(' embed ')' oliteral
  1680  	{
  1681  		$3.Right = Nod(OIND, $3.Right, nil);
  1682  		$3.SetVal($5)
  1683  		$$ = list1($3);
  1684  		Yyerror("cannot parenthesize embedded type");
  1685  	}
  1686  
  1687  packname:
  1688  	LNAME
  1689  	{
  1690  		var n *Node
  1691  
  1692  		$$ = $1;
  1693  		n = oldname($1);
  1694  		if n.Name != nil && n.Name.Pack != nil {
  1695  			n.Name.Pack.Used = true;
  1696  		}
  1697  	}
  1698  |	LNAME '.' sym
  1699  	{
  1700  		var pkg *Pkg
  1701  
  1702  		if $1.Def == nil || $1.Def.Op != OPACK {
  1703  			Yyerror("%v is not a package", $1);
  1704  			pkg = localpkg;
  1705  		} else {
  1706  			$1.Def.Used = true;
  1707  			pkg = $1.Def.Name.Pkg;
  1708  		}
  1709  		$$ = restrictlookup($3.Name, pkg);
  1710  	}
  1711  
  1712  embed:
  1713  	packname
  1714  	{
  1715  		$$ = embedded($1, localpkg);
  1716  	}
  1717  
  1718  interfacedcl:
  1719  	new_name indcl
  1720  	{
  1721  		$$ = Nod(ODCLFIELD, $1, $2);
  1722  		ifacedcl($$);
  1723  	}
  1724  |	packname
  1725  	{
  1726  		$$ = Nod(ODCLFIELD, nil, oldname($1));
  1727  	}
  1728  |	'(' packname ')'
  1729  	{
  1730  		$$ = Nod(ODCLFIELD, nil, oldname($2));
  1731  		Yyerror("cannot parenthesize embedded type");
  1732  	}
  1733  
  1734  indcl:
  1735  	'(' oarg_type_list_ocomma ')' fnres
  1736  	{
  1737  		// without func keyword
  1738  		$2 = checkarglist($2, 1);
  1739  		$$ = Nod(OTFUNC, fakethis(), nil);
  1740  		$$.List = $2;
  1741  		$$.Rlist = $4;
  1742  	}
  1743  
  1744  /*
  1745   * function arguments.
  1746   */
  1747  arg_type:
  1748  	name_or_type
  1749  |	sym name_or_type
  1750  	{
  1751  		$$ = Nod(ONONAME, nil, nil);
  1752  		$$.Sym = $1;
  1753  		$$ = Nod(OKEY, $$, $2);
  1754  	}
  1755  |	sym dotdotdot
  1756  	{
  1757  		$$ = Nod(ONONAME, nil, nil);
  1758  		$$.Sym = $1;
  1759  		$$ = Nod(OKEY, $$, $2);
  1760  	}
  1761  |	dotdotdot
  1762  
  1763  arg_type_list:
  1764  	arg_type
  1765  	{
  1766  		$$ = list1($1);
  1767  	}
  1768  |	arg_type_list ',' arg_type
  1769  	{
  1770  		$$ = list($1, $3);
  1771  	}
  1772  
  1773  oarg_type_list_ocomma:
  1774  	{
  1775  		$$ = nil;
  1776  	}
  1777  |	arg_type_list ocomma
  1778  	{
  1779  		$$ = $1;
  1780  	}
  1781  
  1782  /*
  1783   * statement
  1784   */
  1785  stmt:
  1786  	{
  1787  		$$ = nil;
  1788  	}
  1789  |	compound_stmt
  1790  |	common_dcl
  1791  	{
  1792  		$$ = liststmt($1);
  1793  	}
  1794  |	non_dcl_stmt
  1795  |	error
  1796  	{
  1797  		$$ = nil;
  1798  	}
  1799  
  1800  non_dcl_stmt:
  1801  	simple_stmt
  1802  |	for_stmt
  1803  |	switch_stmt
  1804  |	select_stmt
  1805  |	if_stmt
  1806  |	labelname ':'
  1807  	{
  1808  		$1 = Nod(OLABEL, $1, nil);
  1809  		$1.Sym = dclstack;  // context, for goto restrictions
  1810  	}
  1811  	stmt
  1812  	{
  1813  		var l *NodeList
  1814  
  1815  		$1.Name.Defn = $4;
  1816  		l = list1($1);
  1817  		if $4 != nil {
  1818  			l = list(l, $4);
  1819  		}
  1820  		$$ = liststmt(l);
  1821  	}
  1822  |	LFALL
  1823  	{
  1824  		// will be converted to OFALL
  1825  		$$ = Nod(OXFALL, nil, nil);
  1826  		$$.Xoffset = int64(block);
  1827  	}
  1828  |	LBREAK onew_name
  1829  	{
  1830  		$$ = Nod(OBREAK, $2, nil);
  1831  	}
  1832  |	LCONTINUE onew_name
  1833  	{
  1834  		$$ = Nod(OCONTINUE, $2, nil);
  1835  	}
  1836  |	LGO pseudocall
  1837  	{
  1838  		$$ = Nod(OPROC, $2, nil);
  1839  	}
  1840  |	LDEFER pseudocall
  1841  	{
  1842  		$$ = Nod(ODEFER, $2, nil);
  1843  	}
  1844  |	LGOTO new_name
  1845  	{
  1846  		$$ = Nod(OGOTO, $2, nil);
  1847  		$$.Sym = dclstack;  // context, for goto restrictions
  1848  	}
  1849  |	LRETURN oexpr_list
  1850  	{
  1851  		$$ = Nod(ORETURN, nil, nil);
  1852  		$$.List = $2;
  1853  		if $$.List == nil && Curfn != nil {
  1854  			var l *NodeList
  1855  
  1856  			for l=Curfn.Func.Dcl; l != nil; l=l.Next {
  1857  				if l.N.Class == PPARAM {
  1858  					continue;
  1859  				}
  1860  				if l.N.Class != PPARAMOUT {
  1861  					break;
  1862  				}
  1863  				if l.N.Sym.Def != l.N {
  1864  					Yyerror("%s is shadowed during return", l.N.Sym.Name);
  1865  				}
  1866  			}
  1867  		}
  1868  	}
  1869  
  1870  stmt_list:
  1871  	stmt
  1872  	{
  1873  		$$ = nil;
  1874  		if $1 != nil {
  1875  			$$ = list1($1);
  1876  		}
  1877  	}
  1878  |	stmt_list ';' stmt
  1879  	{
  1880  		$$ = $1;
  1881  		if $3 != nil {
  1882  			$$ = list($$, $3);
  1883  		}
  1884  	}
  1885  
  1886  new_name_list:
  1887  	new_name
  1888  	{
  1889  		$$ = list1($1);
  1890  	}
  1891  |	new_name_list ',' new_name
  1892  	{
  1893  		$$ = list($1, $3);
  1894  	}
  1895  
  1896  dcl_name_list:
  1897  	dcl_name
  1898  	{
  1899  		$$ = list1($1);
  1900  	}
  1901  |	dcl_name_list ',' dcl_name
  1902  	{
  1903  		$$ = list($1, $3);
  1904  	}
  1905  
  1906  expr_list:
  1907  	expr
  1908  	{
  1909  		$$ = list1($1);
  1910  	}
  1911  |	expr_list ',' expr
  1912  	{
  1913  		$$ = list($1, $3);
  1914  	}
  1915  
  1916  expr_or_type_list:
  1917  	expr_or_type
  1918  	{
  1919  		$$ = list1($1);
  1920  	}
  1921  |	expr_or_type_list ',' expr_or_type
  1922  	{
  1923  		$$ = list($1, $3);
  1924  	}
  1925  
  1926  /*
  1927   * list of combo of keyval and val
  1928   */
  1929  keyval_list:
  1930  	keyval
  1931  	{
  1932  		$$ = list1($1);
  1933  	}
  1934  |	bare_complitexpr
  1935  	{
  1936  		$$ = list1($1);
  1937  	}
  1938  |	keyval_list ',' keyval
  1939  	{
  1940  		$$ = list($1, $3);
  1941  	}
  1942  |	keyval_list ',' bare_complitexpr
  1943  	{
  1944  		$$ = list($1, $3);
  1945  	}
  1946  
  1947  braced_keyval_list:
  1948  	{
  1949  		$$ = nil;
  1950  	}
  1951  |	keyval_list ocomma
  1952  	{
  1953  		$$ = $1;
  1954  	}
  1955  
  1956  /*
  1957   * optional things
  1958   */
  1959  osemi:
  1960  |	';'
  1961  
  1962  ocomma:
  1963  |	','
  1964  
  1965  oexpr:
  1966  	{
  1967  		$$ = nil;
  1968  	}
  1969  |	expr
  1970  
  1971  oexpr_list:
  1972  	{
  1973  		$$ = nil;
  1974  	}
  1975  |	expr_list
  1976  
  1977  osimple_stmt:
  1978  	{
  1979  		$$ = nil;
  1980  	}
  1981  |	simple_stmt
  1982  
  1983  ohidden_funarg_list:
  1984  	{
  1985  		$$ = nil;
  1986  	}
  1987  |	hidden_funarg_list
  1988  
  1989  ohidden_structdcl_list:
  1990  	{
  1991  		$$ = nil;
  1992  	}
  1993  |	hidden_structdcl_list
  1994  
  1995  ohidden_interfacedcl_list:
  1996  	{
  1997  		$$ = nil;
  1998  	}
  1999  |	hidden_interfacedcl_list
  2000  
  2001  oliteral:
  2002  	{
  2003  		$$.U = nil
  2004  	}
  2005  |	LLITERAL
  2006  
  2007  /*
  2008   * import syntax from package header
  2009   */
  2010  hidden_import:
  2011  	LIMPORT LNAME LLITERAL ';'
  2012  	{
  2013  		importimport($2, $3.U.(string));
  2014  	}
  2015  |	LVAR hidden_pkg_importsym hidden_type ';'
  2016  	{
  2017  		importvar($2, $3);
  2018  	}
  2019  |	LCONST hidden_pkg_importsym '=' hidden_constant ';'
  2020  	{
  2021  		importconst($2, Types[TIDEAL], $4);
  2022  	}
  2023  |	LCONST hidden_pkg_importsym hidden_type '=' hidden_constant ';'
  2024  	{
  2025  		importconst($2, $3, $5);
  2026  	}
  2027  |	LTYPE hidden_pkgtype hidden_type ';'
  2028  	{
  2029  		importtype($2, $3);
  2030  	}
  2031  |	LFUNC hidden_fndcl fnbody ';'
  2032  	{
  2033  		if $2 == nil {
  2034  			dclcontext = PEXTERN;  // since we skip the funcbody below
  2035  			break;
  2036  		}
  2037  
  2038  		$2.Func.Inl = $3;
  2039  
  2040  		funcbody($2);
  2041  		importlist = list(importlist, $2);
  2042  
  2043  		if Debug['E'] > 0 {
  2044  			fmt.Printf("import [%q] func %v \n", importpkg.Path, $2)
  2045  			if Debug['m'] > 2 && $2.Func.Inl != nil {
  2046  				fmt.Printf("inl body:%v\n", $2.Func.Inl)
  2047  			}
  2048  		}
  2049  	}
  2050  
  2051  hidden_pkg_importsym:
  2052  	hidden_importsym
  2053  	{
  2054  		$$ = $1;
  2055  		structpkg = $$.Pkg;
  2056  	}
  2057  
  2058  hidden_pkgtype:
  2059  	hidden_pkg_importsym
  2060  	{
  2061  		$$ = pkgtype($1);
  2062  		importsym($1, OTYPE);
  2063  	}
  2064  
  2065  /*
  2066   *  importing types
  2067   */
  2068  
  2069  hidden_type:
  2070  	hidden_type_misc
  2071  |	hidden_type_recv_chan
  2072  |	hidden_type_func
  2073  
  2074  hidden_type_non_recv_chan:
  2075  	hidden_type_misc
  2076  |	hidden_type_func
  2077  
  2078  hidden_type_misc:
  2079  	hidden_importsym
  2080  	{
  2081  		$$ = pkgtype($1);
  2082  	}
  2083  |	LNAME
  2084  	{
  2085  		// predefined name like uint8
  2086  		$1 = Pkglookup($1.Name, builtinpkg);
  2087  		if $1.Def == nil || $1.Def.Op != OTYPE {
  2088  			Yyerror("%s is not a type", $1.Name);
  2089  			$$ = nil;
  2090  		} else {
  2091  			$$ = $1.Def.Type;
  2092  		}
  2093  	}
  2094  |	'[' ']' hidden_type
  2095  	{
  2096  		$$ = aindex(nil, $3);
  2097  	}
  2098  |	'[' LLITERAL ']' hidden_type
  2099  	{
  2100  		$$ = aindex(nodlit($2), $4);
  2101  	}
  2102  |	LMAP '[' hidden_type ']' hidden_type
  2103  	{
  2104  		$$ = maptype($3, $5);
  2105  	}
  2106  |	LSTRUCT '{' ohidden_structdcl_list '}'
  2107  	{
  2108  		$$ = tostruct($3);
  2109  	}
  2110  |	LINTERFACE '{' ohidden_interfacedcl_list '}'
  2111  	{
  2112  		$$ = tointerface($3);
  2113  	}
  2114  |	'*' hidden_type
  2115  	{
  2116  		$$ = Ptrto($2);
  2117  	}
  2118  |	LCHAN hidden_type_non_recv_chan
  2119  	{
  2120  		$$ = typ(TCHAN);
  2121  		$$.Type = $2;
  2122  		$$.Chan = Cboth;
  2123  	}
  2124  |	LCHAN '(' hidden_type_recv_chan ')'
  2125  	{
  2126  		$$ = typ(TCHAN);
  2127  		$$.Type = $3;
  2128  		$$.Chan = Cboth;
  2129  	}
  2130  |	LCHAN LCOMM hidden_type
  2131  	{
  2132  		$$ = typ(TCHAN);
  2133  		$$.Type = $3;
  2134  		$$.Chan = Csend;
  2135  	}
  2136  
  2137  hidden_type_recv_chan:
  2138  	LCOMM LCHAN hidden_type
  2139  	{
  2140  		$$ = typ(TCHAN);
  2141  		$$.Type = $3;
  2142  		$$.Chan = Crecv;
  2143  	}
  2144  
  2145  hidden_type_func:
  2146  	LFUNC '(' ohidden_funarg_list ')' ohidden_funres
  2147  	{
  2148  		$$ = functype(nil, $3, $5);
  2149  	}
  2150  
  2151  hidden_funarg:
  2152  	sym hidden_type oliteral
  2153  	{
  2154  		$$ = Nod(ODCLFIELD, nil, typenod($2));
  2155  		if $1 != nil {
  2156  			$$.Left = newname($1);
  2157  		}
  2158  		$$.SetVal($3)
  2159  	}
  2160  |	sym LDDD hidden_type oliteral
  2161  	{
  2162  		var t *Type
  2163  	
  2164  		t = typ(TARRAY);
  2165  		t.Bound = -1;
  2166  		t.Type = $3;
  2167  
  2168  		$$ = Nod(ODCLFIELD, nil, typenod(t));
  2169  		if $1 != nil {
  2170  			$$.Left = newname($1);
  2171  		}
  2172  		$$.Isddd = true;
  2173  		$$.SetVal($4)
  2174  	}
  2175  
  2176  hidden_structdcl:
  2177  	sym hidden_type oliteral
  2178  	{
  2179  		var s *Sym
  2180  		var p *Pkg
  2181  
  2182  		if $1 != nil && $1.Name != "?" {
  2183  			$$ = Nod(ODCLFIELD, newname($1), typenod($2));
  2184  			$$.SetVal($3)
  2185  		} else {
  2186  			s = $2.Sym;
  2187  			if s == nil && Isptr[$2.Etype] {
  2188  				s = $2.Type.Sym;
  2189  			}
  2190  			p = importpkg;
  2191  			if $1 != nil {
  2192  				p = $1.Pkg;
  2193  			}
  2194  			$$ = embedded(s, p);
  2195  			$$.Right = typenod($2);
  2196  			$$.SetVal($3)
  2197  		}
  2198  	}
  2199  
  2200  hidden_interfacedcl:
  2201  	sym '(' ohidden_funarg_list ')' ohidden_funres
  2202  	{
  2203  		$$ = Nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
  2204  	}
  2205  |	hidden_type
  2206  	{
  2207  		$$ = Nod(ODCLFIELD, nil, typenod($1));
  2208  	}
  2209  
  2210  ohidden_funres:
  2211  	{
  2212  		$$ = nil;
  2213  	}
  2214  |	hidden_funres
  2215  
  2216  hidden_funres:
  2217  	'(' ohidden_funarg_list ')'
  2218  	{
  2219  		$$ = $2;
  2220  	}
  2221  |	hidden_type
  2222  	{
  2223  		$$ = list1(Nod(ODCLFIELD, nil, typenod($1)));
  2224  	}
  2225  
  2226  /*
  2227   *  importing constants
  2228   */
  2229  
  2230  hidden_literal:
  2231  	LLITERAL
  2232  	{
  2233  		$$ = nodlit($1);
  2234  	}
  2235  |	'-' LLITERAL
  2236  	{
  2237  		$$ = nodlit($2);
  2238  		switch($$.Val().Ctype()){
  2239  		case CTINT, CTRUNE:
  2240  			mpnegfix($$.Val().U.(*Mpint));
  2241  			break;
  2242  		case CTFLT:
  2243  			mpnegflt($$.Val().U.(*Mpflt));
  2244  			break;
  2245  		case CTCPLX:
  2246  			mpnegflt(&$$.Val().U.(*Mpcplx).Real);
  2247  			mpnegflt(&$$.Val().U.(*Mpcplx).Imag);
  2248  			break;
  2249  		default:
  2250  			Yyerror("bad negated constant");
  2251  		}
  2252  	}
  2253  |	sym
  2254  	{
  2255  		$$ = oldname(Pkglookup($1.Name, builtinpkg));
  2256  		if $$.Op != OLITERAL {
  2257  			Yyerror("bad constant %v", $$.Sym);
  2258  		}
  2259  	}
  2260  
  2261  hidden_constant:
  2262  	hidden_literal
  2263  |	'(' hidden_literal '+' hidden_literal ')'
  2264  	{
  2265  		if $2.Val().Ctype() == CTRUNE && $4.Val().Ctype() == CTINT {
  2266  			$$ = $2;
  2267  			mpaddfixfix($2.Val().U.(*Mpint), $4.Val().U.(*Mpint), 0);
  2268  			break;
  2269  		}
  2270  		$4.Val().U.(*Mpcplx).Real = $4.Val().U.(*Mpcplx).Imag;
  2271  		Mpmovecflt(&$4.Val().U.(*Mpcplx).Imag, 0.0);
  2272  		$$ = nodcplxlit($2.Val(), $4.Val());
  2273  	}
  2274  
  2275  hidden_import_list:
  2276  |	hidden_import_list hidden_import
  2277  
  2278  hidden_funarg_list:
  2279  	hidden_funarg
  2280  	{
  2281  		$$ = list1($1);
  2282  	}
  2283  |	hidden_funarg_list ',' hidden_funarg
  2284  	{
  2285  		$$ = list($1, $3);
  2286  	}
  2287  
  2288  hidden_structdcl_list:
  2289  	hidden_structdcl
  2290  	{
  2291  		$$ = list1($1);
  2292  	}
  2293  |	hidden_structdcl_list ';' hidden_structdcl
  2294  	{
  2295  		$$ = list($1, $3);
  2296  	}
  2297  
  2298  hidden_interfacedcl_list:
  2299  	hidden_interfacedcl
  2300  	{
  2301  		$$ = list1($1);
  2302  	}
  2303  |	hidden_interfacedcl_list ';' hidden_interfacedcl
  2304  	{
  2305  		$$ = list($1, $3);
  2306  	}
  2307  
  2308  %%
  2309  func fixlbrace(lbr int) {
  2310  	// If the opening brace was an LBODY,
  2311  	// set up for another one now that we're done.
  2312  	// See comment in lex.C about loophack.
  2313  	if lbr == LBODY {
  2314  		loophack = 1
  2315  	}
  2316  }