github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6a/a.y (about)

     1  // Inferno utils/6a/a.y
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6a/a.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 a.h re-#defines getc */
    34  #include <libc.h>
    35  #include "a.h"
    36  #include "../../pkg/runtime/funcdata.h"
    37  %}
    38  %union	{
    39  	Sym	*sym;
    40  	vlong	lval;
    41  	double	dval;
    42  	char	sval[8];
    43  	Gen	gen;
    44  	Gen2	gen2;
    45  }
    46  %left	'|'
    47  %left	'^'
    48  %left	'&'
    49  %left	'<' '>'
    50  %left	'+' '-'
    51  %left	'*' '/' '%'
    52  %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
    53  %token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC
    54  %token	<lval>	LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF
    55  %token	<lval>	LCONST LFP LPC LSB
    56  %token	<lval>	LBREG LLREG LSREG LFREG LMREG LXREG
    57  %token	<dval>	LFCONST
    58  %token	<sval>	LSCONST LSP
    59  %token	<sym>	LNAME LLAB LVAR
    60  %type	<lval>	con con2 expr pointer offset
    61  %type	<gen>	mem imm imm2 reg nam rel rem rim rom omem nmem
    62  %type	<gen2>	nonnon nonrel nonrem rimnon rimrem remrim
    63  %type	<gen2>	spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
    64  %type	<gen2>	spec10 spec11 spec12 spec13
    65  %%
    66  prog:
    67  |	prog 
    68  	{
    69  		stmtline = lineno;
    70  	}
    71  	line
    72  
    73  line:
    74  	LLAB ':'
    75  	{
    76  		if($1->value != pc)
    77  			yyerror("redeclaration of %s", $1->name);
    78  		$1->value = pc;
    79  	}
    80  	line
    81  |	LNAME ':'
    82  	{
    83  		$1->type = LLAB;
    84  		$1->value = pc;
    85  	}
    86  	line
    87  |	';'
    88  |	inst ';'
    89  |	error ';'
    90  
    91  inst:
    92  	LNAME '=' expr
    93  	{
    94  		$1->type = LVAR;
    95  		$1->value = $3;
    96  	}
    97  |	LVAR '=' expr
    98  	{
    99  		if($1->value != $3)
   100  			yyerror("redeclaration of %s", $1->name);
   101  		$1->value = $3;
   102  	}
   103  |	LTYPE0 nonnon	{ outcode($1, &$2); }
   104  |	LTYPE1 nonrem	{ outcode($1, &$2); }
   105  |	LTYPE2 rimnon	{ outcode($1, &$2); }
   106  |	LTYPE3 rimrem	{ outcode($1, &$2); }
   107  |	LTYPE4 remrim	{ outcode($1, &$2); }
   108  |	LTYPER nonrel	{ outcode($1, &$2); }
   109  |	LTYPED spec1	{ outcode($1, &$2); }
   110  |	LTYPET spec2	{ outcode($1, &$2); }
   111  |	LTYPEC spec3	{ outcode($1, &$2); }
   112  |	LTYPEN spec4	{ outcode($1, &$2); }
   113  |	LTYPES spec5	{ outcode($1, &$2); }
   114  |	LTYPEM spec6	{ outcode($1, &$2); }
   115  |	LTYPEI spec7	{ outcode($1, &$2); }
   116  |	LTYPEXC spec8	{ outcode($1, &$2); }
   117  |	LTYPEX spec9	{ outcode($1, &$2); }
   118  |	LTYPERT spec10	{ outcode($1, &$2); }
   119  |	LTYPEG spec11	{ outcode($1, &$2); }
   120  |	LTYPEPC spec12	{ outcode($1, &$2); }
   121  |	LTYPEF spec13	{ outcode($1, &$2); }
   122  
   123  nonnon:
   124  	{
   125  		$$.from = nullgen;
   126  		$$.to = nullgen;
   127  	}
   128  |	','
   129  	{
   130  		$$.from = nullgen;
   131  		$$.to = nullgen;
   132  	}
   133  
   134  rimrem:
   135  	rim ',' rem
   136  	{
   137  		$$.from = $1;
   138  		$$.to = $3;
   139  	}
   140  
   141  remrim:
   142  	rem ',' rim
   143  	{
   144  		$$.from = $1;
   145  		$$.to = $3;
   146  	}
   147  
   148  rimnon:
   149  	rim ','
   150  	{
   151  		$$.from = $1;
   152  		$$.to = nullgen;
   153  	}
   154  |	rim
   155  	{
   156  		$$.from = $1;
   157  		$$.to = nullgen;
   158  	}
   159  
   160  nonrem:
   161  	',' rem
   162  	{
   163  		$$.from = nullgen;
   164  		$$.to = $2;
   165  	}
   166  |	rem
   167  	{
   168  		$$.from = nullgen;
   169  		$$.to = $1;
   170  	}
   171  
   172  nonrel:
   173  	',' rel
   174  	{
   175  		$$.from = nullgen;
   176  		$$.to = $2;
   177  	}
   178  |	rel
   179  	{
   180  		$$.from = nullgen;
   181  		$$.to = $1;
   182  	}
   183  |	imm ',' rel
   184  	{
   185  		$$.from = $1;
   186  		$$.to = $3;
   187  	}
   188  
   189  spec1:	/* DATA */
   190  	nam '/' con ',' imm
   191  	{
   192  		$$.from = $1;
   193  		$$.from.scale = $3;
   194  		$$.to = $5;
   195  	}
   196  
   197  spec2:	/* TEXT */
   198  	mem ',' imm2
   199  	{
   200  		$$.from = $1;
   201  		$$.to = $3;
   202  	}
   203  |	mem ',' con ',' imm2
   204  	{
   205  		$$.from = $1;
   206  		$$.from.scale = $3;
   207  		$$.to = $5;
   208  	}
   209  
   210  spec3:	/* JMP/CALL */
   211  	',' rom
   212  	{
   213  		$$.from = nullgen;
   214  		$$.to = $2;
   215  	}
   216  |	rom
   217  	{
   218  		$$.from = nullgen;
   219  		$$.to = $1;
   220  	}
   221  
   222  spec4:	/* NOP */
   223  	nonnon
   224  |	nonrem
   225  
   226  spec5:	/* SHL/SHR */
   227  	rim ',' rem
   228  	{
   229  		$$.from = $1;
   230  		$$.to = $3;
   231  	}
   232  |	rim ',' rem ':' LLREG
   233  	{
   234  		$$.from = $1;
   235  		$$.to = $3;
   236  		if($$.from.index != D_NONE)
   237  			yyerror("dp shift with lhs index");
   238  		$$.from.index = $5;
   239  	}
   240  
   241  spec6:	/* MOVW/MOVL */
   242  	rim ',' rem
   243  	{
   244  		$$.from = $1;
   245  		$$.to = $3;
   246  	}
   247  |	rim ',' rem ':' LSREG
   248  	{
   249  		$$.from = $1;
   250  		$$.to = $3;
   251  		if($$.to.index != D_NONE)
   252  			yyerror("dp move with lhs index");
   253  		$$.to.index = $5;
   254  	}
   255  
   256  spec7:
   257  	rim ','
   258  	{
   259  		$$.from = $1;
   260  		$$.to = nullgen;
   261  	}
   262  |	rim
   263  	{
   264  		$$.from = $1;
   265  		$$.to = nullgen;
   266  	}
   267  |	rim ',' rem
   268  	{
   269  		$$.from = $1;
   270  		$$.to = $3;
   271  	}
   272  
   273  spec8:	/* CMPPS/CMPPD */
   274  	reg ',' rem ',' con
   275  	{
   276  		$$.from = $1;
   277  		$$.to = $3;
   278  		$$.to.offset = $5;
   279  	}
   280  
   281  spec9:	/* shufl */
   282  	imm ',' rem ',' reg
   283  	{
   284  		$$.from = $3;
   285  		$$.to = $5;
   286  		if($1.type != D_CONST)
   287  			yyerror("illegal constant");
   288  		$$.to.offset = $1.offset;
   289  	}
   290  
   291  spec10:	/* RET/RETF */
   292  	{
   293  		$$.from = nullgen;
   294  		$$.to = nullgen;
   295  	}
   296  |	imm
   297  	{
   298  		$$.from = $1;
   299  		$$.to = nullgen;
   300  	}
   301  
   302  spec11:	/* GLOBL */
   303  	mem ',' imm
   304  	{
   305  		$$.from = $1;
   306  		$$.to = $3;
   307  	}
   308  |	mem ',' con ',' imm
   309  	{
   310  		$$.from = $1;
   311  		$$.from.scale = $3;
   312  		$$.to = $5;
   313  	}
   314  
   315  spec12:	/* PCDATA */
   316  	rim ',' rim
   317  	{
   318  		if($1.type != D_CONST || $3.type != D_CONST)
   319  			yyerror("arguments to PCDATA must be integer constants");
   320  		$$.from = $1;
   321  		$$.to = $3;
   322  	}
   323  
   324  spec13:	/* FUNCDATA */
   325  	rim ',' rim
   326  	{
   327  		if($1.type != D_CONST)
   328  			yyerror("index for FUNCDATA must be integer constant");
   329  		if($3.type != D_EXTERN && $3.type != D_STATIC)
   330  			yyerror("value for FUNCDATA must be symbol reference");
   331  		$$.from = $1;
   332  		$$.to = $3;
   333  	}
   334  
   335  rem:
   336  	reg
   337  |	mem
   338  
   339  rom:
   340  	rel
   341  |	nmem
   342  |	'*' reg
   343  	{
   344  		$$ = $2;
   345  	}
   346  |	'*' omem
   347  	{
   348  		$$ = $2;
   349  	}
   350  |	reg
   351  |	omem
   352  
   353  rim:
   354  	rem
   355  |	imm
   356  
   357  rel:
   358  	con '(' LPC ')'
   359  	{
   360  		$$ = nullgen;
   361  		$$.type = D_BRANCH;
   362  		$$.offset = $1 + pc;
   363  	}
   364  |	LNAME offset
   365  	{
   366  		$$ = nullgen;
   367  		if(pass == 2)
   368  			yyerror("undefined label: %s", $1->name);
   369  		$$.type = D_BRANCH;
   370  		$$.sym = $1;
   371  		$$.offset = $2;
   372  	}
   373  |	LLAB offset
   374  	{
   375  		$$ = nullgen;
   376  		$$.type = D_BRANCH;
   377  		$$.sym = $1;
   378  		$$.offset = $1->value + $2;
   379  	}
   380  
   381  reg:
   382  	LBREG
   383  	{
   384  		$$ = nullgen;
   385  		$$.type = $1;
   386  	}
   387  |	LFREG
   388  	{
   389  		$$ = nullgen;
   390  		$$.type = $1;
   391  	}
   392  |	LLREG
   393  	{
   394  		$$ = nullgen;
   395  		$$.type = $1;
   396  	}
   397  |	LMREG
   398  	{
   399  		$$ = nullgen;
   400  		$$.type = $1;
   401  	}
   402  |	LSP
   403  	{
   404  		$$ = nullgen;
   405  		$$.type = D_SP;
   406  	}
   407  |	LSREG
   408  	{
   409  		$$ = nullgen;
   410  		$$.type = $1;
   411  	}
   412  |	LXREG
   413  	{
   414  		$$ = nullgen;
   415  		$$.type = $1;
   416  	}
   417  imm2:
   418  	'$' con2
   419  	{
   420  		$$ = nullgen;
   421  		$$.type = D_CONST;
   422  		$$.offset = $2;
   423  	}
   424  
   425  imm:
   426  	'$' con
   427  	{
   428  		$$ = nullgen;
   429  		$$.type = D_CONST;
   430  		$$.offset = $2;
   431  	}
   432  |	'$' nam
   433  	{
   434  		$$ = $2;
   435  		$$.index = $2.type;
   436  		$$.type = D_ADDR;
   437  		/*
   438  		if($2.type == D_AUTO || $2.type == D_PARAM)
   439  			yyerror("constant cannot be automatic: %s",
   440  				$2.sym->name);
   441  		 */
   442  	}
   443  |	'$' LSCONST
   444  	{
   445  		$$ = nullgen;
   446  		$$.type = D_SCONST;
   447  		memcpy($$.sval, $2, sizeof($$.sval));
   448  	}
   449  |	'$' LFCONST
   450  	{
   451  		$$ = nullgen;
   452  		$$.type = D_FCONST;
   453  		$$.dval = $2;
   454  	}
   455  |	'$' '(' LFCONST ')'
   456  	{
   457  		$$ = nullgen;
   458  		$$.type = D_FCONST;
   459  		$$.dval = $3;
   460  	}
   461  |	'$' '(' '-' LFCONST ')'
   462  	{
   463  		$$ = nullgen;
   464  		$$.type = D_FCONST;
   465  		$$.dval = -$4;
   466  	}
   467  |	'$' '-' LFCONST
   468  	{
   469  		$$ = nullgen;
   470  		$$.type = D_FCONST;
   471  		$$.dval = -$3;
   472  	}
   473  
   474  mem:
   475  	omem
   476  |	nmem
   477  
   478  omem:
   479  	con
   480  	{
   481  		$$ = nullgen;
   482  		$$.type = D_INDIR+D_NONE;
   483  		$$.offset = $1;
   484  	}
   485  |	con '(' LLREG ')'
   486  	{
   487  		$$ = nullgen;
   488  		$$.type = D_INDIR+$3;
   489  		$$.offset = $1;
   490  	}
   491  |	con '(' LSP ')'
   492  	{
   493  		$$ = nullgen;
   494  		$$.type = D_INDIR+D_SP;
   495  		$$.offset = $1;
   496  	}
   497  |	con '(' LSREG ')'
   498  	{
   499  		$$ = nullgen;
   500  		$$.type = D_INDIR+$3;
   501  		$$.offset = $1;
   502  	}
   503  |	con '(' LLREG '*' con ')'
   504  	{
   505  		$$ = nullgen;
   506  		$$.type = D_INDIR+D_NONE;
   507  		$$.offset = $1;
   508  		$$.index = $3;
   509  		$$.scale = $5;
   510  		checkscale($$.scale);
   511  	}
   512  |	con '(' LLREG ')' '(' LLREG '*' con ')'
   513  	{
   514  		$$ = nullgen;
   515  		$$.type = D_INDIR+$3;
   516  		$$.offset = $1;
   517  		$$.index = $6;
   518  		$$.scale = $8;
   519  		checkscale($$.scale);
   520  	}
   521  |	con '(' LLREG ')' '(' LSREG '*' con ')'
   522  	{
   523  		$$ = nullgen;
   524  		$$.type = D_INDIR+$3;
   525  		$$.offset = $1;
   526  		$$.index = $6;
   527  		$$.scale = $8;
   528  		checkscale($$.scale);
   529  	}
   530  |	'(' LLREG ')'
   531  	{
   532  		$$ = nullgen;
   533  		$$.type = D_INDIR+$2;
   534  	}
   535  |	'(' LSP ')'
   536  	{
   537  		$$ = nullgen;
   538  		$$.type = D_INDIR+D_SP;
   539  	}
   540  |	'(' LLREG '*' con ')'
   541  	{
   542  		$$ = nullgen;
   543  		$$.type = D_INDIR+D_NONE;
   544  		$$.index = $2;
   545  		$$.scale = $4;
   546  		checkscale($$.scale);
   547  	}
   548  |	'(' LLREG ')' '(' LLREG '*' con ')'
   549  	{
   550  		$$ = nullgen;
   551  		$$.type = D_INDIR+$2;
   552  		$$.index = $5;
   553  		$$.scale = $7;
   554  		checkscale($$.scale);
   555  	}
   556  
   557  nmem:
   558  	nam
   559  	{
   560  		$$ = $1;
   561  	}
   562  |	nam '(' LLREG '*' con ')'
   563  	{
   564  		$$ = $1;
   565  		$$.index = $3;
   566  		$$.scale = $5;
   567  		checkscale($$.scale);
   568  	}
   569  
   570  nam:
   571  	LNAME offset '(' pointer ')'
   572  	{
   573  		$$ = nullgen;
   574  		$$.type = $4;
   575  		$$.sym = $1;
   576  		$$.offset = $2;
   577  	}
   578  |	LNAME '<' '>' offset '(' LSB ')'
   579  	{
   580  		$$ = nullgen;
   581  		$$.type = D_STATIC;
   582  		$$.sym = $1;
   583  		$$.offset = $4;
   584  	}
   585  
   586  offset:
   587  	{
   588  		$$ = 0;
   589  	}
   590  |	'+' con
   591  	{
   592  		$$ = $2;
   593  	}
   594  |	'-' con
   595  	{
   596  		$$ = -$2;
   597  	}
   598  
   599  pointer:
   600  	LSB
   601  |	LSP
   602  	{
   603  		$$ = D_AUTO;
   604  	}
   605  |	LFP
   606  
   607  con:
   608  	LCONST
   609  |	LVAR
   610  	{
   611  		$$ = $1->value;
   612  	}
   613  |	'-' con
   614  	{
   615  		$$ = -$2;
   616  	}
   617  |	'+' con
   618  	{
   619  		$$ = $2;
   620  	}
   621  |	'~' con
   622  	{
   623  		$$ = ~$2;
   624  	}
   625  |	'(' expr ')'
   626  	{
   627  		$$ = $2;
   628  	}
   629  
   630  con2:
   631  	LCONST
   632  	{
   633  		$$ = ($1 & 0xffffffffLL) +
   634  			((vlong)ArgsSizeUnknown << 32);
   635  	}
   636  |	'-' LCONST
   637  	{
   638  		$$ = (-$2 & 0xffffffffLL) +
   639  			((vlong)ArgsSizeUnknown << 32);
   640  	}
   641  |	LCONST '-' LCONST
   642  	{
   643  		$$ = ($1 & 0xffffffffLL) +
   644  			(($3 & 0xffffLL) << 32);
   645  	}
   646  |	'-' LCONST '-' LCONST
   647  	{
   648  		$$ = (-$2 & 0xffffffffLL) +
   649  			(($4 & 0xffffLL) << 32);
   650  	}
   651  
   652  expr:
   653  	con
   654  |	expr '+' expr
   655  	{
   656  		$$ = $1 + $3;
   657  	}
   658  |	expr '-' expr
   659  	{
   660  		$$ = $1 - $3;
   661  	}
   662  |	expr '*' expr
   663  	{
   664  		$$ = $1 * $3;
   665  	}
   666  |	expr '/' expr
   667  	{
   668  		$$ = $1 / $3;
   669  	}
   670  |	expr '%' expr
   671  	{
   672  		$$ = $1 % $3;
   673  	}
   674  |	expr '<' '<' expr
   675  	{
   676  		$$ = $1 << $4;
   677  	}
   678  |	expr '>' '>' expr
   679  	{
   680  		$$ = $1 >> $4;
   681  	}
   682  |	expr '&' expr
   683  	{
   684  		$$ = $1 & $3;
   685  	}
   686  |	expr '^' expr
   687  	{
   688  		$$ = $1 ^ $3;
   689  	}
   690  |	expr '|' expr
   691  	{
   692  		$$ = $1 | $3;
   693  	}