github.com/aleksi/cc@v0.0.0-20171021204506-4b6ffb9b7827/parser.yy (about)

     1  %{
     2  // Copyright 2016 The CC Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  // Based on [0], 6.10. Substantial portions of expression AST size
     7  // optimizations are from [2], license of which follows.
     8  
     9  // ----------------------------------------------------------------------------
    10  
    11  // Copyright 2013 The Go Authors.  All rights reserved.
    12  // Use of this source code is governed by a BSD-style
    13  // license that can be found in the LICENSE file.
    14  
    15  // This grammar is derived from the C grammar in the 'ansitize'
    16  // program, which carried this notice:
    17  // 
    18  // Copyright (c) 2006 Russ Cox, 
    19  // 	Massachusetts Institute of Technology
    20  // 
    21  // Permission is hereby granted, free of charge, to any person
    22  // obtaining a copy of this software and associated
    23  // documentation files (the "Software"), to deal in the
    24  // Software without restriction, including without limitation
    25  // the rights to use, copy, modify, merge, publish, distribute,
    26  // sublicense, and/or sell copies of the Software, and to
    27  // permit persons to whom the Software is furnished to do so,
    28  // subject to the following conditions:
    29  // 
    30  // The above copyright notice and this permission notice shall
    31  // be included in all copies or substantial portions of the
    32  // Software.
    33  // 
    34  // The software is provided "as is", without warranty of any
    35  // kind, express or implied, including but not limited to the
    36  // warranties of merchantability, fitness for a particular
    37  // purpose and noninfringement.  In no event shall the authors
    38  // or copyright holders be liable for any claim, damages or
    39  // other liability, whether in an action of contract, tort or
    40  // otherwise, arising from, out of or in connection with the
    41  // software or the use or other dealings in the software.
    42  
    43  package cc
    44  
    45  import (
    46  	"fmt"
    47  
    48  	"github.com/cznic/xc"
    49  	"github.com/cznic/golex/lex"
    50  )
    51  %}
    52  
    53  %union {
    54  	Token			xc.Token
    55  	groupPart		Node
    56  	node			Node
    57  	toks			PPTokenList
    58  }
    59  
    60  %token
    61  	/*yy:token "'%c'"            */ CHARCONST		"character constant"
    62  	/*yy:token "1.%d"            */ FLOATCONST		"floating-point constant"
    63  	/*yy:token "%c"              */ IDENTIFIER		"identifier"
    64  	/*yy:token "%c"              */ IDENTIFIER_NONREPL	"non replaceable identifier"
    65  	/*yy:token "%c("             */ IDENTIFIER_LPAREN	"identifier immediatelly followed by '('"
    66  	/*yy:token "%d"              */ INTCONST		"integer constant"
    67  	/*yy:token "L'%c'"           */ LONGCHARCONST		"long character constant"
    68  	/*yy:token "L\"%c\""         */ LONGSTRINGLITERAL	"long string constant"
    69  	/*yy:token "<%c.h>"          */ PPHEADER_NAME		"header name"
    70  	/*yy:token "%d"              */ PPNUMBER		"preprocessing number"
    71  	/*yy:token "\"%c\""          */ STRINGLITERAL		"string literal"
    72  
    73  	/*yy:token "\U00100000"      */	PREPROCESSING_FILE	1048576	"preprocessing file prefix"	// 0x100000 = 1048576
    74  	/*yy:token "\U00100001"      */	CONSTANT_EXPRESSION	1048577	"constant expression prefix"
    75  	/*yy:token "\U00100002"      */	TRANSLATION_UNIT	1048578	"translation unit prefix"
    76  
    77  	/*yy:token "\n#define"       */	PPDEFINE		"#define"
    78  	/*yy:token "\n#elif"         */	PPELIF			"#elif"
    79  	/*yy:token "\n#else"         */	PPELSE			"#else"
    80  	/*yy:token "\n#endif"        */	PPENDIF			"#endif"
    81  	/*yy:token "\n#error"        */	PPERROR			"#error"
    82  	/*yy:token "\n#"             */	PPHASH_NL		"#"
    83  	/*yy:token "\n#if"           */	PPIF			"#if"
    84  	/*yy:token "\n#ifdef"        */	PPIFDEF			"#ifdef"
    85  	/*yy:token "\n#ifndef"       */	PPIFNDEF		"#ifndef"
    86  	/*yy:token "\n#include"      */	PPINCLUDE		"#include"
    87  	/*yy:token "\n#include_next" */	PPINCLUDE_NEXT		"#include_next"
    88  	/*yy:token "\n#line"         */	PPLINE			"#line"
    89  	/*yy:token "\n#foo"          */	PPNONDIRECTIVE		"#foo"
    90  	/*yy:token "other_%c"        */ PPOTHER			"ppother"
    91  	/*yy:token "\n##"            */	PPPASTE			"##"
    92  	/*yy:token "\n#pragma"       */	PPPRAGMA		"#pragma"
    93  	/*yy:token "\n#undef"        */	PPUNDEF			"#undef"
    94  
    95  	ADDASSIGN			"+="
    96  	ALIGNOF				"_Alignof"
    97  	ANDAND				"&&"
    98  	ANDASSIGN			"&="
    99  	ARROW				"->"
   100  	ASM				"asm"
   101  	AUTO				"auto"
   102  	BOOL				"_Bool"
   103  	BREAK				"break"
   104  	CASE				"case"
   105  	CHAR				"char"
   106  	COMPLEX				"_Complex"
   107  	CONST				"const"
   108  	CONTINUE			"continue"
   109  	DDD				"..."
   110  	DEC				"--"
   111  	DEFAULT				"default"
   112  	DIVASSIGN			"/="
   113  	DO				"do"
   114  	DOUBLE				"double"
   115  	ELSE				"else"
   116  	ENUM				"enum"
   117  	EQ				"=="
   118  	EXTERN				"extern"
   119  	FLOAT				"float"
   120  	FOR				"for"
   121  	GEQ				">="
   122  	GOTO				"goto"
   123  	IF				"if"
   124  	INC				"++"
   125  	INLINE				"inline"
   126  	INT				"int"
   127  	LEQ				"<="
   128  	LONG				"long"
   129  	LSH				"<<"
   130  	LSHASSIGN			"<<="
   131  	MODASSIGN			"%="
   132  	MULASSIGN			"*="
   133  	NEQ				"!="
   134  	NORETURN			"_Noreturn"
   135  	ORASSIGN			"|="
   136  	OROR				"||"
   137  	REGISTER			"register"
   138  	RESTRICT			"restrict"
   139  	RETURN				"return"
   140  	RSH				">>"
   141  	RSHASSIGN			">>="
   142  	SHORT				"short"
   143  	SIGNED				"signed"
   144  	SIZEOF				"sizeof"
   145  	STATIC				"static"
   146  	STATIC_ASSERT			"_Static_assert"
   147  	STRUCT				"struct"
   148  	SUBASSIGN			"-="
   149  	SWITCH				"switch"
   150  	TYPEDEF				"typedef"
   151  	TYPEDEFNAME			"typedefname"
   152  	TYPEOF				"typeof"
   153  	UNION				"union"
   154  	UNSIGNED			"unsigned"
   155  	VOID				"void"
   156  	VOLATILE			"volatile"
   157  	WHILE				"while"
   158  	XORASSIGN			"^="
   159  
   160  %type	<toks>
   161  	PPTokenList			"token list"
   162  	PPTokenListOpt			"optional token list"
   163  	ReplacementList			"replacement list"
   164  	TextLine			"text line"
   165  
   166  %type	<groupPart>
   167  	GroupPart			"group part"
   168  
   169  %type	<node>
   170  	AbstractDeclarator		"abstract declarator"
   171  	AbstractDeclaratorOpt		"optional abstract declarator"
   172  	ArgumentExpressionList		"argument expression list"
   173  	ArgumentExpressionListOpt	"optional argument expression list"
   174  	AssemblerInstructions		"assembler instructions"
   175  	AssemblerOperand		"assembler operand"
   176  	AssemblerOperands		"assembler operands"
   177  	AssemblerStatement		"assembler statement"
   178  	AssemblerSymbolicNameOpt	"optional assembler symbolic name"
   179  	BasicAssemblerStatement		"basic assembler statement"
   180  	BlockItem			"block item"
   181  	BlockItemList			"block item list"
   182  	BlockItemListOpt		"optional block item list"
   183  	Clobbers			"clobbers"
   184  	CommaOpt			"optional comma"
   185  	CompoundStatement		"compound statement"
   186  	ConstantExpression		"constant expression"
   187  	ControlLine			"control line"
   188  	Declaration			"declaration"
   189  	DeclarationList			"declaration list"
   190  	DeclarationListOpt		"optional declaration list"
   191  	DeclarationSpecifiers		"declaration specifiers"
   192  	DeclarationSpecifiersOpt	"optional declaration specifiers"
   193  	Declarator			"declarator"
   194  	DeclaratorOpt			"optional declarator"
   195  	Designation			"designation"
   196  	DesignationOpt			"optional designation"
   197  	Designator			"designator"
   198  	DesignatorList			"designator list"
   199  	DirectAbstractDeclarator	"direct abstract declarator"
   200  	DirectAbstractDeclaratorOpt	"optional direct abstract declarator"
   201  	DirectDeclarator		"direct declarator"
   202  	ElifGroup			"elif group"
   203  	ElifGroupList			"elif group list"
   204  	ElifGroupListOpt		"optional elif group list"
   205  	ElseGroup			"else group"
   206  	ElseGroupOpt			"optional else group"
   207  	EndifLine			"endif line"
   208  	EnumSpecifier			"enum specifier"
   209  	EnumerationConstant		"enumearation constant"
   210  	Enumerator			"enumerator"
   211  	EnumeratorList			"enumerator list"
   212  	Expression			"expression"
   213  	ExpressionList			"expression list"
   214  	ExpressionListOpt		"optional expression list"
   215  	ExpressionOpt			"optional expression"
   216  	ExpressionStatement		"expression statement"
   217  	ExternalDeclaration		"external declaration"
   218  	FunctionDefinition		"function definition"
   219  	FunctionBody			"function body"
   220  	FunctionSpecifier		"function specifier"
   221  	GroupList			"group list"
   222  	GroupListOpt			"optional group list"
   223  	IdentifierList			"identifier list"
   224  	IdentifierListOpt		"optional identifier list"
   225  	IdentifierOpt			"optional identifier"
   226  	IfGroup				"if group"
   227  	IfSection			"if section"
   228  	InitDeclarator			"init declarator"
   229  	InitDeclaratorList		"init declarator list"
   230  	InitDeclaratorListOpt		"optional init declarator list"
   231  	Initializer			"initializer"
   232  	InitializerList			"initializer list"
   233  	IterationStatement		"iteration statement"
   234  	JumpStatement			"jump statement"
   235  	LabeledStatement		"labeled statement"
   236  	ParameterDeclaration		"parameter declaration"
   237  	ParameterList			"parameter list"
   238  	ParameterTypeList		"parameter type list"
   239  	ParameterTypeListOpt		"optional parameter type list"
   240  	Pointer				"pointer"
   241  	PointerOpt			"optional pointer"
   242  	PreprocessingFile		"preprocessing file"
   243  	SelectionStatement		"selection statement"
   244  	SpecifierQualifierList		"specifier qualifier list"
   245  	SpecifierQualifierListOpt	"optional specifier qualifier list"
   246  	Statement			"statement"
   247  	StaticAssertDeclaration		"static assert declaration"
   248  	StorageClassSpecifier		"storage class specifier"
   249  	StructDeclaration		"struct declaration"
   250  	StructDeclarationList		"struct declaration list"
   251  	StructDeclarator		"struct declarator"
   252  	StructDeclaratorList		"struct declarator list"
   253  	StructOrUnion			"struct-or-union"
   254  	StructOrUnionSpecifier		"struct-or-union specifier"
   255  	TranslationUnit			"translation unit"
   256  	TypeName			"type name"
   257  	TypeQualifier			"type qualifier"
   258  	TypeQualifierList		"type qualifier list"
   259  	TypeQualifierListOpt		"optional type qualifier list"
   260  	TypeSpecifier			"type specifier"
   261  	VolatileOpt			"optional volatile"
   262  
   263  
   264  %precedence	NOSEMI
   265  %precedence	';'
   266  
   267  %precedence	NOELSE
   268  %precedence	ELSE
   269  
   270  %right		'=' ADDASSIGN ANDASSIGN DIVASSIGN LSHASSIGN MODASSIGN MULASSIGN
   271  		ORASSIGN RSHASSIGN SUBASSIGN XORASSIGN
   272  		
   273  %right		':' '?'
   274  %left		OROR
   275  %left		ANDAND
   276  %left		'|'
   277  %left		'^'
   278  %left		'&'
   279  %left		EQ NEQ
   280  %left		'<' '>' GEQ LEQ
   281  %left		LSH RSH
   282  %left		'+' '-' 
   283  %left		'%' '*' '/'
   284  %precedence	CAST
   285  %left		'!' '~' SIZEOF UNARY
   286  %right		'(' '.' '[' ARROW DEC INC
   287  
   288  %%
   289  
   290  //yy:ignore
   291  Start:
   292  	PREPROCESSING_FILE
   293  	{
   294  		lx.preprocessingFile = nil
   295  	}
   296  	PreprocessingFile
   297  	{
   298  		lx.preprocessingFile = $3.(*PreprocessingFile)
   299  	}
   300  |	CONSTANT_EXPRESSION
   301  	{
   302  		lx.constantExpression = nil
   303  	}
   304  	ConstantExpression
   305  	{
   306  		lx.constantExpression = $3.(*ConstantExpression)
   307  	}
   308  |	TRANSLATION_UNIT
   309  	{
   310  		lx.translationUnit = nil
   311  	}
   312  	TranslationUnit
   313  	{
   314  		if lx.report.Errors(false) == nil && lx.scope.kind != ScopeFile {
   315  			panic("internal error")
   316  		}
   317  
   318  		lx.translationUnit = $3.(*TranslationUnit).reverse()
   319  		lx.translationUnit.Declarations = lx.scope
   320  	}
   321  
   322  // [0](6.4.4.3)
   323  EnumerationConstant:
   324  	IDENTIFIER
   325  
   326  // [0](6.5.2)
   327  ArgumentExpressionList:
   328  	Expression
   329  |	ArgumentExpressionList ',' Expression
   330  
   331  ArgumentExpressionListOpt:
   332  	/* empty */ {}
   333  |	ArgumentExpressionList
   334  
   335  // [0](6.5.16)
   336  //yy:field	BinOpType	Type		// The type operands of binary expression are coerced into, if different from Type.
   337  //yy:field	Type		Type		// Type of expression.
   338  //yy:field	Value		interface{}	// Non nil for certain constant expressions.
   339  //yy:field	scope		*Bindings	// Case 0: IDENTIFIER resolution scope.
   340  Expression:
   341  	IDENTIFIER %prec NOSEMI
   342  	{
   343  		lhs.scope = lx.scope
   344  	}
   345  |	CHARCONST
   346  |	FLOATCONST
   347  |	INTCONST
   348  |	LONGCHARCONST
   349  |	LONGSTRINGLITERAL
   350  |	STRINGLITERAL
   351  |	'(' ExpressionList ')'
   352  |	Expression '[' ExpressionList ']'
   353  |	Expression '(' ArgumentExpressionListOpt ')'
   354  	{
   355  		o := lhs.ArgumentExpressionListOpt
   356  		if o == nil {
   357  			break
   358  		}
   359  
   360  		if lhs.Expression.Case == 0 { // IDENTIFIER
   361  			if lx.tweaks.enableBuiltinConstantP &&lhs.Expression.Token.Val == idBuiltinConstantP {
   362  				break
   363  			}
   364  
   365  			b := lhs.Expression.scope.Lookup(NSIdentifiers, lhs.Expression.Token.Val)
   366  			if b.Node == nil && lx.tweaks.enableImplicitFuncDef {
   367  				for l := o.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList {
   368  					l.Expression.eval(lx)
   369  				}
   370  				break
   371  			}
   372  		}
   373  
   374  		lhs.Expression.eval(lx)
   375  		for l := o.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList {
   376  			l.Expression.eval(lx)
   377  		}
   378  	}
   379  |	Expression '.' IDENTIFIER
   380  |	Expression "->" IDENTIFIER
   381  |	Expression "++"
   382  |	Expression "--"
   383  |	'(' TypeName ')' '{' InitializerList CommaOpt '}'
   384  |	"++" Expression
   385  |	"--" Expression
   386  |	'&' Expression %prec UNARY
   387  |	'*' Expression %prec UNARY
   388  |	'+' Expression %prec UNARY
   389  |	'-' Expression %prec UNARY
   390  |	'~' Expression
   391  |	'!' Expression
   392  |	"sizeof" Expression
   393  |	"sizeof" '(' TypeName ')' %prec SIZEOF
   394  |	'(' TypeName ')' Expression %prec CAST
   395  |	Expression '*' Expression
   396  |	Expression '/' Expression
   397  |	Expression '%' Expression
   398  |	Expression '+' Expression
   399  |	Expression '-' Expression
   400  |	Expression "<<" Expression
   401  |	Expression ">>" Expression
   402  |	Expression '<' Expression
   403  |	Expression '>' Expression
   404  |	Expression "<=" Expression
   405  |	Expression ">=" Expression
   406  |	Expression "==" Expression
   407  |	Expression "!=" Expression
   408  |	Expression '&' Expression
   409  |	Expression '^' Expression
   410  |	Expression '|' Expression
   411  |	Expression "&&" Expression
   412  |	Expression "||" Expression
   413  |	Expression '?' ExpressionList ':' Expression
   414  |	Expression '=' Expression
   415  |	Expression "*=" Expression
   416  |	Expression "/=" Expression
   417  |	Expression "%=" Expression
   418  |	Expression "+=" Expression
   419  |	Expression "-=" Expression
   420  |	Expression "<<=" Expression
   421  |	Expression ">>=" Expression
   422  |	Expression "&=" Expression
   423  |	Expression "^=" Expression
   424  |	Expression "|=" Expression
   425  |	"_Alignof" '(' TypeName ')'
   426  |	'(' CompoundStatement ')'
   427  |	"&&" IDENTIFIER
   428  	{
   429  		if !lx.tweaks.enableComputedGotos {
   430  			lx.report.Err(lhs.Pos(), "computed gotos not enabled")
   431  		}
   432  	}
   433  |	Expression '?' ':' Expression
   434  	{
   435  		if !lx.tweaks.enableOmitConditionalOperand {
   436  			lx.report.Err(lhs.Pos(), "omitting conditional operand not enabled")
   437  		}
   438  	}
   439  
   440  
   441  ExpressionOpt:
   442  	/* empty */ {}
   443  |	Expression
   444  	{
   445  		lhs.Expression.eval(lx)
   446  	}
   447  
   448  // [0](6.5.17)
   449  //yy:field	Type	Type		// Type of expression.
   450  //yy:field	Value	interface{}	// Non nil for certain constant expressions.
   451  //yy:list
   452  ExpressionList:
   453  	Expression
   454  |	ExpressionList ',' Expression
   455  
   456  ExpressionListOpt:
   457  	/* empty */ {}
   458  |	ExpressionList
   459  	{
   460  		lhs.ExpressionList.eval(lx)
   461  	}
   462  
   463  // [0](6.6)
   464  //yy:field	Type	Type		// Type of expression.
   465  //yy:field	Value	interface{}	// Non nil for certain constant expressions.
   466  //yy:field	toks	[]xc.Token	//
   467  ConstantExpression:
   468  	{
   469  		lx.constExprToks = []xc.Token{lx.last}
   470  	}
   471  	Expression
   472  	{
   473  		lhs.Value, lhs.Type = lhs.Expression.eval(lx)
   474  		if lhs.Value == nil {
   475  			lx.report.Err(lhs.Pos(), "not a constant expression")
   476  		}
   477  		l := lx.constExprToks
   478  		lhs.toks = l[:len(l)-1]
   479  		lx.constExprToks = nil
   480  	}
   481  
   482  // [0](6.7)
   483  //yy:field	declarator	*Declarator	// Synthetic declarator when InitDeclaratorListOpt is nil.
   484  Declaration:
   485  	DeclarationSpecifiers InitDeclaratorListOpt ';'
   486  	{
   487  		ts0 := lhs.DeclarationSpecifiers.typeSpecifiers()
   488  		if ts0 == 0 && lx.tweaks.enableImplicitIntType {
   489  			lhs.DeclarationSpecifiers.typeSpecifier = tsEncode(tsInt)
   490  		}
   491  		ts := tsDecode(lhs.DeclarationSpecifiers.typeSpecifiers())
   492  		ok := false
   493  		for _, v := range ts {
   494  			if v == tsStructSpecifier || v == tsUnionSpecifier {
   495  				ok = true
   496  				break
   497  			}
   498  		}
   499  		if ok {
   500  			s := lhs.DeclarationSpecifiers
   501  			d := &Declarator{specifier: s}
   502  			dd := &DirectDeclarator{
   503  				Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)},
   504  				declarator: d,
   505  				idScope: lx.scope,
   506  				specifier: s,
   507  			}
   508  			d.DirectDeclarator = dd
   509  			d.setFull(lx)
   510  			for l := lhs.DeclarationSpecifiers; l != nil; {
   511  				ts := l.TypeSpecifier
   512  				if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}'
   513  					ts.StructOrUnionSpecifier.declarator = d
   514  					break
   515  				}
   516  
   517  				if o := l.DeclarationSpecifiersOpt; o != nil {
   518  					l = o.DeclarationSpecifiers
   519  					continue
   520  				}
   521  
   522  				break
   523  			}
   524  		}
   525  
   526  		o := lhs.InitDeclaratorListOpt
   527  		if o != nil {
   528  			break
   529  		}
   530  
   531  		s := lhs.DeclarationSpecifiers
   532  		d := &Declarator{specifier: s}
   533  		dd := &DirectDeclarator{
   534  			Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)},
   535  			declarator: d,
   536  			idScope: lx.scope,
   537  			specifier: s,
   538  		}
   539  		d.DirectDeclarator = dd
   540  		d.setFull(lx)
   541  		lhs.declarator = d
   542  	}
   543  |	StaticAssertDeclaration
   544  
   545  // [0](6.7)
   546  //yy:field	attr		int	// tsInline, tsTypedefName, ...
   547  //yy:field	typeSpecifier	int	// Encoded combination of tsVoid, tsInt, ...
   548  DeclarationSpecifiers:
   549  	StorageClassSpecifier DeclarationSpecifiersOpt
   550  	{
   551  		lx.scope.specifier = lhs
   552  		a := lhs.StorageClassSpecifier
   553  		b := lhs.DeclarationSpecifiersOpt
   554  		if b == nil {
   555  			lhs.attr = a.attr
   556  			break
   557  		}
   558  
   559  		if a.attr&b.attr != 0 {
   560  			lx.report.Err(a.Pos(), "invalid storage class specifier")
   561  			break
   562  		}
   563  
   564  		lhs.attr = a.attr|b.attr
   565  		lhs.typeSpecifier = b.typeSpecifier
   566  		if lhs.StorageClassSpecifier.Case != 0 /* "typedef" */ && lhs.IsTypedef() {
   567  			lx.report.Err(a.Pos(), "invalid storage class specifier")
   568  		}
   569  	}
   570  |	TypeSpecifier DeclarationSpecifiersOpt
   571  	{
   572  		lx.scope.specifier = lhs
   573  		a := lhs.TypeSpecifier
   574  		b := lhs.DeclarationSpecifiersOpt
   575  		if b == nil {
   576  			lhs.typeSpecifier = a.typeSpecifier
   577  			break
   578  		}
   579  
   580  		lhs.attr = b.attr
   581  		tsb := tsDecode(b.typeSpecifier)
   582  		if len(tsb) == 1 && tsb[0] == tsTypedefName && lx.tweaks.allowCompatibleTypedefRedefinitions {
   583  			tsb[0] = 0
   584  		}
   585  		ts := tsEncode(append(tsDecode(a.typeSpecifier), tsb...)...)
   586  		if _, ok := tsValid[ts]; !ok {
   587  			ts = tsEncode(tsInt)
   588  			lx.report.Err(a.Pos(), "invalid type specifier")
   589  		}
   590  		lhs.typeSpecifier = ts
   591  	}
   592  |	TypeQualifier DeclarationSpecifiersOpt
   593  	{
   594  		lx.scope.specifier = lhs
   595  		a := lhs.TypeQualifier
   596  		b := lhs.DeclarationSpecifiersOpt
   597  		if b == nil {
   598  			lhs.attr = a.attr
   599  			break
   600  		}
   601  	
   602  		if a.attr&b.attr != 0 {
   603  			lx.report.Err(a.Pos(), "invalid type qualifier")
   604  			break
   605  		}
   606  
   607  		lhs.attr = a.attr|b.attr
   608  		lhs.typeSpecifier = b.typeSpecifier
   609  		if lhs.IsTypedef() {
   610  			lx.report.Err(a.Pos(), "invalid type qualifier")
   611  		}
   612  	}
   613  |	FunctionSpecifier DeclarationSpecifiersOpt
   614  	{
   615  		lx.scope.specifier = lhs
   616  		a := lhs.FunctionSpecifier
   617  		b := lhs.DeclarationSpecifiersOpt
   618  		if b == nil {
   619  			lhs.attr = a.attr
   620  			break
   621  		}
   622  	
   623  		if a.attr&b.attr != 0 {
   624  			lx.report.Err(a.Pos(), "invalid function specifier")
   625  			break
   626  		}
   627  
   628  		lhs.attr = a.attr|b.attr
   629  		lhs.typeSpecifier = b.typeSpecifier
   630  		if lhs.IsTypedef() {
   631  			lx.report.Err(a.Pos(), "invalid function specifier")
   632  		}
   633  	}
   634  
   635  //yy:field	attr		int	// tsInline, tsTypedefName, ...
   636  //yy:field	typeSpecifier	int	// Encoded combination of tsVoid, tsInt, ...
   637  DeclarationSpecifiersOpt:
   638  	/* empty */ {}
   639  |	DeclarationSpecifiers
   640  	{
   641  		lhs.attr = lhs.DeclarationSpecifiers.attr
   642  		lhs.typeSpecifier = lhs.DeclarationSpecifiers.typeSpecifier
   643  	}
   644  
   645  // [0](6.7)
   646  InitDeclaratorList:
   647  	InitDeclarator
   648  |	InitDeclaratorList ',' InitDeclarator
   649  
   650  InitDeclaratorListOpt:
   651  	/* empty */ {}
   652  |	InitDeclaratorList
   653  
   654  // [0](6.7)
   655  InitDeclarator:
   656  	Declarator
   657  	{
   658  		lhs.Declarator.setFull(lx)
   659  	}
   660  |	Declarator
   661  	{
   662  		d := $1.(*Declarator)
   663  		d.setFull(lx)
   664  	}
   665  	'=' Initializer
   666  	{
   667  		d := lhs.Declarator
   668  		lhs.Initializer.typeCheck(&d.Type, d.Type, lhs.Declarator.specifier.IsStatic(), lx)
   669  		if d.Type.Specifier().IsExtern() {
   670  			id, _ := d.Identifier()
   671  			lx.report.Err(d.Pos(), "'%s' initialized and declared 'extern'", dict.S(id))
   672  		}
   673  	}
   674  
   675  // [0](6.7.1)
   676  //yy:field	attr	int
   677  StorageClassSpecifier:
   678  	"typedef"
   679  	{
   680  		lhs.attr = saTypedef
   681  	}
   682  |	"extern"
   683  	{
   684  		lhs.attr = saExtern
   685  	}
   686  |	"static"
   687  	{
   688  		lhs.attr = saStatic
   689  	}
   690  |	"auto"
   691  	{
   692  		lhs.attr = saAuto
   693  	}
   694  |	"register"
   695  	{
   696  		lhs.attr = saRegister
   697  	}
   698  
   699  // [0](6.7.2)
   700  //yy:field	scope		*Bindings	// If case TYPEDEFNAME.
   701  //yy:field	typeSpecifier	int		// Encoded combination of tsVoid, tsInt, ...
   702  //yy:field	Type		Type		// Type of typeof.
   703  TypeSpecifier:
   704  	"void"
   705  	{
   706  		lhs.typeSpecifier = tsEncode(tsVoid)
   707  	}
   708  |	"char"
   709  	{
   710  		lhs.typeSpecifier = tsEncode(tsChar)
   711  	}
   712  |	"short"
   713  	{
   714  		lhs.typeSpecifier = tsEncode(tsShort)
   715  	}
   716  |	"int"
   717  	{
   718  		lhs.typeSpecifier = tsEncode(tsInt)
   719  	}
   720  |	"long"
   721  	{
   722  		lhs.typeSpecifier = tsEncode(tsLong)
   723  	}
   724  |	"float"
   725  	{
   726  		lhs.typeSpecifier = tsEncode(tsFloat)
   727  	}
   728  |	"double"
   729  	{
   730  		lhs.typeSpecifier = tsEncode(tsDouble)
   731  	}
   732  |	"signed"
   733  	{
   734  		lhs.typeSpecifier = tsEncode(tsSigned)
   735  	}
   736  |	"unsigned"
   737  	{
   738  		lhs.typeSpecifier = tsEncode(tsUnsigned)
   739  	}
   740  |	"_Bool"
   741  	{
   742  		lhs.typeSpecifier = tsEncode(tsBool)
   743  	}
   744  |	"_Complex"
   745  	{
   746  		lhs.typeSpecifier = tsEncode(tsComplex)
   747  	}
   748  |	StructOrUnionSpecifier
   749  	{
   750  		lhs.typeSpecifier = tsEncode(lhs.StructOrUnionSpecifier.typeSpecifiers())
   751  	}
   752  |	EnumSpecifier
   753  	{
   754  		lhs.typeSpecifier = tsEncode(tsEnumSpecifier)
   755  	}
   756  /*yy:example "\U00100002 typedef int i; i j;" */
   757  |	TYPEDEFNAME
   758  	{
   759  		lhs.typeSpecifier = tsEncode(tsTypedefName)
   760  		_, lhs.scope = lx.scope.Lookup2(NSIdentifiers, lhs.Token.Val)
   761  	}
   762  |	"typeof" '(' Expression ')'
   763  	{
   764  		lhs.typeSpecifier = tsEncode(tsTypeof)
   765  		_, lhs.Type = lhs.Expression.eval(lx)
   766  	}
   767  |	"typeof" '(' TypeName ')'
   768  	{
   769  		lhs.typeSpecifier = tsEncode(tsTypeof)
   770  		lhs.Type = undefined
   771  		if t := lhs.TypeName.Type; t != nil {
   772  			lhs.Type = t
   773  		}
   774  	}
   775  
   776  // [0](6.7.2.1)
   777  //yy:example	"\U00100002 struct { int i; } ("
   778  //yy:field	alignOf	int
   779  //yy:field	declarator	*Declarator	// Synthetic declarator when tagged struct/union defined inline.
   780  //yy:field	scope		*Bindings
   781  //yy:field	sizeOf		int
   782  StructOrUnionSpecifier:
   783  	StructOrUnion IdentifierOpt
   784  	'{'
   785  	{
   786  		if o := $2.(*IdentifierOpt); o != nil {
   787  			lx.scope.declareStructTag(o.Token, lx.report)
   788  		}
   789  		lx.pushScope(ScopeMembers)
   790  		lx.scope.isUnion = $1.(*StructOrUnion).Case == 1 // "union"
   791  		lx.scope.prevStructDeclarator = nil
   792  	}
   793  	StructDeclarationList '}'
   794  	{
   795  		sc := lx.scope
   796  		lhs.scope = sc
   797  		if sc.bitOffset != 0 {
   798  			finishBitField(lhs, lx)
   799  		}
   800  
   801  		i := 0
   802  		var bt Type
   803  		var d *Declarator
   804  		for l := lhs.StructDeclarationList; l != nil; l = l.StructDeclarationList {
   805  			for l := l.StructDeclaration.StructDeclaratorList; l != nil; l = l.StructDeclaratorList {
   806  				switch sd := l.StructDeclarator; sd.Case {
   807  				case 0: // Declarator
   808  					d = sd.Declarator
   809  				case 1: // DeclaratorOpt ':' ConstantExpression
   810  					if o := sd.DeclaratorOpt; o != nil {
   811  						x := o.Declarator
   812  						if x.bitOffset == 0  {
   813  							d = x
   814  							bt = lx.scope.bitFieldTypes[i]
   815  							i++
   816  						}
   817  						x.bitFieldType = bt
   818  					}
   819  				}
   820  			}
   821  		}
   822  		lx.scope.bitFieldTypes = nil
   823  
   824  		lhs.alignOf = sc.maxAlign
   825  		switch {
   826  		case sc.isUnion:
   827  			lhs.sizeOf = align(sc.maxSize, sc.maxAlign)
   828  		default:
   829  			off := sc.offset
   830  			lhs.sizeOf = align(sc.offset, sc.maxAlign)
   831  			if d != nil {
   832  				d.padding = lhs.sizeOf-off
   833  			}
   834  		}
   835  
   836  		lx.popScope(lhs.Token2)
   837  		if o := lhs.IdentifierOpt; o != nil {
   838  			lx.scope.defineStructTag(o.Token, lhs, lx.report)
   839  		}
   840  	}
   841  |	StructOrUnion IDENTIFIER
   842  	{
   843  		lx.scope.declareStructTag(lhs.Token, lx.report)
   844  		lhs.scope = lx.scope
   845  	}
   846  |	StructOrUnion IdentifierOpt '{' '}'
   847  	{
   848  		if !lx.tweaks.enableEmptyStructs {
   849  			lx.report.Err(lhs.Token.Pos(), "empty structs/unions not allowed")
   850  		}
   851  		if o := $2.(*IdentifierOpt); o != nil {
   852  			lx.scope.declareStructTag(o.Token, lx.report)
   853  		}
   854  		lx.scope.isUnion = $1.(*StructOrUnion).Case == 1 // "union"
   855  		lx.scope.prevStructDeclarator = nil
   856  		lhs.alignOf = 1
   857  		lhs.sizeOf = 0
   858  		if o := lhs.IdentifierOpt; o != nil {
   859  			lx.scope.defineStructTag(o.Token, lhs, lx.report)
   860  		}
   861  	}
   862  
   863  // [0](6.7.2.1)
   864  StructOrUnion:
   865  	"struct"
   866  |	"union"
   867  
   868  // [0](6.7.2.1)
   869  StructDeclarationList:
   870  	StructDeclaration
   871  |	StructDeclarationList StructDeclaration
   872  
   873  // [0](6.7.2.1)
   874  StructDeclaration:
   875  	SpecifierQualifierList StructDeclaratorList ';'
   876  	{
   877  		s := lhs.SpecifierQualifierList
   878  		if k := s.kind(); k != Struct && k != Union {
   879  			break
   880  		}
   881  
   882  		d := &Declarator{specifier: s}
   883  		dd := &DirectDeclarator{
   884  			Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)},
   885  			declarator: d,
   886  			idScope: lx.scope,
   887  			specifier: s,
   888  		}
   889  		d.DirectDeclarator = dd
   890  		d.setFull(lx)
   891  		for l := lhs.SpecifierQualifierList; l != nil; {
   892  			ts := l.TypeSpecifier
   893  			if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}'
   894  				ts.StructOrUnionSpecifier.declarator = d
   895  				break
   896  			}
   897  
   898  			if o := l.SpecifierQualifierListOpt; o != nil {
   899  				l = o.SpecifierQualifierList
   900  				continue
   901  			}
   902  
   903  			break
   904  		}
   905  	}
   906  |	SpecifierQualifierList ';'
   907  	{
   908  		s := lhs.SpecifierQualifierList
   909  		if !lx.tweaks.enableAnonymousStructFields {
   910  			lx.report.Err(lhs.Token.Pos(), "unnamed fields not allowed")
   911  		} else if k := s.kind(); k != Struct && k != Union {
   912  			lx.report.Err(lhs.Token.Pos(), "only unnamed structs and unions are allowed")
   913  			break
   914  		}
   915  
   916  		d := &Declarator{specifier: s}
   917  		dd := &DirectDeclarator{
   918  			Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)},
   919  			declarator: d,
   920  			idScope: lx.scope,
   921  			specifier: s,
   922  		}
   923  		d.DirectDeclarator = dd
   924  		d.setFull(lx)
   925  
   926  		// we have no struct declarators to parse, so we have to create the case of one implicit declarator
   927  		// because else the size of anonymous members is not included in the struct size!
   928  		dummy := &StructDeclarator{Declarator: d}
   929  		dummy.post(lx)
   930  
   931  		for l := lhs.SpecifierQualifierList; l != nil; {
   932  			ts := l.TypeSpecifier
   933  			if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}'
   934  				ts.StructOrUnionSpecifier.declarator = d
   935  				break
   936  			}
   937  
   938  			if o := l.SpecifierQualifierListOpt; o != nil {
   939  				l = o.SpecifierQualifierList
   940  				continue
   941  			}
   942  
   943  			break
   944  		}
   945  	}
   946  |	StaticAssertDeclaration
   947  
   948  // [0](6.7.2.1)
   949  //yy:field	attr		int	// tsInline, tsTypedefName, ...
   950  //yy:field	typeSpecifier	int	// Encoded combination of tsVoid, tsInt, ...
   951  SpecifierQualifierList:
   952  	TypeSpecifier SpecifierQualifierListOpt
   953  	{
   954  		lx.scope.specifier = lhs
   955  		a := lhs.TypeSpecifier
   956  		b := lhs.SpecifierQualifierListOpt
   957  		if b == nil {
   958  			lhs.typeSpecifier = a.typeSpecifier
   959  			break
   960  		}
   961  
   962  		lhs.attr = b.attr
   963  		ts := tsEncode(append(tsDecode(a.typeSpecifier), tsDecode(b.typeSpecifier)...)...)
   964  		if _, ok := tsValid[ts]; !ok {
   965  			lx.report.Err(a.Pos(), "invalid type specifier")
   966  			break
   967  		}
   968  
   969  		lhs.typeSpecifier = ts
   970  	}
   971  |	TypeQualifier SpecifierQualifierListOpt
   972  	{
   973  		lx.scope.specifier = lhs
   974  		a := lhs.TypeQualifier
   975  		b := lhs.SpecifierQualifierListOpt
   976  		if b == nil {
   977  			lhs.attr = a.attr
   978  			break
   979  		}
   980  	
   981  		if a.attr&b.attr != 0 {
   982  			lx.report.Err(a.Pos(), "invalid type qualifier")
   983  			break
   984  		}
   985  
   986  		lhs.attr = a.attr|b.attr
   987  		lhs.typeSpecifier = b.typeSpecifier
   988  	}
   989  
   990  //yy:field	attr		int	// tsInline, tsTypedefName, ...
   991  //yy:field	typeSpecifier	int	// Encoded combination of tsVoid, tsInt, ...
   992  SpecifierQualifierListOpt:
   993  	/* empty */ {}
   994  |	SpecifierQualifierList
   995  	{
   996  		lhs.attr = lhs.SpecifierQualifierList.attr
   997  		lhs.typeSpecifier = lhs.SpecifierQualifierList.typeSpecifier
   998  	}
   999  
  1000  // [0](6.7.2.1)
  1001  StructDeclaratorList:
  1002  	StructDeclarator
  1003  |	StructDeclaratorList ',' StructDeclarator
  1004  
  1005  // [0](6.7.2.1)
  1006  StructDeclarator:
  1007  	Declarator
  1008  	{
  1009  		lhs.Declarator.setFull(lx)
  1010  		lhs.post(lx)
  1011  	}
  1012  |	DeclaratorOpt ':' ConstantExpression
  1013  	{
  1014  		m := lx.model
  1015  		e := lhs.ConstantExpression
  1016  		if e.Value == nil {
  1017  			e.Value, e.Type = m.value2(1, m.IntType)
  1018  		}
  1019  		if !IsIntType(e.Type) {
  1020  			lx.report.Err(e.Pos(), "bit field width not an integer (have '%s')", e.Type)
  1021  			e.Value, e.Type = m.value2(1, m.IntType)
  1022  		}
  1023  		if o := lhs.DeclaratorOpt; o != nil {
  1024  			o.Declarator.setFull(lx)
  1025  		}
  1026  		lhs.post(lx)
  1027  	}
  1028  
  1029  CommaOpt:
  1030  	/* empty */ {}
  1031  |	','
  1032  
  1033  // [0](6.7.2.2)
  1034  //yy:field	unsigned	bool
  1035  EnumSpecifier:
  1036  	"enum" IdentifierOpt
  1037  	{
  1038  		if o := $2.(*IdentifierOpt); o != nil {
  1039  			lx.scope.declareEnumTag(o.Token, lx.report)
  1040  		}
  1041  		lx.iota = 0
  1042  	}
  1043  	'{' EnumeratorList  CommaOpt '}'
  1044  	{
  1045  		if o := lhs.IdentifierOpt; o != nil {
  1046  			lx.scope.defineEnumTag(o.Token, lhs, lx.report)
  1047  		}
  1048  		if !lx.tweaks.enableUnsignedEnums {
  1049  			break
  1050  		}
  1051  
  1052  		lhs.unsigned = true
  1053  	loop:
  1054  		for l := lhs.EnumeratorList; l != nil; l = l.EnumeratorList {
  1055  			switch e := l.Enumerator; x := e.Value.(type) {
  1056  			case int32:
  1057  				if x < 0 {
  1058  					lhs.unsigned = false
  1059  					break loop
  1060  				}
  1061  			case int64:
  1062  				if x < 0 {
  1063  					lhs.unsigned = false
  1064  					break loop
  1065  				}
  1066  			default:
  1067  				panic(fmt.Errorf("%s: TODO Enumerator.Value type %T", position(e.Pos()), x))
  1068  			}
  1069  		}
  1070  	}
  1071  |	"enum" IDENTIFIER
  1072  	{
  1073  		lx.scope.declareEnumTag(lhs.Token2, lx.report)
  1074  	}
  1075  
  1076  // [0](6.7.2.2)
  1077  EnumeratorList:
  1078  	Enumerator
  1079  |	EnumeratorList ',' Enumerator
  1080  
  1081  // [0](6.7.2.2)
  1082  //yy:field	Value		interface{}	// Enumerator's value.
  1083  Enumerator:
  1084  	EnumerationConstant
  1085  	{
  1086  		m := lx.model
  1087  		v := m.MustConvert(lx.iota, m.IntType)
  1088  		lhs.Value = v
  1089  		lx.scope.defineEnumConst(lx, lhs.EnumerationConstant.Token, v)
  1090  	}
  1091  |	EnumerationConstant '=' ConstantExpression
  1092  	{
  1093  		m := lx.model
  1094  		e := lhs.ConstantExpression
  1095  		var v interface{}
  1096  		// [0], 6.7.2.2
  1097  		// The expression that defines the value of an enumeration
  1098  		// constant shall be an integer constant expression that has a
  1099  		// value representable as an int.
  1100  		switch {
  1101  		case !IsIntType(e.Type):
  1102  			lx.report.Err(e.Pos(), "not an integer constant expression (have '%s')", e.Type)
  1103  			v = m.MustConvert(int32(0), m.IntType)
  1104  		default:
  1105  			var ok bool
  1106  			if v, ok = m.enumValueToInt(e.Value); !ok {
  1107  				lx.report.Err(e.Pos(), "overflow in enumeration value: %v", e.Value)
  1108  			}
  1109  		}
  1110  
  1111  		lhs.Value = v
  1112  		lx.scope.defineEnumConst(lx, lhs.EnumerationConstant.Token, v)
  1113  	}
  1114  
  1115  // [0](6.7.3)
  1116  //yy:field	attr		int	// tsInline, tsTypedefName, ...
  1117  TypeQualifier:
  1118  	"const"
  1119  	{
  1120  		lhs.attr = saConst
  1121  	}
  1122  |	"restrict"
  1123  	{
  1124  		lhs.attr = saRestrict
  1125  	}
  1126  |	"volatile"
  1127  	{
  1128  		lhs.attr = saVolatile
  1129  	}
  1130  
  1131  // [0](6.7.4)
  1132  //yy:field	attr		int	// tsInline, tsTypedefName, ...
  1133  FunctionSpecifier:
  1134  	"inline"
  1135  	{
  1136  		lhs.attr = saInline
  1137  	}
  1138  |	"_Noreturn"
  1139  	{
  1140  		lhs.attr = saNoreturn
  1141  	}
  1142  
  1143  // [0](6.7.5)
  1144  //yy:field	Linkage		Linkage
  1145  //yy:field	Type		Type
  1146  //yy:field	bitFieldType	Type
  1147  //yy:field	bitFieldGroup	int
  1148  //yy:field	bitOffset	int
  1149  //yy:field	bits		int
  1150  //yy:field	offsetOf	int
  1151  //yy:field	padding		int
  1152  //yy:field	specifier	Specifier
  1153  Declarator:
  1154  	PointerOpt DirectDeclarator
  1155  	{
  1156  		lhs.specifier = lx.scope.specifier
  1157  		lhs.DirectDeclarator.declarator = lhs
  1158  	}
  1159  
  1160  DeclaratorOpt:
  1161  	/* empty */ {}
  1162  |	Declarator
  1163  
  1164  // [0](6.7.5)
  1165  //yy:field	EnumVal		interface{}	// Non nil if DD declares an enumeration constant.
  1166  //yy:field	declarator	*Declarator
  1167  //yy:field	elements	int
  1168  //yy:field	idScope		*Bindings	// Of case 0: IDENTIFIER.
  1169  //yy:field	paramsScope	*Bindings
  1170  //yy:field	parent		*DirectDeclarator
  1171  //yy:field	prev		*Binding	// Existing declaration in same scope, if any.
  1172  //yy:field	specifier	Specifier
  1173  //yy:field	visible		*Binding	// Existing declaration of same ident visible in same scope, if any and this DD has storage class extrn.
  1174  DirectDeclarator:
  1175  	IDENTIFIER
  1176  	{
  1177  		lhs.specifier = lx.scope.specifier
  1178  		lx.scope.declareIdentifier(lhs.Token, lhs, lx.report)
  1179  		lhs.idScope = lx.scope
  1180  	}
  1181  |	'(' Declarator ')'
  1182  	{
  1183  		lhs.Declarator.specifier = nil
  1184  		lhs.Declarator.DirectDeclarator.parent = lhs
  1185  	}
  1186  |	DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']'
  1187  	{
  1188  		lhs.elements = -1
  1189  		if o := lhs.ExpressionOpt; o != nil {
  1190  			var err error
  1191  			if lhs.elements, err = elements(o.Expression.eval(lx)); err != nil {
  1192  				lx.report.Err(o.Expression.Pos(), "%s", err)
  1193  			}
  1194  			
  1195  		}
  1196  		lhs.DirectDeclarator.parent = lhs
  1197  	}
  1198  |	DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']'
  1199  	{
  1200  		var err error
  1201  		if lhs.elements, err = elements(lhs.Expression.eval(lx)); err != nil {
  1202  			lx.report.Err(lhs.Expression.Pos(), "%s", err)
  1203  		}
  1204  		lhs.DirectDeclarator.parent = lhs
  1205  	}
  1206  |	DirectDeclarator '[' TypeQualifierList "static" Expression ']'
  1207  	{
  1208  		var err error
  1209  		if lhs.elements, err = elements(lhs.Expression.eval(lx)); err != nil {
  1210  			lx.report.Err(lhs.Expression.Pos(), "%s", err)
  1211  		}
  1212  		lhs.DirectDeclarator.parent = lhs
  1213  	}
  1214  |	DirectDeclarator '[' TypeQualifierListOpt '*' ']'
  1215  	{
  1216  		lhs.DirectDeclarator.parent = lhs
  1217  		lhs.elements = -1
  1218  	}
  1219  |	DirectDeclarator '('
  1220  	{
  1221  		lx.pushScope(ScopeParams)
  1222  	}
  1223  	ParameterTypeList ')'
  1224  	{
  1225  		lhs.paramsScope, _ = lx.popScope(lhs.Token2)
  1226  		lhs.DirectDeclarator.parent = lhs
  1227  	}
  1228  |	DirectDeclarator '(' IdentifierListOpt ')'
  1229  	{
  1230  		lhs.DirectDeclarator.parent = lhs
  1231  	}
  1232  
  1233  // [0](6.7.5)
  1234  Pointer:
  1235  	'*' TypeQualifierListOpt
  1236  |	'*' TypeQualifierListOpt Pointer
  1237  
  1238  PointerOpt:
  1239  	/* empty */ {}
  1240  |	Pointer
  1241  
  1242  // [0](6.7.5)
  1243  //yy:field	attr		int	// tsInline, tsTypedefName, ...
  1244  TypeQualifierList:
  1245  	TypeQualifier
  1246  	{
  1247  		lhs.attr = lhs.TypeQualifier.attr
  1248  	}
  1249  |	TypeQualifierList TypeQualifier
  1250  	{
  1251  		a := lhs.TypeQualifierList
  1252  		b := lhs.TypeQualifier
  1253  		if a.attr&b.attr != 0 {
  1254  			lx.report.Err(b.Pos(), "invalid type qualifier")
  1255  			break
  1256  		}
  1257  
  1258  		lhs.attr = a.attr|b.attr
  1259  	}
  1260  
  1261  TypeQualifierListOpt:
  1262  	/* empty */ {}
  1263  |	TypeQualifierList
  1264  
  1265  // [0](6.7.5)
  1266  //yy:field	params	[]Parameter
  1267  ParameterTypeList:
  1268  	ParameterList
  1269  	{
  1270  		lhs.post()
  1271  	}
  1272  |	ParameterList ',' "..."
  1273  	{
  1274  		lhs.post()
  1275  	}
  1276  
  1277  ParameterTypeListOpt:
  1278  	/* empty */ {}
  1279  |	ParameterTypeList
  1280  
  1281  // [0](6.7.5)
  1282  ParameterList:
  1283  	ParameterDeclaration
  1284  |	ParameterList ',' ParameterDeclaration
  1285  
  1286  // [0](6.7.5)
  1287  //yy:field	declarator	*Declarator
  1288  /*TODO
  1289  A declaration of a parameter as ‘‘function returning type’’ shall be adjusted
  1290  to ‘‘pointer to function returning type’’, as in 6.3.2.1.
  1291  */
  1292  ParameterDeclaration:
  1293  	DeclarationSpecifiers Declarator
  1294  	{
  1295  		lhs.Declarator.setFull(lx)
  1296  		lhs.declarator = lhs.Declarator
  1297  	}
  1298  |	DeclarationSpecifiers AbstractDeclaratorOpt
  1299  	{
  1300  		if o := lhs.AbstractDeclaratorOpt; o != nil {
  1301  			lhs.declarator = o.AbstractDeclarator.declarator
  1302  			lhs.declarator.setFull(lx)
  1303  			break
  1304  		}
  1305  
  1306  		d := &Declarator{
  1307  			specifier: lx.scope.specifier,
  1308  			DirectDeclarator: &DirectDeclarator{
  1309  				Case: 0, // IDENTIFIER
  1310  			},
  1311  		}
  1312  		d.DirectDeclarator.declarator = d
  1313  		lhs.declarator = d
  1314  		d.setFull(lx)
  1315  	}
  1316  
  1317  // [0](6.7.5)
  1318  IdentifierList:
  1319  	IDENTIFIER
  1320  |	IdentifierList ',' IDENTIFIER
  1321  
  1322  //yy:field	params	[]Parameter
  1323  IdentifierListOpt:
  1324  	/* empty */ {}
  1325  |	IdentifierList
  1326  
  1327  IdentifierOpt:
  1328  	/* empty */ {}
  1329  |	IDENTIFIER
  1330  
  1331  // [0](6.7.6)
  1332  //yy:field	Type		Type
  1333  //yy:field	declarator	*Declarator
  1334  //yy:field	scope		*Bindings
  1335  TypeName:
  1336  	{
  1337  		lx.pushScope(ScopeBlock)
  1338  	}
  1339  	SpecifierQualifierList AbstractDeclaratorOpt
  1340  	{
  1341  		if o := lhs.AbstractDeclaratorOpt; o != nil {
  1342  			lhs.declarator = o.AbstractDeclarator.declarator
  1343  		} else {
  1344  			d := &Declarator{
  1345  				specifier: lhs.SpecifierQualifierList,
  1346  				DirectDeclarator: &DirectDeclarator{
  1347  					Case: 0, // IDENTIFIER
  1348  					idScope: lx.scope,
  1349  				},
  1350  			}
  1351  			d.DirectDeclarator.declarator = d
  1352  			lhs.declarator = d
  1353  		}
  1354  		lhs.Type = lhs.declarator.setFull(lx)
  1355  		lhs.scope = lx.scope
  1356  		lx.popScope(xc.Token{})
  1357  	}
  1358  
  1359  // [0](6.7.6)
  1360  //yy:field	declarator	*Declarator
  1361  AbstractDeclarator:
  1362  	Pointer
  1363  	{
  1364  		d := &Declarator{
  1365  			specifier: lx.scope.specifier,
  1366  			PointerOpt: &PointerOpt {
  1367  				Pointer: lhs.Pointer,
  1368  			},
  1369  			DirectDeclarator: &DirectDeclarator{
  1370  				Case: 0, // IDENTIFIER
  1371  				idScope: lx.scope,
  1372  			},
  1373  		}
  1374  		d.DirectDeclarator.declarator = d
  1375  		lhs.declarator = d
  1376  	}
  1377  |	PointerOpt DirectAbstractDeclarator
  1378  	{
  1379  		d := &Declarator{
  1380  			specifier: lx.scope.specifier,
  1381  			PointerOpt: lhs.PointerOpt,
  1382  			DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator,
  1383  		}
  1384  		d.DirectDeclarator.declarator = d
  1385  		lhs.declarator = d
  1386  	}
  1387  
  1388  AbstractDeclaratorOpt:
  1389  	/* empty */ {}
  1390  |	AbstractDeclarator
  1391  
  1392  // [0](6.7.6)
  1393  //yy:field	directDeclarator	*DirectDeclarator
  1394  //yy:field	paramsScope		*Bindings
  1395  DirectAbstractDeclarator:
  1396  	'(' AbstractDeclarator ')'
  1397  	{
  1398  		lhs.AbstractDeclarator.declarator.specifier = nil
  1399  		lhs.directDeclarator = &DirectDeclarator{
  1400  			Case: 1, // '(' Declarator ')'
  1401  			Declarator: lhs.AbstractDeclarator.declarator,
  1402  		}
  1403  		lhs.AbstractDeclarator.declarator.DirectDeclarator.parent = lhs.directDeclarator
  1404  	}
  1405  |	DirectAbstractDeclaratorOpt '[' ExpressionOpt ']'
  1406  	{
  1407  		nElements := -1
  1408  		if o := lhs.ExpressionOpt; o != nil {
  1409  			var err error
  1410  			if nElements, err = elements(o.Expression.eval(lx)); err != nil {
  1411  				lx.report.Err(o.Expression.Pos(), "%s", err)
  1412  			}
  1413  		}
  1414  		var dd *DirectDeclarator
  1415  		switch o := lhs.DirectAbstractDeclaratorOpt; {
  1416  		case o == nil:
  1417  			dd = &DirectDeclarator{
  1418  				Case: 0, // IDENTIFIER
  1419  			}
  1420  		default:
  1421  			dd = o.DirectAbstractDeclarator.directDeclarator
  1422  		}
  1423  		lhs.directDeclarator = &DirectDeclarator{
  1424  			Case: 2, // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']'
  1425  			DirectDeclarator: dd,
  1426  			ExpressionOpt: lhs.ExpressionOpt,
  1427  			elements: nElements,
  1428  		}
  1429  		dd.parent = lhs.directDeclarator
  1430  	}
  1431  |	DirectAbstractDeclaratorOpt '[' TypeQualifierList ExpressionOpt ']'
  1432  	{
  1433  		if o := lhs.ExpressionOpt; o != nil {
  1434  			o.Expression.eval(lx)
  1435  		}
  1436  		var dd *DirectDeclarator
  1437  		switch o := lhs.DirectAbstractDeclaratorOpt; {
  1438  		case o == nil:
  1439  			dd = &DirectDeclarator{
  1440  				Case: 0, // IDENTIFIER
  1441  			}
  1442  		default:
  1443  			dd = o.DirectAbstractDeclarator.directDeclarator
  1444  		}
  1445  		lhs.directDeclarator = &DirectDeclarator{
  1446  			Case: 2, // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']'
  1447  			DirectDeclarator: dd,
  1448  			TypeQualifierListOpt: &TypeQualifierListOpt{ lhs.TypeQualifierList },
  1449  			ExpressionOpt: lhs.ExpressionOpt,
  1450  		}
  1451  		dd.parent = lhs.directDeclarator
  1452  	}
  1453  |	DirectAbstractDeclaratorOpt '[' "static" TypeQualifierListOpt Expression ']'
  1454  	{
  1455  		lhs.Expression.eval(lx)
  1456  		var dd *DirectDeclarator
  1457  		switch o := lhs.DirectAbstractDeclaratorOpt; {
  1458  		case o == nil:
  1459  			dd = &DirectDeclarator{
  1460  				Case: 0, // IDENTIFIER
  1461  			}
  1462  		default:
  1463  			dd = o.DirectAbstractDeclarator.directDeclarator
  1464  		}
  1465  		lhs.directDeclarator = &DirectDeclarator{
  1466  			Case: 2, // DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']'
  1467  			DirectDeclarator: dd,
  1468  			TypeQualifierListOpt: lhs.TypeQualifierListOpt,
  1469  			Expression: lhs.Expression,
  1470  		}
  1471  		dd.parent = lhs.directDeclarator
  1472  	}
  1473  |	DirectAbstractDeclaratorOpt '[' TypeQualifierList "static" Expression ']'
  1474  	{
  1475  		lhs.Expression.eval(lx)
  1476  		var dd *DirectDeclarator
  1477  		switch o := lhs.DirectAbstractDeclaratorOpt; {
  1478  		case o == nil:
  1479  			dd = &DirectDeclarator{
  1480  				Case: 0, // IDENTIFIER
  1481  			}
  1482  		default:
  1483  			dd = o.DirectAbstractDeclarator.directDeclarator
  1484  		}
  1485  		lhs.directDeclarator = &DirectDeclarator{
  1486  			Case: 4, // DirectDeclarator '[' TypeQualifierList "static" Expression ']'
  1487  			DirectDeclarator: dd,
  1488  			TypeQualifierList: lhs.TypeQualifierList,
  1489  			Expression: lhs.Expression,
  1490  		}
  1491  		dd.parent = lhs.directDeclarator
  1492  	}
  1493  |	DirectAbstractDeclaratorOpt '[' '*' ']'
  1494  	{
  1495  		var dd *DirectDeclarator
  1496  		switch o := lhs.DirectAbstractDeclaratorOpt; {
  1497  		case o == nil:
  1498  			dd = &DirectDeclarator{
  1499  				Case: 0, // IDENTIFIER
  1500  			}
  1501  		default:
  1502  			dd = o.DirectAbstractDeclarator.directDeclarator
  1503  		}
  1504  		lhs.directDeclarator = &DirectDeclarator{
  1505  			Case: 5, // DirectDeclarator '[' TypeQualifierListOpt '*' ']'
  1506  			DirectDeclarator: dd,
  1507  		}
  1508  		dd.parent = lhs.directDeclarator
  1509  	}
  1510  |	'('
  1511  	{
  1512  		lx.pushScope(ScopeParams)
  1513  	}
  1514  	ParameterTypeListOpt ')'
  1515  	{
  1516  		lhs.paramsScope, _ = lx.popScope(lhs.Token2)
  1517  		switch o := lhs.ParameterTypeListOpt; {
  1518  		case o != nil:
  1519  			lhs.directDeclarator = &DirectDeclarator{
  1520  				Case: 6, // DirectDeclarator '(' ParameterTypeList ')'
  1521  				DirectDeclarator: &DirectDeclarator{
  1522  					Case: 0, // IDENTIFIER
  1523  				},
  1524  				ParameterTypeList: o.ParameterTypeList,
  1525  			}
  1526  		default:
  1527  			lhs.directDeclarator = &DirectDeclarator{
  1528  				Case: 7, // DirectDeclarator '(' IdentifierListOpt ')'
  1529  				DirectDeclarator: &DirectDeclarator{
  1530  					Case: 0, // IDENTIFIER
  1531  				},
  1532  			}
  1533  		}
  1534  		lhs.directDeclarator.DirectDeclarator.parent = lhs.directDeclarator
  1535  	}
  1536  |	DirectAbstractDeclarator '('
  1537  	{
  1538  		lx.pushScope(ScopeParams)
  1539  	}
  1540  	ParameterTypeListOpt ')'
  1541  	{
  1542  		lhs.paramsScope, _ = lx.popScope(lhs.Token2)
  1543  		switch o := lhs.ParameterTypeListOpt; {
  1544  		case o != nil:
  1545  			lhs.directDeclarator = &DirectDeclarator{
  1546  				Case: 6, // DirectDeclarator '(' ParameterTypeList ')'
  1547  				DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator,
  1548  				ParameterTypeList: o.ParameterTypeList,
  1549  			}
  1550  		default:
  1551  			lhs.directDeclarator = &DirectDeclarator{
  1552  				Case: 7, // DirectDeclarator '(' IdentifierListOpt ')'
  1553  				DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator,
  1554  			}
  1555  		}
  1556  		lhs.directDeclarator.DirectDeclarator.parent = lhs.directDeclarator
  1557  	}
  1558  
  1559  DirectAbstractDeclaratorOpt:
  1560  	/* empty */ {}
  1561  |	DirectAbstractDeclarator
  1562  
  1563  // [0](6.7.8)
  1564  Initializer:
  1565  	Expression
  1566  	{
  1567  		lhs.Expression.eval(lx)
  1568  	}
  1569  |	'{' InitializerList CommaOpt '}'
  1570  |	IDENTIFIER ':' Initializer
  1571  	{
  1572  		if !lx.tweaks.enableLegacyDesignators {
  1573  			lx.report.Err(lhs.Pos(), "legacy designators not enabled")
  1574  		}
  1575  	}
  1576  
  1577  // [0](6.7.8)
  1578  InitializerList:
  1579  	DesignationOpt Initializer
  1580  |	InitializerList ',' DesignationOpt Initializer
  1581  |	/* empty */ {}
  1582  
  1583  // [0](6.7.8)
  1584  Designation:
  1585  	DesignatorList '='
  1586  
  1587  DesignationOpt:
  1588  	/* empty */ {}
  1589  |	Designation
  1590  
  1591  // [0](6.7.8)
  1592  DesignatorList:
  1593  	Designator
  1594  |	DesignatorList Designator
  1595  
  1596  // [0](6.7.8)
  1597  Designator:
  1598  	'[' ConstantExpression ']'
  1599  |	'.' IDENTIFIER
  1600  
  1601  // [0](6.8)
  1602  Statement:
  1603  	LabeledStatement
  1604  |	CompoundStatement
  1605  |	ExpressionStatement
  1606  |	SelectionStatement
  1607  |	IterationStatement
  1608  |	JumpStatement
  1609  |	AssemblerStatement
  1610  
  1611  // [0](6.8.1)
  1612  LabeledStatement:
  1613  	IDENTIFIER ':' Statement
  1614  |	"case" ConstantExpression ':' Statement
  1615  |	"default" ':' Statement
  1616  
  1617  // [0](6.8.2)
  1618  //yy:field	scope	*Bindings	// Scope of the CompoundStatement.
  1619  CompoundStatement:
  1620  	'{'
  1621  	{
  1622  		m := lx.scope.mergeScope
  1623  		lx.pushScope(ScopeBlock)
  1624  		if m != nil {
  1625  			lx.scope.merge(m)
  1626  		}
  1627  		lx.scope.mergeScope = nil
  1628  	}
  1629  	BlockItemListOpt '}'
  1630  	{
  1631  		lhs.scope = lx.scope
  1632  		lx.popScope(lhs.Token2)
  1633  	}
  1634  
  1635  // [0](6.8.2)
  1636  BlockItemList:
  1637  	BlockItem
  1638  |	BlockItemList BlockItem
  1639  
  1640  BlockItemListOpt:
  1641  	/* empty */ {}
  1642  |	BlockItemList
  1643  
  1644  // [0](6.8.2)
  1645  BlockItem:
  1646  	Declaration
  1647  |	Statement
  1648  
  1649  // [0](6.8.3)
  1650  ExpressionStatement:
  1651  	ExpressionListOpt ';'
  1652  
  1653  // [0](6.8.4)
  1654  SelectionStatement:
  1655  	"if" '(' ExpressionList ')' Statement %prec NOELSE
  1656  	{
  1657  		lhs.ExpressionList.eval(lx)
  1658  	}
  1659  |	"if" '(' ExpressionList ')' Statement "else" Statement
  1660  	{
  1661  		lhs.ExpressionList.eval(lx)
  1662  	}
  1663  |	"switch" '(' ExpressionList ')' Statement
  1664  	{
  1665  		lhs.ExpressionList.eval(lx)
  1666  	}
  1667  
  1668  // [0](6.8.5)
  1669  IterationStatement:
  1670  	"while" '(' ExpressionList ')' Statement
  1671  	{
  1672  		lhs.ExpressionList.eval(lx)
  1673  	}
  1674  |	"do" Statement "while" '(' ExpressionList ')' ';'
  1675  	{
  1676  		lhs.ExpressionList.eval(lx)
  1677  	}
  1678  |	"for" '(' ExpressionListOpt ';' ExpressionListOpt ';' ExpressionListOpt ')' Statement
  1679  |	"for" '(' Declaration ExpressionListOpt ';' ExpressionListOpt ')' Statement
  1680  
  1681  // [0](6.8.6)
  1682  JumpStatement:
  1683  	"goto" IDENTIFIER ';'
  1684  |	"continue" ';'
  1685  |	"break" ';'
  1686  |	"return" ExpressionListOpt ';'
  1687  |	"goto" Expression ';'
  1688  	{
  1689  		_, t := lhs.Expression.eval(lx)
  1690  		if t == nil {
  1691  			break
  1692  		}
  1693  
  1694  		for t != nil && t.Kind() == Ptr {
  1695  			t = t.Element()
  1696  		}
  1697  
  1698  		if t == nil || t.Kind() != Void {
  1699  			lx.report.Err(lhs.Pos(), "invalid computed goto argument type, have '%s'", t)
  1700  		}
  1701  
  1702  		if !lx.tweaks.enableComputedGotos {
  1703  			lx.report.Err(lhs.Pos(), "computed gotos not enabled")
  1704  		}
  1705  	}
  1706  
  1707  // [0](6.9)
  1708  //yy:field	Comments	map[token.Pos]int	// Position -> comment ID. Enable using the KeepComments option.
  1709  //yy:field	Declarations	*Bindings
  1710  //yy:field	Macros		map[int]*Macro		// Ident ID -> preprocessor macro defined by ident.
  1711  //yy:field	Model		*Model			// Model used to parse the TranslationUnit.
  1712  //yy:list
  1713  TranslationUnit:
  1714  	ExternalDeclaration
  1715  |	TranslationUnit ExternalDeclaration
  1716  
  1717  // [0](6.9)
  1718  ExternalDeclaration:
  1719  	FunctionDefinition
  1720  |	Declaration
  1721  |	BasicAssemblerStatement ';'
  1722  |	';'
  1723  	{
  1724  		if !lx.tweaks.enableEmptyDeclarations {
  1725  			lx.report.Err(lhs.Pos(), "C++11 empty declarations are illegal in C99.")
  1726  		}
  1727  	}
  1728  
  1729  // [0](6.9.1)
  1730  FunctionDefinition:
  1731  	DeclarationSpecifiers Declarator DeclarationListOpt
  1732  	{
  1733  		if ds := $1.(*DeclarationSpecifiers); ds.typeSpecifier == 0 {
  1734  			ds.typeSpecifier = tsEncode(tsInt)
  1735  			$2.(*Declarator).Type = lx.model.IntType
  1736  			if !lx.tweaks.enableOmitFuncRetType {
  1737  				lx.report.Err($2.Pos(), "missing function return type")
  1738  			}
  1739  		}
  1740  		var fd *FunctionDefinition
  1741  		fd.post(lx, $2.(*Declarator), $3.(*DeclarationListOpt))
  1742  	}
  1743  	FunctionBody
  1744  |	{
  1745  		lx.scope.specifier = &DeclarationSpecifiers{typeSpecifier: tsEncode(tsInt)}
  1746  	}
  1747  	Declarator DeclarationListOpt
  1748  	{
  1749  		if !lx.tweaks.enableOmitFuncRetType {
  1750  			lx.report.Err($2.Pos(), "missing function return type")
  1751  		}
  1752  		var fd *FunctionDefinition
  1753  		fd.post(lx, $2.(*Declarator), $3.(*DeclarationListOpt))
  1754  	}
  1755  	FunctionBody
  1756  
  1757  //yy:field	scope	*Bindings	// Scope of the FunctionBody.
  1758  FunctionBody:
  1759  	{
  1760  		// Handle __func__, [0], 6.4.2.2.
  1761  		id, _ := lx.fnDeclarator.Identifier()
  1762  		lx.injectFunc = []xc.Token{
  1763  			{lex.Char{Rune: STATIC}, idStatic},
  1764  			{lex.Char{Rune: CONST}, idConst},
  1765  			{lex.Char{Rune: CHAR}, idChar},
  1766  			{lex.Char{Rune: IDENTIFIER}, idMagicFunc},
  1767  			{lex.Char{Rune: '['}, 0},
  1768  			{lex.Char{Rune: ']'}, 0},
  1769  			{lex.Char{Rune: '='}, 0},
  1770  			{lex.Char{Rune: STRINGLITERAL}, xc.Dict.SID(fmt.Sprintf("%q", xc.Dict.S(id)))},
  1771  			{lex.Char{Rune: ';'}, 0},
  1772  		}
  1773  	}
  1774  	CompoundStatement
  1775  	{
  1776  		lhs.scope = lhs.CompoundStatement.scope
  1777  	}
  1778  |	
  1779  	{
  1780  		m := lx.scope.mergeScope
  1781  		lx.pushScope(ScopeBlock)
  1782  		if m != nil {
  1783  			lx.scope.merge(m)
  1784  		}
  1785  		lx.scope.mergeScope = nil
  1786  	}
  1787  	AssemblerStatement ';'
  1788  	{
  1789  		lhs.scope = lx.scope
  1790  		lx.popScope(lx.tokPrev)
  1791  	}
  1792  
  1793  // [0](6.9.1)
  1794  DeclarationList:
  1795  	Declaration
  1796  |	DeclarationList Declaration
  1797  
  1798  //yy:field	paramsScope	*Bindings
  1799  DeclarationListOpt:
  1800  	/* empty */ {}
  1801  |	{
  1802  		lx.pushScope(ScopeParams)
  1803  	}
  1804  	DeclarationList
  1805  	{
  1806  		lhs.paramsScope, _ = lx.popScopePos(lhs.Pos())
  1807  	}
  1808  
  1809  //yy:list
  1810  AssemblerInstructions:
  1811  	STRINGLITERAL
  1812  |	AssemblerInstructions STRINGLITERAL
  1813  
  1814  BasicAssemblerStatement:
  1815  	"asm" VolatileOpt '(' AssemblerInstructions ')'
  1816  
  1817  VolatileOpt:
  1818  	/* empty */ {}
  1819  |	"volatile"
  1820  
  1821  AssemblerOperand:
  1822  	AssemblerSymbolicNameOpt STRINGLITERAL '(' Expression ')'
  1823  
  1824  //yy:list
  1825  AssemblerOperands:
  1826  	AssemblerOperand
  1827  |	AssemblerOperands ',' AssemblerOperand
  1828  
  1829  AssemblerSymbolicNameOpt:
  1830  	/* empty */ {}
  1831  |	'[' IDENTIFIER ']'
  1832  
  1833  //yy:list
  1834  Clobbers:
  1835  	STRINGLITERAL
  1836  |	Clobbers ',' STRINGLITERAL
  1837  
  1838  AssemblerStatement:
  1839  	BasicAssemblerStatement
  1840  |	"asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ')'
  1841  |	"asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ':' AssemblerOperands ')'
  1842  |	"asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ':' AssemblerOperands ':' Clobbers ')'
  1843  |	"asm" VolatileOpt "goto" '(' AssemblerInstructions ':' ':' AssemblerOperands ':' Clobbers ':' IdentifierList ')'
  1844  |	"asm" VolatileOpt '(' AssemblerInstructions ':' ')' // https://github.com/cznic/cc/issues/59
  1845  |	"asm" VolatileOpt '(' AssemblerInstructions ':' ':' AssemblerOperands ')'
  1846  
  1847  StaticAssertDeclaration:
  1848  	"_Static_assert" '(' ConstantExpression ',' STRINGLITERAL ')' ';'
  1849  	{
  1850  		ce := lhs.ConstantExpression
  1851  		if ce.Type == nil || ce.Type.Kind() == Undefined || ce.Value == nil || !IsIntType(ce.Type) {
  1852  			lx.report.Err(ce.Pos(), "invalid static assert expression (have '%v')", ce.Type)
  1853  			break
  1854  		}
  1855  
  1856  		if !isNonZero(ce.Value) {
  1857  			lx.report.ErrTok(lhs.Token, "%s", lhs.Token4.S())
  1858  		}
  1859  	}
  1860  
  1861  // ========================================================= PREPROCESSING_FILE
  1862  
  1863  // [0](6.10)
  1864  //yy:field	path	string
  1865  PreprocessingFile:
  1866  	GroupList // No more GroupListOpt due to final '\n' injection.
  1867  	{
  1868  		lhs.path = lx.file.Name()
  1869  	}
  1870  
  1871  // [0](6.10)
  1872  GroupList:
  1873  	GroupPart
  1874  //yy:example "\U00100000int\nf() {}"
  1875  |	GroupList GroupPart
  1876  
  1877  GroupListOpt:
  1878  	/* empty */ {}
  1879  //yy:example "\U00100000 \n#ifndef a\nb\n#elif"
  1880  |	GroupList
  1881  
  1882  // [0](6.10)
  1883  //yy:ignore
  1884  GroupPart:
  1885  	ControlLine
  1886  	{
  1887  		$$ = $1.(Node)
  1888  	}
  1889  |	IfSection
  1890  	{
  1891  		$$ = $1.(Node)
  1892  	}
  1893  |	PPNONDIRECTIVE PPTokenList '\n'
  1894  	{
  1895  		$$ = $1
  1896  	}
  1897  |	TextLine
  1898  	{
  1899  		$$ = $1
  1900  	}
  1901  
  1902  //(6.10)
  1903  IfSection:
  1904  	IfGroup ElifGroupListOpt ElseGroupOpt EndifLine
  1905  
  1906  //(6.10)
  1907  IfGroup:
  1908  	PPIF PPTokenList '\n' GroupListOpt
  1909  |	PPIFDEF IDENTIFIER '\n' GroupListOpt
  1910  |	PPIFNDEF IDENTIFIER '\n' GroupListOpt
  1911  
  1912  // [0](6.10)
  1913  ElifGroupList:
  1914  	ElifGroup
  1915  |	ElifGroupList ElifGroup
  1916  
  1917  ElifGroupListOpt:
  1918  	/* empty */ {}
  1919  |	ElifGroupList
  1920  
  1921  // [0](6.10)
  1922  ElifGroup:
  1923  	PPELIF PPTokenList '\n' GroupListOpt
  1924  
  1925  // [0](6.10)
  1926  ElseGroup:
  1927  	PPELSE '\n' GroupListOpt
  1928  
  1929  ElseGroupOpt:
  1930  	/* empty */ {}
  1931  |	ElseGroup
  1932  
  1933  // [0](6.10)
  1934  EndifLine:
  1935  	PPENDIF /* PPTokenListOpt */ //TODO Option enabling the non std PPTokenListOpt part.
  1936  
  1937  // [0](6.10)
  1938  ControlLine:
  1939  	PPDEFINE IDENTIFIER ReplacementList
  1940  |	PPDEFINE IDENTIFIER_LPAREN "..." ')' ReplacementList
  1941  |	PPDEFINE IDENTIFIER_LPAREN IdentifierList ',' "..." ')' ReplacementList
  1942  |	PPDEFINE IDENTIFIER_LPAREN IdentifierListOpt ')' ReplacementList
  1943  |	PPERROR PPTokenListOpt
  1944  |	PPHASH_NL
  1945  |	PPINCLUDE PPTokenList '\n'
  1946  |	PPLINE PPTokenList '\n'
  1947  |	PPPRAGMA PPTokenListOpt
  1948  //yy:example	"\U00100000 \n#undef foo"
  1949  |	PPUNDEF IDENTIFIER '\n'
  1950  
  1951  	// Non standard stuff.
  1952  
  1953  |	PPDEFINE IDENTIFIER_LPAREN IdentifierList "..." ')' ReplacementList
  1954  	{
  1955  		if !lx.tweaks.enableDefineOmitCommaBeforeDDD {
  1956  			lx.report.ErrTok(lhs.Token4, "missing comma before \"...\"")
  1957  		}
  1958  	}
  1959  |	PPDEFINE '\n'
  1960  	{
  1961  		if !lx.tweaks.enableEmptyDefine {
  1962  			lx.report.ErrTok(lhs.Token2, "expected identifier")
  1963  		}
  1964  	}
  1965  //yy:example	"\U00100000 \n#undef foo(bar)"
  1966  |	PPUNDEF IDENTIFIER PPTokenList '\n'
  1967  	{
  1968  		toks := decodeTokens(lhs.PPTokenList, nil, false)
  1969  		if len(toks) == 0 {
  1970  			lhs.Case = 9 // PPUNDEF IDENTIFIER '\n' 
  1971  			break
  1972  		}
  1973  
  1974  		lx.report.ErrTok(toks[0], "extra tokens after #undef argument")
  1975  	}
  1976  |	PPINCLUDE_NEXT PPTokenList '\n'
  1977  
  1978  // [0](6.10)
  1979  //yy:ignore
  1980  TextLine:
  1981  	PPTokenListOpt
  1982  
  1983  // [0](6.10)
  1984  //yy:ignore
  1985  ReplacementList:
  1986  	PPTokenListOpt
  1987  
  1988  // [0](6.10)
  1989  //yy:ignore
  1990  PPTokenList:
  1991  	PPTokens
  1992  	{
  1993  		$$ = PPTokenList(dict.ID(lx.encBuf))
  1994  		lx.encBuf = lx.encBuf[:0]
  1995  		lx.encPos = 0
  1996  	}
  1997  
  1998  //yy:ignore
  1999  PPTokenListOpt:
  2000  	'\n'
  2001  	{
  2002  		$$ = 0
  2003  	}
  2004  |	PPTokenList '\n'
  2005  
  2006  //yy:ignore
  2007  PPTokens:
  2008  	PPOTHER
  2009  |	PPTokens PPOTHER