compiler/grammar: Added support for extended declarator in between struct and identifier
[sdk] / compiler / libec / src / type.y
1 %{
2
3 import "ecdefs"
4
5 #define YYLTYPE Location
6 #include "grammar.h"
7
8 #ifndef YYLLOC_DEFAULT
9 # define YYLLOC_DEFAULT(Current, Rhs, N)         \
10   (Current).start = (Rhs)[1].start;      \
11   (Current).end = (Rhs)[N].end;
12 #endif
13
14 TypeName parsedType;
15
16 #define PRECOMPILER
17
18 #define yyparse type_yyparse
19 #define yylval  type_yylval
20 #define yychar  type_yychar
21 #define yydebug type_yydebug
22 #define yynerrs type_yynerrs
23 #define yylloc  type_yylloc
24
25 extern bool parseTypeError;
26
27 extern File fileInput;
28 extern char * yytext;
29 int yylex();
30 int yyerror();
31
32 #define uint _uint
33 default:
34
35 %}
36
37 %debug
38 %union
39 {
40    int i;
41    SpecifierType specifierType;
42    Identifier id;
43    Expression exp;
44    Specifier specifier;
45    OldList * list;
46    Enumerator enumerator;
47    Declarator declarator;
48    Pointer pointer;
49    Initializer initializer;
50    InitDeclarator initDeclarator;
51    TypeName typeName;
52    Declaration declaration;
53    Statement stmt;
54    FunctionDefinition function;
55    External external;
56    Context context;
57    Attrib attrib;
58    ExtDecl extDecl;
59    Attribute attribute;
60
61    Instantiation instance;
62    MembersInit membersInit;
63    MemberInit memberInit;
64    ClassFunction classFunction;
65    ClassDefinition _class;
66    ClassDef classDef;
67    PropertyDef prop;
68    char * string;
69    Symbol symbol;
70    TemplateParameter templateParameter;
71    TemplateArgument templateArgument;
72    TemplateDatatype templateDatatype;
73 }
74
75 // *** Types ***
76
77 %type <specifierType> struct_or_union
78 %type <i>   unary_operator assignment_operator
79 %type <id>  identifier
80 %type <exp> primary_expression postfix_expression unary_expression cast_expression
81             multiplicative_expression additive_expression shift_expression
82             relational_expression relational_expression_smaller_than equality_expression and_expression
83             exclusive_or_expression inclusive_or_expression logical_and_expression
84             logical_or_expression conditional_expression assignment_expression
85             constant_expression
86             common_unary_expression simple_primary_expression simple_postfix_expression simple_unary_expression
87             anon_instantiation_expression
88
89 %type <list> argument_expression_list expression enumerator_list
90              struct_declarator_list struct_declaration_list 
91              declaration_specifiers identifier_list initializer_list init_declarator_list
92              parameter_list parameter_type_list declaration_list statement_list 
93              members_initialization_list members_initialization_list_coloned data_member_initialization_list data_member_initialization_list_coloned
94              guess_declaration_specifiers real_guess_declaration_specifiers
95              specifier_qualifier_list guess_specifier_qualifier_list
96              type_qualifier_list property_specifiers
97              renew_specifiers
98              default_property_list
99              template_arguments_list attribs_list
100              
101
102 %type <specifier> storage_class_specifier enum_specifier_compound enum_specifier_nocompound type_qualifier type_specifier strict_type_specifier
103                   struct_or_union_specifier_compound struct_or_union_specifier_nocompound guess_type type strict_type
104                   real_guess_type ext_storage base_strict_type
105 %type <enumerator> enumerator
106 %type <declarator> declarator direct_declarator direct_abstract_declarator abstract_declarator
107                    struct_declarator direct_declarator_function direct_declarator_function_start declarator_function direct_declarator_nofunction 
108                    direct_abstract_declarator_noarray abstract_declarator_noarray declarator_nofunction
109                    
110 %type <pointer> pointer
111 %type <initializer> initializer initializer_condition
112 %type <initDeclarator> init_declarator 
113 %type <typeName> type_name guess_type_name parameter_declaration
114 %type <stmt> statement labeled_statement compound_statement expression_statement 
115              selection_statement iteration_statement jump_statement compound_inside
116
117 %type <declaration> declaration
118 %type <classDef> struct_declaration 
119 %type <string> string_literal attribute_word
120 %type <extDecl> ext_decl
121 %type <attrib> attrib
122 %type <attribute> attribute
123
124 %type <instance> instantiation_named instantiation_unnamed guess_instantiation_named instantiation_anon
125 /* %type <membersInit>  members_initialization */
126 %type <memberInit> data_member_initialization default_property
127 %type <classFunction> class_function_definition class_function_definition_start 
128                      virtual_class_function_definition_start 
129                      constructor_function_definition_start destructor_function_definition_start 
130 %type <classFunction> instance_class_function_definition instance_class_function_definition_start 
131 %type <prop> property
132
133 %type <templateArgument> template_argument template_type_argument template_expression_argument
134 %type <templateDatatype> template_datatype
135
136 %type <context> compound_start
137
138 %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
139 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
140 %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
141 %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
142 %token XOR_ASSIGN OR_ASSIGN TYPE_NAME
143
144 %token TYPEDEF EXTERN STATIC AUTO REGISTER
145 %token CHAR SHORT INT UINT INT64 LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID VALIST
146 %token STRUCT UNION ENUM ELLIPSIS
147
148 %token CASE DEFAULT IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
149
150 %nonassoc IFX
151 %nonassoc ELSE
152 %token CLASS THISCLASS CLASS_NAME
153 %token PROPERTY SETPROP GETPROP NEWOP RENEW DELETE EXT_DECL EXT_STORAGE IMPORT DEFINE VIRTUAL ATTRIB
154 %token PUBLIC PRIVATE
155 %token TYPED_OBJECT ANY_OBJECT _INCREF EXTENSION ASM TYPEOF
156 %token WATCH STOPWATCHING FIREWATCHERS WATCHABLE CLASS_DESIGNER CLASS_NO_EXPANSION CLASS_FIXED ISPROPSET
157 %token CLASS_DEFAULT_PROPERTY PROPERTY_CATEGORY CLASS_DATA CLASS_PROPERTY SUBCLASS NAMESPACE
158 %token NEW0OP RENEW0 VAARG
159 %token DBTABLE DBFIELD DBINDEX DATABASE_OPEN
160 %token ALIGNOF ATTRIB_DEP __ATTRIB
161
162 %destructor { FreeIdentifier($$); } identifier 
163 %destructor { FreePointer($$); } pointer
164 %destructor { FreeExpression($$); } primary_expression postfix_expression unary_expression cast_expression
165                                     multiplicative_expression additive_expression shift_expression
166                                     relational_expression equality_expression and_expression
167                                     exclusive_or_expression inclusive_or_expression logical_and_expression
168                                     logical_or_expression conditional_expression assignment_expression
169                                     constant_expression
170 %destructor { FreeSpecifier($$); }  storage_class_specifier enum_specifier_compound enum_specifier_nocompound type_qualifier type_specifier
171                                     struct_or_union_specifier_compound struct_or_union_specifier_nocompound ext_storage type strict_type guess_type strict_type_specifier
172                                     base_strict_type
173 %destructor { FreeEnumerator($$); } enumerator
174 %destructor { FreeDeclarator($$); } declarator direct_declarator direct_abstract_declarator abstract_declarator
175                                     direct_abstract_declarator_noarray abstract_declarator_noarray
176                                     struct_declarator direct_declarator_function direct_declarator_function_start declarator_function direct_declarator_nofunction
177                                     declarator_nofunction
178
179 %destructor { FreeInitializer($$); } initializer initializer_condition
180 %destructor { FreeInitDeclarator($$); } init_declarator
181 %destructor { FreeTypeName($$); } type_name guess_type_name parameter_declaration
182 %destructor { FreeStatement($$); }  statement labeled_statement compound_statement expression_statement 
183                                     selection_statement iteration_statement jump_statement compound_inside
184
185 %destructor { FreeDeclaration($$); } declaration
186
187 %destructor { FreeInstance($$); } instantiation_named instantiation_unnamed
188
189 %destructor { FreeMemberInit($$); } data_member_initialization default_property
190
191 %destructor { FreeClassFunction($$); } class_function_definition class_function_definition_start 
192                                        virtual_class_function_definition_start
193                                        constructor_function_definition_start destructor_function_definition_start 
194                                        instance_class_function_definition instance_class_function_definition_start 
195 %destructor { FreeClassDef($$); } struct_declaration
196 %destructor { delete $$; } string_literal attribute_word
197 %destructor { FreeProperty($$); } property
198
199 %destructor { FreeList($$, FreeExpression); }  argument_expression_list expression 
200 %destructor { FreeList($$, FreeEnumerator); }  enumerator_list 
201 %destructor { FreeList($$, FreeSpecifier); }   type_qualifier_list specifier_qualifier_list declaration_specifiers
202                                                guess_declaration_specifiers guess_specifier_qualifier_list
203 %destructor { FreeList($$, FreeDeclarator); }  struct_declarator_list
204 %destructor { FreeList($$, FreeDeclaration); } declaration_list 
205 %destructor { FreeList($$, FreeInitializer); } initializer_list
206 %destructor { FreeList($$, FreeInitDeclarator); } init_declarator_list 
207 %destructor { FreeList($$, FreeTypeName); } parameter_list parameter_type_list identifier_list 
208 %destructor { FreeList($$, FreeStatement); } statement_list
209 %destructor { FreeList($$, FreeClassDef); } struct_declaration_list
210 %destructor { FreeList($$, FreeMemberInit); } default_property_list data_member_initialization_list data_member_initialization_list_coloned
211 %destructor { FreeList($$, FreeMembersInit); } members_initialization_list members_initialization_list_coloned
212 %destructor { PopContext($$); FreeContext($$); delete $$; } compound_start
213 %destructor { FreeTemplateArgument($$); } template_argument template_type_argument template_expression_argument
214 %destructor { FreeTemplateDataType($$); } template_datatype
215 %destructor { FreeAttrib($$); } attrib
216 %destructor { FreeExtDecl($$); } ext_decl
217 %destructor { FreeAttribute($$); } attribute
218 %destructor { FreeList($$, FreeAttribute); }  attribs_list
219
220 %start type_unit
221
222 %%
223
224 guess_type:
225    identifier '*'
226    {
227       $$ = null;
228       DeclClass(0, $1.string);
229       fileInput.Seek(@1.start.pos, start); 
230       resetScannerPos(&@1.start);
231       yyclearin;
232       
233       FreeIdentifier($1);
234
235       YYPOPSTACK(1);
236       yystate = *yyssp;
237       YY_STACK_PRINT (yyss, yyssp);
238       YYPOPSTACK(1);
239       yystate = *yyssp;
240       YY_STACK_PRINT (yyss, yyssp);
241       goto yysetstate;
242    }
243    | identifier '<'
244    {
245       $$ = null;
246    #ifdef PRECOMPILER
247       // if($1._class && !$1._class.name)
248       if($1._class)
249       {
250          char name[1024];
251          strcpy(name,  $1._class.name ? $1._class.name : "");
252          strcat(name, "::");
253          strcat(name, $1.string);
254          _DeclClass(0, name);
255       }
256       else
257          _DeclClass(0, $1.string);
258
259       FreeIdentifier($1);
260
261       fileInput.Seek(@1.start.pos, start); 
262       resetScannerPos(&@1.start);
263       yyclearin;
264
265       YYPOPSTACK(1);
266       yystate = *yyssp;
267       YY_STACK_PRINT (yyss, yyssp);
268       YYPOPSTACK(1);
269       yystate = *yyssp;
270       YY_STACK_PRINT (yyss, yyssp);
271       goto yysetstate;
272    #endif
273    }
274    ;
275
276 real_guess_type:
277    identifier error
278    {
279       DeclClass(0, $1.string);
280       fileInput.Seek(@1.start.pos, start); 
281       parseTypeError = 0;
282       resetScannerPos(&@1.start);
283       yyclearin;
284       FreeIdentifier($1);
285
286       YYPOPSTACK(1);
287       yystate = *yyssp;
288       YY_STACK_PRINT (yyss, yyssp);
289       YYPOPSTACK(1);
290       yystate = *yyssp;
291       YY_STACK_PRINT (yyss, yyssp);
292       goto yysetstate;
293    }
294 /*   | identifier '<'
295    {
296    #ifdef PRECOMPILER
297       // if($1._class && !$1._class.name)
298       if($1._class)
299       {
300          char name[1024];
301          strcpy(name,  $1._class.name ? $1._class.name : "");
302          strcat(name, "::");
303          strcat(name, $1.string);
304          _DeclClass(0, name);
305       }
306       else
307          _DeclClass(0, $1.string);
308
309       FreeIdentifier($1);
310
311       fileInput.Seek(@1.start.pos, start); 
312       resetScannerPos(&@1.start);
313       yyclearin;
314
315       YYPOPSTACK(1);
316       yystate = *yyssp;
317       YY_STACK_PRINT (yyss, yyssp);
318       YYPOPSTACK(1);
319       yystate = *yyssp;
320       YY_STACK_PRINT (yyss, yyssp);
321       goto yysetstate;
322    #endif
323    }
324    ;
325 */
326 type:
327    strict_type       { $$ = $1; }
328    | identifier identifier
329    {
330    #ifdef PRECOMPILER
331       DeclClass(0, $1.string);
332       fileInput.Seek(@1.start.pos, start); 
333       resetScannerPos(&@1.start);
334       yyclearin;
335
336       FreeIdentifier($1);
337       FreeIdentifier($2);
338
339       YYPOPSTACK(1);
340       yystate = *yyssp;
341       YY_STACK_PRINT (yyss, yyssp);
342       YYPOPSTACK(1);
343       yystate = *yyssp;
344       YY_STACK_PRINT (yyss, yyssp);
345       goto yysetstate;
346    #else
347       Location tmpLoc = yylloc; $$ = $2; yylloc = @1; 
348       Compiler_Error($"Not a type: %s\n", $1.string);      
349       yylloc = tmpLoc; $2.badID = $1; // FreeIdentifier($1);
350    #endif
351    }
352    ;
353
354 base_strict_type:
355      TYPE_NAME    { $$ = MkSpecifierName(yytext); }
356    ;
357
358 strict_type:
359      base_strict_type
360     | base_strict_type '<' template_arguments_list '>' { $$ = $1; SetClassTemplateArgs($$, $3); $$.loc = @$; }
361     | base_strict_type '<' template_arguments_list RIGHT_OP 
362     {
363       $$ = $1;
364       SetClassTemplateArgs($$, $3);
365       $$.loc = @$;
366
367       @4.end.pos--;
368       fileInput.Seek(@4.end.pos, start); 
369       resetScannerPos(&@4.end);
370       yyclearin;
371     }
372
373 /*  | identifier '<' template_arguments_list '>'
374       { $$ = MkSpecifierNameArgs($1.string, $3); $$.loc = @$; FreeIdentifier($1); } */
375    ;
376
377 class_function_definition_start:
378      guess_declaration_specifiers declarator_function
379       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
380    | declarator_function
381       { $$ = MkClassFunction(null, null, $1, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
382    ;
383
384 constructor_function_definition_start:
385    guess_declaration_specifiers '(' ')'
386       { $$ = MkClassFunction(null, null, null, null); $$.isConstructor = true; $$.loc = @$; $$.id = ++globalContext.nextID; FreeList /*FreeSpecifier*/($1, FreeSpecifier); }
387    ;
388
389 destructor_function_definition_start:
390    '~' guess_declaration_specifiers '(' ')'
391       { $$ = MkClassFunction(null, null, null, null); $$.isDestructor = true; $$.loc = @$; $$.id = ++globalContext.nextID; FreeList /*FreeSpecifier*/($2, FreeSpecifier); }
392    ;
393
394 virtual_class_function_definition_start:
395      VIRTUAL guess_declaration_specifiers declarator_function
396       { $$ = MkClassFunction($2, null, $3, null); $$.isVirtual = true; $$.loc = @$; $$.id = ++globalContext.nextID; }
397    | VIRTUAL declarator_function
398       { $$ = MkClassFunction(null, null, $2, null); $$.isVirtual = true; $$.loc = @$; $$.id = ++globalContext.nextID; }
399       ;
400
401 identifier:
402    IDENTIFIER
403       { $$ = MkIdentifier(yytext); $$.loc = @1; }
404    ;
405
406 primary_expression:
407      simple_primary_expression
408         | '(' expression ')'
409       { $$ = MkExpBrackets($2); $$.loc = @$; }
410    ;
411
412 simple_primary_expression:
413           identifier
414       { $$ = MkExpIdentifier($1); $$.loc = @$; }
415    | instantiation_unnamed
416       { $$ = MkExpInstance($1); $$.loc = @$; }
417         | CONSTANT
418       { $$ = MkExpConstant(yytext); $$.loc = @$; }
419         | string_literal
420       { $$ = MkExpString($1); delete $1; $$.loc = @$; }
421    | '$' string_literal     { $$ = MkExpIntlString($2, null); delete $2; $$.loc = @$; }
422    | '$' string_literal '.' string_literal     { $$ = MkExpIntlString($4, $2); delete $2; delete $4; $$.loc = @$; }
423    | '(' ')'
424       { Expression exp = MkExpDummy(); exp.loc.start = @1.end; exp.loc.end = @2.start; $$ = MkExpBrackets(MkListOne(exp)); $$.loc = @$; yyerror(); }
425
426    | NEWOP guess_declaration_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpNew(MkTypeName($2,$3), $5); $$.loc = @$; }
427    | NEWOP guess_declaration_specifiers '[' constant_expression ']' { $$ = MkExpNew(MkTypeName($2,null), $4); $$.loc = @$; }
428    | NEW0OP guess_declaration_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpNew0(MkTypeName($2,$3), $5); $$.loc = @$; }
429    | NEW0OP guess_declaration_specifiers '[' constant_expression ']' { $$ = MkExpNew0(MkTypeName($2,null), $4); $$.loc = @$; }
430    | RENEW constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpRenew($2, MkTypeName($3,$4), $6); $$.loc = @$; }
431    | RENEW constant_expression renew_specifiers '[' constant_expression ']' { $$ = MkExpRenew($2, MkTypeName($3,null), $5); $$.loc = @$; }
432    | RENEW0 constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpRenew0($2, MkTypeName($3,$4), $6); $$.loc = @$; }
433    | RENEW0 constant_expression renew_specifiers '[' constant_expression ']' { $$ = MkExpRenew0($2, MkTypeName($3,null), $5); $$.loc = @$; }
434    | error { $$ = MkExpDummy(); }
435    ;
436
437 postfix_expression:
438           primary_expression
439    | postfix_expression '[' expression ']'               { $$ = MkExpIndex($1, $3); $$.loc = @$; }
440         | postfix_expression '(' ')'                          { $$ = MkExpCall($1, MkList()); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @3.end; $$.loc = @$; }
441         | postfix_expression '(' argument_expression_list ')' { $$ = MkExpCall($1, $3); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @4.end; $$.loc = @$; }
442         | postfix_expression '.' identifier                   { $$ = MkExpMember($1, $3); $$.loc = @$; }
443         | postfix_expression PTR_OP identifier                { $$ = MkExpPointer($1, $3); $$.loc = @$; }
444         | postfix_expression INC_OP                           { $$ = MkExpOp($1, INC_OP, null); $$.loc = @$; }
445         | postfix_expression DEC_OP                           { $$ = MkExpOp($1, DEC_OP, null); $$.loc = @$; }
446         ;
447
448 anon_instantiation_expression:
449    instantiation_anon            { $$ = MkExpInstance($1); $$.loc = @$; }
450    ;
451
452
453 simple_postfix_expression:
454           simple_primary_expression
455    | simple_postfix_expression '[' expression ']'               { $$ = MkExpIndex($1, $3); $$.loc = @$; }
456         | simple_postfix_expression '(' ')'                          { $$ = MkExpCall($1, MkList()); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @3.end; $$.loc = @$; }
457         | simple_postfix_expression '(' argument_expression_list ')' { $$ = MkExpCall($1, $3); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @4.end; $$.loc = @$; }
458         | simple_postfix_expression '.' identifier                   { $$ = MkExpMember($1, $3); $$.loc = @$; }
459         | simple_postfix_expression PTR_OP identifier                { $$ = MkExpPointer($1, $3); $$.loc = @$; }
460         | simple_postfix_expression INC_OP                           { $$ = MkExpOp($1, INC_OP, null); $$.loc = @$; }
461         | simple_postfix_expression DEC_OP                           { $$ = MkExpOp($1, DEC_OP, null); $$.loc = @$; }
462         ;
463
464 argument_expression_list:
465           assignment_expression          { $$ = MkList(); ListAdd($$, $1); }
466    | anon_instantiation_expression  { $$ = MkList(); ListAdd($$, $1); }
467         | argument_expression_list ',' assignment_expression   { $$ = $1; ListAdd($1, $3);  }
468    | argument_expression_list ',' anon_instantiation_expression   { $$ = $1; ListAdd($1, $3);  }
469         ;
470
471 common_unary_expression:
472           INC_OP unary_expression           { $$ = MkExpOp(null, INC_OP, $2); $$.loc = @$; }
473         | DEC_OP unary_expression           { $$ = MkExpOp(null, DEC_OP, $2); $$.loc = @$; }
474         | unary_operator cast_expression    { $$ = MkExpOp(null, $1, $2); $$.loc = @$; }
475         | SIZEOF '(' unary_expression ')'         { $$ = MkExpOp(null, SIZEOF, $3); $$.loc = @$; }
476    | SIZEOF simple_unary_expression          { $$ = MkExpOp(null, SIZEOF, $2); $$.loc = @$; }
477    | SIZEOF '(' guess_type_name ')'          { $$ = MkExpTypeSize($3); $$.loc = @$; }
478         | ALIGNOF '(' unary_expression ')'         { $$ = MkExpOp(null, ALIGNOF, $3); $$.loc = @$; }
479    | ALIGNOF simple_unary_expression          { $$ = MkExpOp(null, ALIGNOF, $2); $$.loc = @$; }
480    | ALIGNOF '(' guess_type_name ')'          { $$ = MkExpTypeAlign($3); $$.loc = @$; }
481    ;
482
483 unary_expression:
484        common_unary_expression
485           | postfix_expression
486         ;
487
488 simple_unary_expression:
489      common_unary_expression
490         | simple_postfix_expression
491         ;
492
493 unary_operator:
494           '&'     { $$ = '&'; }
495         | '*'     { $$ = '*'; }
496         | '+'     { $$ = '+'; }
497         | '-'     { $$ = '-'; }
498         | '~'     { $$ = '~'; }
499         | '!'     { $$ = '!'; }
500    | DELETE  { $$ = DELETE; }
501         ;
502
503 cast_expression:
504      unary_expression
505         | '(' type_name ')' cast_expression    { $$ = MkExpCast($2, $4); $$.loc = @$; }
506         ;
507
508 multiplicative_expression:
509           cast_expression
510         | multiplicative_expression '*' cast_expression { $$ = MkExpOp($1, '*', $3); $$.loc = @$; }
511         | multiplicative_expression '/' cast_expression { $$ = MkExpOp($1, '/', $3); $$.loc = @$; }
512         | multiplicative_expression '%' cast_expression { $$ = MkExpOp($1, '%', $3); $$.loc = @$; }
513         ;
514
515 additive_expression:
516           multiplicative_expression
517         | additive_expression '+' multiplicative_expression  { $$ = MkExpOp($1, '+', $3); $$.loc = @$; }
518         | additive_expression '-' multiplicative_expression  { $$ = MkExpOp($1, '-', $3); $$.loc = @$; }
519         ;
520
521 shift_expression:
522           additive_expression
523         | shift_expression LEFT_OP additive_expression  { $$ = MkExpOp($1, LEFT_OP, $3); $$.loc = @$; }
524         | shift_expression RIGHT_OP additive_expression { $$ = MkExpOp($1, RIGHT_OP, $3); $$.loc = @$; }
525         ;
526
527 relational_expression_smaller_than:
528    relational_expression '<'
529    {
530       $$ = $1;
531       skipErrors = true;
532    }
533    ;
534
535 relational_expression:
536           shift_expression
537         | relational_expression_smaller_than /*relational_expression '<' */ shift_expression    { skipErrors = false; $$ = MkExpOp($1, '<', $2/*$3*/); $$.loc = @$; }
538         | relational_expression '>' shift_expression    { $$ = MkExpOp($1, '>', $3); $$.loc = @$; }
539         | relational_expression LE_OP shift_expression  { $$ = MkExpOp($1, LE_OP, $3); $$.loc = @$; }
540         | relational_expression GE_OP shift_expression  { $$ = MkExpOp($1, GE_OP, $3); $$.loc = @$; }
541         ;
542
543 equality_expression:
544           relational_expression
545         | equality_expression EQ_OP relational_expression  { $$ = MkExpOp($1, EQ_OP, $3); $$.loc = @$; }
546         | equality_expression NE_OP relational_expression  { $$ = MkExpOp($1, NE_OP, $3); $$.loc = @$; }
547         ;
548
549 and_expression:
550           equality_expression
551         | and_expression '&' equality_expression  { $$ = MkExpOp($1, '&', $3); $$.loc = @$; }
552         ;
553
554 exclusive_or_expression:
555           and_expression
556         | exclusive_or_expression '^' and_expression { $$ = MkExpOp($1, '^', $3); $$.loc = @$; }
557         ;
558
559 inclusive_or_expression:
560           exclusive_or_expression
561         | inclusive_or_expression '|' exclusive_or_expression { $$ = MkExpOp($1, '|', $3); $$.loc = @$; }
562         ;
563
564 logical_and_expression:
565           inclusive_or_expression
566         | logical_and_expression AND_OP inclusive_or_expression  { $$ = MkExpOp($1, AND_OP, $3); $$.loc = @$; }
567         ;
568
569 logical_or_expression:
570           logical_and_expression
571         | logical_or_expression OR_OP logical_and_expression     { $$ = MkExpOp($1, OR_OP, $3); $$.loc = @$; }
572         ;
573
574 conditional_expression:
575           logical_or_expression
576         | logical_or_expression '?' expression ':' conditional_expression { $$ = MkExpCondition($1, $3, $5); $$.loc = @$; }
577         ;
578
579 assignment_expression:
580           conditional_expression
581         | unary_expression assignment_operator assignment_expression   { $$ = MkExpOp($1, $2, $3); $$.loc = @$; }
582         | unary_expression assignment_operator anon_instantiation_expression   { $$ = MkExpOp($1, $2, $3); $$.loc = @$; }
583    ;
584
585 assignment_operator:
586           '='                   { $$ = '='; }
587         | MUL_ASSIGN            { $$ = MUL_ASSIGN; }
588         | DIV_ASSIGN            { $$ = DIV_ASSIGN; }
589         | MOD_ASSIGN            { $$ = MOD_ASSIGN; }
590         | ADD_ASSIGN            { $$ = ADD_ASSIGN; }
591         | SUB_ASSIGN            { $$ = SUB_ASSIGN; }
592         | LEFT_ASSIGN           { $$ = LEFT_ASSIGN; }
593         | RIGHT_ASSIGN          { $$ = RIGHT_ASSIGN; }
594         | AND_ASSIGN            { $$ = AND_ASSIGN; }
595         | XOR_ASSIGN            { $$ = XOR_ASSIGN; }
596         | OR_ASSIGN             { $$ = OR_ASSIGN; }
597         ;
598
599 expression:
600      assignment_expression                 { $$ = MkList(); ListAdd($$, $1); }
601         | expression ',' assignment_expression  { $$ = $1; ListAdd($1, $3); }
602         ;
603
604 constant_expression:
605           conditional_expression
606         ;
607
608 declaration:
609           declaration_specifiers ';'                       { $$ = MkDeclaration($1, null); $$.loc = @$; }
610         | declaration_specifiers init_declarator_list ';'  { $$ = MkDeclaration($1, $2); $$.loc = @$; }
611    | instantiation_named ';'                          { $$ = MkDeclarationInst($1); $$.loc = @$; }
612    | DEFINE identifier '=' constant_expression ';'           { $$ = MkDeclarationDefine($2, $4); $$.loc = @$; }
613         ;
614
615 specifier_qualifier_list:
616      type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
617    | specifier_qualifier_list  type_qualifier            { $$ = $1; ListAdd($1, $2); }
618    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
619    | specifier_qualifier_list  type_specifier            { $$ = $1; ListAdd($1, $2); }
620    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
621         | specifier_qualifier_list enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
622    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
623         | specifier_qualifier_list struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
624    ;
625
626 guess_specifier_qualifier_list:
627      type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
628    | guess_specifier_qualifier_list  type_qualifier            { $$ = $1; ListAdd($1, $2); }
629    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
630    | guess_specifier_qualifier_list  type_specifier            { $$ = $1; ListAdd($1, $2); }
631    | guess_type                                       { $$ = MkList(); ListAdd($$, $1); }
632    | guess_specifier_qualifier_list  guess_type            { $$ = $1; ListAdd($1, $2); }
633    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
634         | guess_specifier_qualifier_list enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
635    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
636         | guess_specifier_qualifier_list struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
637    ;
638
639 declaration_specifiers:
640      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
641    | declaration_specifiers storage_class_specifier    { $$ = $1; ListAdd($1, $2); }
642    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
643    | declaration_specifiers  type_qualifier            { $$ = $1; ListAdd($1, $2); }
644    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
645    | declaration_specifiers  type_specifier            { $$ = $1; ListAdd($1, $2); }
646    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
647         | declaration_specifiers enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
648    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
649         | declaration_specifiers struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
650    ;
651
652 guess_declaration_specifiers:
653      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
654    | guess_declaration_specifiers storage_class_specifier    { $$ = $1; ListAdd($1, $2); }
655    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
656    | guess_declaration_specifiers  type_qualifier            { $$ = $1; ListAdd($1, $2); }
657    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
658    | guess_declaration_specifiers  type_specifier            { $$ = $1; ListAdd($1, $2); }
659    | guess_type                                       { $$ = MkList(); ListAdd($$, $1); }
660         | guess_declaration_specifiers guess_type          { $$ = $1; ListAdd($1, $2); }
661    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
662         | guess_declaration_specifiers struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
663    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
664         | guess_declaration_specifiers enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
665    ;
666
667 real_guess_declaration_specifiers:
668        guess_declaration_specifiers                          { $$ = $1; }
669      | real_guess_type                                       { $$ = MkList(); ListAdd($$, $1); }
670    ;
671
672 property_specifiers:
673      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
674    | property_specifiers storage_class_specifier     { $$ = $1; ListAdd($1, $2); }
675    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
676    | property_specifiers type_qualifier            { $$ = $1; ListAdd($1, $2); }
677    | strict_type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
678    | property_specifiers strict_type_specifier            { $$ = $1; ListAdd($1, $2); }
679    | identifier                        { $$ = MkList(); ListAdd($$, MkSpecifierName($1.string)); FreeIdentifier($1); }
680    | property_specifiers identifier          { ListAdd($1, MkSpecifierName($2.string)); FreeIdentifier($2); }
681    | identifier '<' template_arguments_list '>'
682       {
683          // if($1._class && !$1._class.name)
684          if($1._class)
685          {
686             char name[1024];
687             strcpy(name,  $1._class.name ? $1._class.name : "");
688             strcat(name, "::");
689             strcat(name, $1.string);
690             _DeclClass(0, name);
691          }
692          else
693             _DeclClass(0, $1.string);
694
695          $$ = MkList();
696          ListAdd($$, MkSpecifierNameArgs($1.string, $3));
697          FreeIdentifier($1);
698       }
699    | property_specifiers identifier '<' template_arguments_list '>'
700       {
701          if($2._class && !$2._class.name)
702          {
703             char name[1024];
704             strcpy(name, "::");
705             strcat(name, $2.string);
706             _DeclClass(0, name);
707          }
708          else
709             _DeclClass(0, $2.string);
710          ListAdd($1, MkSpecifierNameArgs($2.string, $4));
711          FreeIdentifier($2);
712       }
713    ;
714
715 renew_specifiers:
716      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
717    | renew_specifiers storage_class_specifier    { $$ = $1; ListAdd($1, $2); }
718    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
719    | renew_specifiers type_qualifier            { $$ = $1; ListAdd($1, $2); }
720    | strict_type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
721    | renew_specifiers strict_type_specifier            { $$ = $1; ListAdd($1, $2); }
722    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
723         | renew_specifiers struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
724    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
725         | renew_specifiers enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
726    | identifier                        { $$ = MkList(); ListAdd($$, MkSpecifierName($1.string)); FreeIdentifier($1); }
727    | renew_specifiers identifier          { $$ = $1; ListAdd($1, MkSpecifierName($2.string)); FreeIdentifier($2)}
728    | identifier '<' template_arguments_list '>'
729       {
730          // if($1._class && !$1._class.name)
731          if($1._class)
732          {
733             char name[1024];
734             strcpy(name,  $1._class.name ? $1._class.name : "");
735             strcat(name, "::");
736             strcat(name, $1.string);
737             _DeclClass(0, name);
738          }
739          else
740             _DeclClass(0, $1.string);
741
742          $$ = MkList();
743          ListAdd($$, MkSpecifierNameArgs($1.string, $3));
744          FreeIdentifier($1);
745       }
746    | renew_specifiers identifier '<' template_arguments_list '>'
747       {
748          if($2._class && !$2._class.name)
749          {
750             char name[1024];
751             strcpy(name, "::");
752             strcat(name, $2.string);
753             _DeclClass(0, name);
754          }
755          else
756             _DeclClass(0, $2.string);
757          ListAdd($1, MkSpecifierNameArgs($2.string, $4));
758          FreeIdentifier($2);
759       }
760    ;
761
762 init_declarator_list:
763           init_declarator                            { $$ = MkList(); ListAdd($$, $1); }
764         | init_declarator_list ',' init_declarator   { $$ = $1; ListAdd($1, $3); }
765         ;
766
767 init_declarator:
768           declarator                        { $$ = MkInitDeclarator($1, null); $$.loc = @$; }
769         | declarator '=' initializer                 { $$ = MkInitDeclarator($1, $3); $$.loc = @$; $$.initializer.loc.start = @2.end; }
770         ;
771
772 storage_class_specifier:
773           TYPEDEF       { $$ = MkSpecifier(TYPEDEF); }
774         | EXTERN        { $$ = MkSpecifier(EXTERN); }
775         | STATIC        { $$ = MkSpecifier(STATIC); }
776         | AUTO          { $$ = MkSpecifier(AUTO); }
777         | REGISTER      { $$ = MkSpecifier(REGISTER); }
778         ;
779
780 ext_decl:
781      EXT_DECL { $$ = MkExtDeclString(CopyString(yytext)); }
782    | attrib { $$ = MkExtDeclAttrib($1); }
783    ;
784
785 _attrib:
786    ATTRIB      { $<i>$ = ATTRIB; }
787  | ATTRIB_DEP  { $<i>$ = ATTRIB_DEP; }
788  | __ATTRIB    { $<i>$ = __ATTRIB; }
789  ;
790
791
792 attribute_word: 
793      IDENTIFIER   { $$  = CopyString(yytext); } 
794    | TYPE_NAME    { $$  = CopyString(yytext); } 
795    | EXT_STORAGE  { $$  = CopyString(yytext); } 
796    | EXT_DECL     { $$  = CopyString(yytext); } 
797    | CONST        { $$  = CopyString(yytext); }
798    ;
799
800 attribute:
801      attribute_word  { $$ = MkAttribute($1, null); $$.loc = @$; }
802    | attribute_word '(' expression ')'  { $$ = MkAttribute($1, MkExpBrackets($3)); $$.loc = @$; }
803    ;   
804
805 attribs_list:
806      attribute { $$ = MkListOne($1); }
807    | attribs_list attribute { ListAdd($1, $2); $$ = $1; }
808    | attribs_list ',' attribute { ListAdd($1, $3); $$ = $1; }
809    ;
810
811 attrib:
812      _attrib '(' '(' attribs_list ')' ')' { $$ = MkAttrib($<i>1, $4); $$.loc = @$; }
813    | _attrib '(' '('              ')' ')'  { $$ = MkAttrib($<i>1, null); $$.loc = @$; }
814    ;   
815
816 ext_storage:
817      EXT_STORAGE  { $$ = MkSpecifierExtended(MkExtDeclString(CopyString(yytext))); }
818    | ext_decl   { $$ = MkSpecifierExtended($1); }
819    ;
820
821 type_qualifier:
822           CONST        { $$ = MkSpecifier(CONST); }
823         | VOLATILE     { $$ = MkSpecifier(VOLATILE); }
824    | ext_storage  { $$ = $1; }
825         ;
826
827
828 type_specifier:
829           VOID            { $$ = MkSpecifier(VOID); }  
830         | CHAR            { $$ = MkSpecifier(CHAR); }
831         | SHORT           { $$ = MkSpecifier(SHORT); }
832         | INT             { $$ = MkSpecifier(INT); }
833    | UINT            { $$ = MkSpecifier(UINT); }
834    | INT64           { $$ = MkSpecifier(INT64); }
835    | VALIST          { $$ = MkSpecifier(VALIST); }
836         | LONG            { $$ = MkSpecifier(LONG); }
837         | FLOAT           { $$ = MkSpecifier(FLOAT); }
838         | DOUBLE          { $$ = MkSpecifier(DOUBLE); }
839         | SIGNED          { $$ = MkSpecifier(SIGNED); }
840         | UNSIGNED        { $$ = MkSpecifier(UNSIGNED); }
841    | EXTENSION       { $$ = MkSpecifier(EXTENSION); }
842         | struct_or_union_specifier_nocompound
843         | enum_specifier_nocompound
844         | type
845    | SUBCLASS '(' type ')'                { $$ = MkSpecifierSubClass($3); }
846    | SUBCLASS '(' identifier ')'          { DeclClass(0, $3.string); $$ = MkSpecifierSubClass(MkSpecifierName($3.string)); FreeIdentifier($3); }
847    | THISCLASS       { $$ = MkSpecifier(THISCLASS); }
848         ;
849
850 strict_type_specifier:
851           VOID            { $$ = MkSpecifier(VOID); }  
852         | CHAR            { $$ = MkSpecifier(CHAR); }
853         | SHORT           { $$ = MkSpecifier(SHORT); }
854         | INT             { $$ = MkSpecifier(INT); }
855    | UINT            { $$ = MkSpecifier(UINT); }
856    | INT64           { $$ = MkSpecifier(INT64); }
857    | VALIST          { $$ = MkSpecifier(VALIST); }
858         | LONG            { $$ = MkSpecifier(LONG); }
859         | FLOAT           { $$ = MkSpecifier(FLOAT); }
860         | DOUBLE          { $$ = MkSpecifier(DOUBLE); }
861         | SIGNED          { $$ = MkSpecifier(SIGNED); }
862         | UNSIGNED        { $$ = MkSpecifier(UNSIGNED); }
863         | struct_or_union_specifier_nocompound
864         | enum_specifier_nocompound
865         | strict_type
866    | SUBCLASS '(' type ')'                { $$ = MkSpecifierSubClass($3); }
867    | SUBCLASS '(' identifier ')'          { DeclClass(0, $3.string); $$ = MkSpecifierSubClass(MkSpecifierName($3.string)); FreeIdentifier($3); }
868    | THISCLASS       { $$ = MkSpecifier(THISCLASS); }
869         ;
870
871
872 struct_or_union_specifier_compound:
873           struct_or_union identifier '{' struct_declaration_list '}'   { $$ = MkStructOrUnion($1, $2, $4); if(declMode) DeclClass(globalContext.nextID++, $2.string); }
874         | struct_or_union '{' struct_declaration_list '}'              { $$ = MkStructOrUnion($1, null, $3); }
875    | struct_or_union identifier '{' '}'   { $$ = MkStructOrUnion($1, $2, null); if(declMode) DeclClass(globalContext.nextID++, $2.string); }
876    | struct_or_union '{' '}'              { $$ = MkStructOrUnion($1, null, null); }
877         | struct_or_union base_strict_type '{' struct_declaration_list '}'
878       { $$ = MkStructOrUnion($1, MkIdentifier($2.name), $4); if(declMode) DeclClass(globalContext.nextID++, $2.name); FreeSpecifier($2); }
879
880         | struct_or_union ext_decl identifier '{' struct_declaration_list '}'   { $$ = MkStructOrUnion($1, $3, $5); $$.extDeclStruct = $2; if(declMode) DeclClass(globalContext.nextID++, $3.string); }
881         | struct_or_union ext_decl '{' struct_declaration_list '}'              { $$ = MkStructOrUnion($1, null, $4); $$.extDeclStruct = $2; }
882    | struct_or_union ext_decl identifier '{' '}'   { $$ = MkStructOrUnion($1, $3, null); $$.extDeclStruct = $2; if(declMode) DeclClass(globalContext.nextID++, $3.string); }
883    | struct_or_union ext_decl '{' '}'              { $$ = MkStructOrUnion($1, null, null); $$.extDeclStruct = $2; }
884         | struct_or_union ext_decl strict_type '{' struct_declaration_list '}'
885       { $$ = MkStructOrUnion($1, MkIdentifier($3.name), $5); $$.extDeclStruct = $2; if(declMode) DeclClass(globalContext.nextID++, $3.name); FreeSpecifier($3); }
886         ;
887
888 struct_or_union_specifier_nocompound:
889           struct_or_union identifier                                   { $$ = MkStructOrUnion($1, $2, null); if(declMode) DeclClass(0, $2.string); }
890         | struct_or_union strict_type
891       { $$ = MkStructOrUnion($1, MkIdentifier($2.name), null); if(declMode) DeclClass(0, $2.name); FreeSpecifier($2); }
892
893         | struct_or_union ext_decl identifier
894       { $$ = MkStructOrUnion($1, $3, null); $$.extDeclStruct = $2;if(declMode) DeclClass(0, $3.string); }
895         | struct_or_union ext_decl strict_type
896       { $$ = MkStructOrUnion($1, MkIdentifier($3.name), null); $$.extDeclStruct = $2; if(declMode) DeclClass(0, $3.name); FreeSpecifier($3); }
897         ;
898
899 template_datatype:
900      declaration_specifiers { $$ = MkTemplateDatatype($1, null); }
901    | declaration_specifiers abstract_declarator { $$ = MkTemplateDatatype($1, $2); }
902    /*| identifier { $$ = MkTemplateDatatype(MkListOne(MkSpecifierName($1.string)), null); FreeIdentifier($1); }*/
903    ;
904
905 template_type_argument:
906      template_datatype { $$ = MkTemplateTypeArgument($1); }
907    ;
908
909 /*
910 template_identifier_argument:
911      identifier { $$ = MkTemplateIdentifierArgument($1); }
912    ;
913 */
914
915 template_expression_argument:
916      shift_expression /*constant_expression*/ { $$ = MkTemplateExpressionArgument($1); }
917    ;
918
919 template_argument:
920      template_expression_argument
921    /*| template_identifier_argument*/
922    | template_type_argument
923    | identifier '=' template_expression_argument   { $$ = $3; $$.name = $1; $$.loc = @$; }
924    /*| identifier '=' template_identifier_argument   { $$ = $3; $$.name = $1; $$.loc = @$; }*/
925    | identifier '=' template_type_argument         { $$ = $3; $$.name = $1; $$.loc = @$; }
926    | template_datatype '=' template_expression_argument 
927    {
928       $$ = $3; 
929       if($1.specifiers && $1.specifiers->first)
930       {
931          Specifier spec = $1.specifiers->first;
932          if(spec.type == nameSpecifier)
933             $$.name = MkIdentifier(spec.name);
934       }
935       FreeTemplateDataType($1);
936       $$.loc = @$;
937    }
938    /*| template_datatype '=' template_identifier_argument
939    {
940       $$ = $3; 
941       if($1.specifiers && $1.specifiers->first)
942       {
943          Specifier spec = $1.specifiers->first;
944          if(spec.type == nameSpecifier)
945             $$.name = MkIdentifier(spec.name);
946       }
947       FreeTemplateDataType($1);
948       $$.loc = @$;
949    } */
950    | template_datatype '=' template_type_argument
951    {
952       $$ = $3; 
953       if($1.specifiers && $1.specifiers->first)
954       {
955          Specifier spec = $1.specifiers->first;
956          if(spec.type == nameSpecifier)
957             $$.name = MkIdentifier(spec.name);
958       }
959       FreeTemplateDataType($1);
960       $$.loc = @$;
961    }
962    ;
963
964 template_arguments_list:
965      template_argument                                { $$ = MkList(); ListAdd($$, $1); }
966    | template_arguments_list ',' template_argument    { ListAdd($1, $3); }
967    ;
968
969 struct_or_union:
970           STRUCT    { $$ = structSpecifier; }
971         | UNION     { $$ = unionSpecifier; }
972         ;
973
974 struct_declaration_list:
975           struct_declaration                            { $$ = MkList(); ListAdd($$, $1); }
976         | struct_declaration_list struct_declaration    { $$ = $1; ListAdd($1, $2); }
977         ;
978
979 default_property:
980      postfix_expression '=' initializer_condition { $$ = MkMemberInitExp($1, $3); $$.loc = @$; $$.realLoc = @$; }
981    ;
982
983 default_property_list:
984      default_property        { $$ = MkList(); ListAdd($$, $1); ((MemberInit)$$->last).loc = @$; }
985    | default_property_list ',' default_property      { ((MemberInit)$1->last).loc.end = @3.start; ListAdd($1, $3); $$ = $1; }
986    ;
987
988 property:
989    PROPERTY property_specifiers identifier '{' SETPROP compound_statement GETPROP compound_statement '}'  
990       { $$ = MkProperty($2, null, $3, $6, $8); $$.loc = @$; } 
991    | PROPERTY property_specifiers identifier '{' GETPROP compound_statement SETPROP compound_statement '}'  
992       { $$ = MkProperty($2, null, $3, $8, $6); $$.loc = @$; }
993    | PROPERTY property_specifiers identifier '{' SETPROP compound_statement '}'  
994       { $$ = MkProperty($2, null, $3, $6, null); $$.loc = @$; }
995    | PROPERTY property_specifiers identifier '{' GETPROP compound_statement '}'
996       { $$ = MkProperty($2, null, $3, null, $6); $$.loc = @$; }
997    | PROPERTY property_specifiers identifier '{' '}'
998       { $$ = MkProperty($2, null, $3, null, null); $$.loc = @$; }
999
1000    | PROPERTY property_specifiers abstract_declarator identifier '{' SETPROP compound_statement GETPROP compound_statement '}'  
1001       { $$ = MkProperty($2, $3, $4, $7, $9); $$.loc = @$; }
1002    | PROPERTY property_specifiers abstract_declarator identifier '{' GETPROP compound_statement SETPROP compound_statement '}'  
1003       { $$ = MkProperty($2, $3, $4, $9, $7); $$.loc = @$; }
1004    | PROPERTY property_specifiers abstract_declarator identifier '{' SETPROP compound_statement '}'  
1005       { $$ = MkProperty($2, $3, $4, $7, null); $$.loc = @$; }
1006    | PROPERTY property_specifiers abstract_declarator identifier '{' GETPROP compound_statement '}'
1007       { $$ = MkProperty($2, $3, $4, null, $7); $$.loc = @$; }
1008    | PROPERTY property_specifiers abstract_declarator identifier '{' '}'
1009       { $$ = MkProperty($2, $3, $4, null, null); $$.loc = @$; }
1010
1011    | PROPERTY property_specifiers '{' SETPROP compound_statement GETPROP compound_statement '}'  
1012       { $$ = MkProperty($2, null, null, $5, $7); $$.loc = @$; }
1013    | PROPERTY property_specifiers '{' GETPROP compound_statement SETPROP compound_statement '}'  
1014       { $$ = MkProperty($2, null, null, $7, $5); $$.loc = @$; }
1015    | PROPERTY property_specifiers '{' SETPROP compound_statement '}'  
1016       { $$ = MkProperty($2, null, null, $5, null); $$.loc = @$; }
1017    | PROPERTY property_specifiers '{' GETPROP compound_statement '}'
1018       { $$ = MkProperty($2, null, null, null, $5); $$.loc = @$; }
1019    | PROPERTY property_specifiers '{' '}'
1020       { $$ = MkProperty($2, null, null, null, null); $$.loc = @$; }
1021
1022    | PROPERTY property_specifiers abstract_declarator '{' SETPROP compound_statement GETPROP compound_statement '}'  
1023       { $$ = MkProperty($2, $3, null, $6, $8); $$.loc = @$; }
1024    | PROPERTY property_specifiers abstract_declarator '{' GETPROP compound_statement SETPROP compound_statement '}'  
1025       { $$ = MkProperty($2, $3, null, $8, $6); $$.loc = @$; }
1026    | PROPERTY property_specifiers abstract_declarator '{' SETPROP compound_statement '}'  
1027       { $$ = MkProperty($2, $3, null, $6, null); $$.loc = @$; }
1028    | PROPERTY property_specifiers abstract_declarator '{' GETPROP compound_statement '}'
1029       { $$ = MkProperty($2, $3, null, null, $6); $$.loc = @$; }
1030    | PROPERTY property_specifiers abstract_declarator '{' '}'
1031       { $$ = MkProperty($2, $3, null, null, null); $$.loc = @$; }
1032 ;
1033
1034 struct_declaration:
1035           guess_declaration_specifiers struct_declarator_list ';'         { $$ = MkClassDefDeclaration(MkStructDeclaration($1, $2, null)); $$.decl.loc = @$; $$.loc = @$; }
1036    | guess_declaration_specifiers ';'                                { $$ = MkClassDefDeclaration(MkStructDeclaration($1, null, null)); $$.decl.loc = @$; $$.loc = @$; }
1037    | instantiation_unnamed ';'                                       { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; }
1038    | guess_instantiation_named ';'                                   { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; }
1039    | class_function_definition                                       { $$ = MkClassDefFunction($1); $$.loc = @$; }
1040    | default_property_list ';' { $$ = MkClassDefDefaultProperty($1); if($1->last) ((MemberInit)$1->last).loc.end = @2.start; $$.loc = @$; }
1041    | property { $$ = MkClassDefProperty($1); $$.loc = @$; globalContext.nextID++; }
1042    | ';' { $$ = null; }
1043         ;
1044
1045 struct_declarator_list:
1046           struct_declarator
1047       { $$ = MkList(); ListAdd($$, $1); }
1048         | struct_declarator_list ',' struct_declarator
1049       { $$ = $1; ListAdd($1, $3); }
1050         ;
1051
1052 struct_declarator:
1053           declarator_nofunction
1054       { $$ = MkStructDeclarator($1, null); $$.loc = @$; }  
1055         | declarator_nofunction attrib
1056       { $$ = MkStructDeclarator($1, null); $$.structDecl.attrib = $2; $$.loc = @$; }  
1057         | ':' constant_expression
1058       { $$ = MkStructDeclarator(null, $2);  $$.loc = @$; }
1059         | declarator_nofunction ':' constant_expression
1060       { $$ = MkStructDeclarator($1, $3);  $$.loc = @$; }
1061    | declarator_nofunction ':' constant_expression ':' constant_expression
1062       { $$ = MkStructDeclarator($1, $3); $$.structDecl.posExp = $5; $$.loc = @$; }
1063         ;
1064
1065 enum_specifier_nocompound:
1066      ENUM identifier                            { $$ = MkEnum($2, null); if(declMode) DeclClass(0, $2.string); }
1067    | ENUM strict_type                           { $$ = MkEnum(MkIdentifier($2.name), null); if(declMode) DeclClass(0, $2.name); FreeSpecifier($2); }
1068    ;
1069
1070 enum_specifier_compound:
1071           ENUM '{' enumerator_list '}'               
1072       { $$ = MkEnum(null, $3); }
1073         | ENUM identifier '{' enumerator_list '}'    { $$ = MkEnum($2, $4); if(declMode) DeclClass(globalContext.nextID++, $2.string); }
1074    | ENUM identifier '{' enumerator_list ';' struct_declaration_list '}'    { $$ = MkEnum($2, $4); $$.definitions = $6; if(declMode) DeclClass(globalContext.nextID++, $2.string); }
1075         | ENUM strict_type '{' enumerator_list ';' struct_declaration_list '}'          { $$ = MkEnum(MkIdentifier($2.name), $4); $$.definitions = $6; if(declMode) DeclClass(globalContext.nextID++, $2.name); FreeSpecifier($2); }
1076    | ENUM strict_type '{' enumerator_list '}'          { $$ = MkEnum(MkIdentifier($2.name), $4); if(declMode) DeclClass(globalContext.nextID++, $2.name); FreeSpecifier($2); }
1077         ;
1078
1079 enumerator_list:
1080           enumerator
1081       { $$ = MkList(); ListAdd($$, $1); }
1082         | enumerator_list ',' enumerator
1083       { $$ = $1; ListAdd($1, $3); }
1084         ;
1085
1086 enumerator:
1087           identifier
1088       { $$ = MkEnumerator($1, null); }
1089         | identifier '=' constant_expression
1090       { $$ = MkEnumerator($1, $3); }
1091         ;
1092
1093
1094 direct_abstract_declarator:
1095           '(' abstract_declarator ')'
1096                                  { $$ = MkDeclaratorBrackets($2); }
1097         | '[' ']'
1098                                  { $$ = MkDeclaratorArray(null, null); }
1099    | '[' constant_expression ']'
1100                                  { $$ = MkDeclaratorArray(null, $2); }
1101    | '[' type ']'
1102                                  { $$ = MkDeclaratorEnumArray(null, $2); }
1103         | direct_abstract_declarator '[' ']'
1104                                  { $$ = MkDeclaratorArray($1, null); }
1105         | direct_abstract_declarator '[' constant_expression ']'
1106                                  { $$ = MkDeclaratorArray($1, $3); }
1107         | direct_abstract_declarator '[' type']'
1108                                  { $$ = MkDeclaratorEnumArray($1, $3); }
1109         | '(' ')'
1110                                  { $$ = MkDeclaratorFunction(null, null); }
1111         | '(' parameter_type_list ')'
1112                                  { $$ = MkDeclaratorFunction(null, $2); }
1113         | direct_abstract_declarator '(' ')'
1114                                  { $$ = MkDeclaratorFunction($1, null); }
1115         | direct_abstract_declarator '(' parameter_type_list ')'
1116                                  { $$ = MkDeclaratorFunction($1, $3); }
1117         ;
1118
1119 direct_abstract_declarator_noarray:
1120           '(' abstract_declarator_noarray ')'
1121                                  { $$ = MkDeclaratorBrackets($2); }
1122         | '(' ')'
1123                                  { $$ = MkDeclaratorFunction(null, null); }
1124         | '(' parameter_type_list ')'
1125                                  { $$ = MkDeclaratorFunction(null, $2); }
1126         | direct_abstract_declarator_noarray '(' ')'
1127                                  { $$ = MkDeclaratorFunction($1, null); }
1128         | direct_abstract_declarator_noarray '(' parameter_type_list ')'
1129                                  { $$ = MkDeclaratorFunction($1, $3); }
1130         ;
1131
1132 abstract_declarator:
1133           pointer                              { $$ = MkDeclaratorPointer($1, null); }
1134         | direct_abstract_declarator
1135         | pointer direct_abstract_declarator   { $$ = MkDeclaratorPointer($1, $2); }
1136    | ext_decl pointer                     { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
1137    | ext_decl direct_abstract_declarator  { $$ = MkDeclaratorExtended($1, $2); }
1138         | ext_decl pointer direct_abstract_declarator { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
1139         ;
1140
1141 abstract_declarator_noarray:
1142           pointer                              { $$ = MkDeclaratorPointer($1, null); }
1143         | direct_abstract_declarator_noarray
1144         | pointer direct_abstract_declarator_noarray   { $$ = MkDeclaratorPointer($1, $2); }
1145    | ext_decl pointer { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
1146    | ext_decl direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, $2); }
1147         | ext_decl pointer direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
1148         ;
1149
1150 /*
1151 abstract_declarator:
1152           pointer
1153       { $$ = MkDeclaratorPointer($1, null); }
1154         | direct_abstract_declarator
1155         | pointer direct_abstract_declarator
1156       { $$ = MkDeclaratorPointer($1, $2); }
1157    
1158    | ext_decl pointer
1159       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
1160         | ext_decl direct_abstract_declarator
1161       { $$ = MkDeclaratorExtended($1, $2); }
1162         | ext_decl pointer direct_abstract_declarator
1163       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
1164       
1165         ;
1166
1167 direct_abstract_declarator:
1168           '(' abstract_declarator ')'
1169       { $$ = MkDeclaratorBrackets($2); }
1170         | '[' ']'
1171       { $$ = MkDeclaratorArray(null, null); }
1172         | '[' constant_expression ']'
1173       { $$ = MkDeclaratorArray(null, $2); }
1174    | '[' type ']'
1175       { $$ = MkDeclaratorEnumArray(null, $2); }
1176         | direct_abstract_declarator '[' ']'
1177       { $$ = MkDeclaratorArray($1, null); }
1178         | direct_abstract_declarator '[' constant_expression ']'
1179       { $$ = MkDeclaratorArray($1, $3); }
1180         | direct_abstract_declarator '[' type ']'
1181       { $$ = MkDeclaratorEnumArray($1, $3); }
1182         | '(' ')'
1183       { $$ = MkDeclaratorFunction(null, null); }
1184         | '(' parameter_type_list ')'
1185       { $$ = MkDeclaratorFunction(null, $2); }
1186         | direct_abstract_declarator '(' ')'
1187       { $$ = MkDeclaratorFunction($1, null); }
1188         | direct_abstract_declarator '(' parameter_type_list ')'
1189       { $$ = MkDeclaratorFunction($1, $3); }
1190         ;
1191 */
1192 declarator:
1193           direct_declarator
1194         | pointer direct_declarator
1195       { $$ = MkDeclaratorPointer($1, $2); }
1196    | ext_decl pointer direct_declarator
1197       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
1198    | declarator ext_decl
1199       { $$ = MkDeclaratorExtendedEnd($2, $1); }
1200    ;
1201
1202 direct_declarator_nofunction:
1203           identifier
1204       { $$ = MkDeclaratorIdentifier($1); }
1205         | '(' declarator ')'
1206       { $$ = MkDeclaratorBrackets($2); }
1207         | direct_declarator_nofunction '[' constant_expression ']' 
1208       { $$ = MkDeclaratorArray($1, $3); }
1209         | direct_declarator_nofunction '[' ']'
1210       { $$ = MkDeclaratorArray($1, null); }
1211    | direct_declarator_nofunction '[' type ']'
1212       { $$ = MkDeclaratorEnumArray($1, $3); }
1213         ;
1214
1215 declarator_function:
1216      direct_declarator_function
1217         | pointer direct_declarator_function
1218       { $$ = MkDeclaratorPointer($1, $2); }
1219      
1220    | ext_decl direct_declarator_function
1221       { $$ = MkDeclaratorExtended($1, $2); }
1222         | ext_decl pointer direct_declarator_function
1223       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
1224         | pointer ext_decl direct_declarator_function
1225       { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }      
1226      
1227    ;
1228
1229 direct_declarator_function_start:
1230      direct_declarator_nofunction '('
1231    ;
1232
1233 direct_declarator_function:
1234           direct_declarator_function_start parameter_type_list ')' 
1235       { $$ = MkDeclaratorFunction($1, $2); }
1236         | direct_declarator_function_start identifier_list ')'
1237       { $$ = MkDeclaratorFunction($1, $2); }
1238         | direct_declarator_function_start ')'
1239       { $$ = MkDeclaratorFunction($1, null); }
1240         ;
1241
1242 direct_declarator:
1243      direct_declarator_function
1244    | direct_declarator_nofunction
1245    | ext_decl direct_declarator_function
1246       { $$ = MkDeclaratorExtended($1, $2); }
1247    | ext_decl direct_declarator_nofunction
1248       { $$ = MkDeclaratorExtended($1, $2); }
1249         ;
1250
1251 declarator_nofunction:
1252           direct_declarator_nofunction
1253         | pointer direct_declarator_nofunction      { $$ = MkDeclaratorPointer($1, $2); }
1254    | ext_decl direct_declarator_nofunction { $$ = MkDeclaratorExtended($1, $2); }
1255         | ext_decl pointer direct_declarator_nofunction { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
1256         | pointer ext_decl direct_declarator_nofunction { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
1257 ;
1258
1259 type_qualifier_list:
1260           type_qualifier                          { $$ = MkList(); ListAdd($$, $1); }
1261         | type_qualifier_list type_qualifier      { $$ = $1; ListAdd($1, $2);  }
1262         ;
1263
1264 pointer:
1265           '*'                               { $$ = MkPointer(null, null); }
1266         | '*' type_qualifier_list           { $$ = MkPointer($2, null); }
1267         | '*' pointer                       { $$ = MkPointer(null, $2); }
1268         | '*' type_qualifier_list pointer   { $$ = MkPointer($2, $3); }
1269         ;
1270
1271 parameter_type_list:
1272           parameter_list                 
1273         | parameter_list ',' ELLIPSIS { $$ = $1; ListAdd($1, MkTypeName(null, null)); }
1274         ;
1275
1276 parameter_list:
1277           parameter_declaration                      { $$ = MkList(); ListAdd($$, $1); }
1278         | parameter_list ',' parameter_declaration   { $$ = $1; ListAdd($1, $3); }
1279         ;
1280
1281 parameter_declaration:
1282           guess_declaration_specifiers declarator          { $$ = MkTypeName($1, $2); }
1283         | guess_declaration_specifiers abstract_declarator { $$ = MkTypeName($1, $2); }
1284    | real_guess_declaration_specifiers                { $$ = MkTypeName($1, null); }
1285 /*
1286    | CLASS                                            
1287       { $$ = MkTypeName(MkList(), null); $$.typedObject = true; }                        // Confusion with ellipsis? MkList()?
1288    | CLASS '&'                                        
1289       { $$ = MkTypeName(null, null); $$.typedObject = true; $$.byReference = true; }
1290    | CLASS declarator                                           
1291       { $$ = MkTypeName(MkList(), $2); $$.typedObject = true; }                        // Confusion with ellipsis? MkList()?
1292    | CLASS '&' declarator                                       
1293       { $$ = MkTypeName(null, $3); $$.typedObject = true; $$.byReference = true; }
1294 */
1295    | CLASS
1296       { $$ = MkTypeName(MkListOne(MkSpecifier(CLASS)), null); }
1297    | TYPED_OBJECT                                            
1298       { $$ = MkTypeName(MkListOne(MkSpecifier(TYPED_OBJECT)), null); }
1299    | TYPED_OBJECT '&'                                        
1300       { $$ = MkTypeName(MkListOne(MkSpecifier(TYPED_OBJECT)), MkDeclaratorPointer(MkPointer(null,null), null)); }
1301    | TYPED_OBJECT declarator                                           
1302       { $$ = MkTypeName(MkListOne(MkSpecifier(TYPED_OBJECT)), $2);  }
1303    | TYPED_OBJECT '&' declarator                                       
1304       { $$ = MkTypeName(MkListOne(MkSpecifier(TYPED_OBJECT)), MkDeclaratorPointer(MkPointer(null,null), $3)); }
1305    | ANY_OBJECT
1306       { $$ = MkTypeName(MkListOne(MkSpecifier(ANY_OBJECT)), null); }
1307    | ANY_OBJECT declarator
1308       { $$ = MkTypeName(MkListOne(MkSpecifier(ANY_OBJECT)), $2); }
1309
1310    | error                                               
1311       { $$ = MkTypeName(MkListOne(MkSpecifier(INT)), null); }
1312    | error declarator             { $$ = MkTypeName(MkListOne(MkSpecifier(INT)), $2); }
1313    //| error struct_declarator             { $$ = MkTypeName(MkListOne(MkSpecifier(INT)), $2); }
1314    | error abstract_declarator          { $$ = MkTypeName(MkListOne(MkSpecifier(INT)), $2); }  
1315         ;
1316
1317 identifier_list:
1318           identifier                        { $$ = MkList(); ListAdd($$, MkTypeName(null, MkDeclaratorIdentifier($1))); }
1319         | identifier_list ',' identifier    { $$ = $1; ListAdd($1, MkTypeName(null, MkDeclaratorIdentifier($3))); }
1320         ;
1321
1322 type_name:
1323           specifier_qualifier_list                      { $$ = MkTypeName($1, null); }
1324         | specifier_qualifier_list abstract_declarator  { $$ = MkTypeName($1, $2); }
1325         ;
1326
1327 guess_type_name:
1328           guess_specifier_qualifier_list                         { $$ = MkTypeName($1, null); }
1329         | guess_specifier_qualifier_list abstract_declarator     { $$ = MkTypeName($1, $2); }
1330         ;
1331
1332 initializer:
1333           assignment_expression
1334       { $$ = MkInitializerAssignment($1); $$.loc = @$; }
1335         | '{' initializer_list '}'
1336       { $$ = MkInitializerList($2); $$.loc = @$; }
1337         | '{' initializer_list ',' '}'
1338       { 
1339          $$ = MkInitializerList($2); 
1340          $$.loc = @$; 
1341
1342          {
1343             Expression exp = MkExpDummy();
1344             Initializer init = MkInitializerAssignment(exp);
1345             init.loc = @3;
1346             exp.loc = @3;
1347             ListAdd($2, init); 
1348          }
1349       }
1350         ;
1351
1352 initializer_condition:
1353           conditional_expression
1354       { $$ = MkInitializerAssignment($1); $$.loc = @$; }
1355    | anon_instantiation_expression
1356       { $$ = MkInitializerAssignment($1); $$.loc = @$; }
1357 /*
1358         | '{' initializer_list '}'
1359       { $$ = MkInitializerList($2); $$.loc = @$; }
1360         | '{' initializer_list ',' '}'
1361       { 
1362          $$ = MkInitializerList($2); 
1363          $$.loc = @$; 
1364
1365          {
1366             Expression exp = MkExpDummy();
1367             Initializer init = MkInitializerAssignment(exp);
1368             init.loc = @3;
1369             exp.loc = @3;
1370             ListAdd($2, init); 
1371          }
1372       }
1373 */
1374         ;
1375
1376 initializer_list:
1377           initializer
1378       { $$ = MkList(); ListAdd($$, $1); }
1379         | initializer_list ',' initializer
1380       { $$ = $1; ListAdd($1, $3); }
1381         ;
1382
1383 statement:
1384           labeled_statement
1385         | compound_statement
1386         | expression_statement
1387         | selection_statement
1388         | iteration_statement
1389         | jump_statement
1390         ;
1391
1392 labeled_statement:
1393           identifier ':' statement
1394       { $$ = MkLabeledStmt($1, $3); $$.loc = @$; }
1395         | CASE constant_expression ':' statement
1396       { $$ = MkCaseStmt($2, $4); $$.loc = @$; $2.loc.start = @1.end; }
1397         | DEFAULT ':' statement
1398       { $$ = MkCaseStmt(null, $3); $$.loc = @$; }
1399         ;
1400
1401 declaration_list:
1402           declaration                       { $$ = MkList(); ListAdd($$, $1); }
1403         | declaration_list declaration      { $$ = $1; ListAdd($1, $2); }
1404         ;
1405
1406 statement_list:
1407           statement                         { $$ = MkList(); ListAdd($$, $1); }
1408         | statement_list statement          { $$ = $1; ListAdd($1, $2); }
1409
1410    // declaration not allowed after statements
1411    | statement_list declaration              { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; /*yyerror(); */ ListAdd($1, stmt); $$ = $1; }
1412         ;
1413
1414 compound_inside:
1415           statement_list                      { $$ = MkCompoundStmt(null, $1); }
1416         | declaration_list                  { $$ = MkCompoundStmt($1, null); }
1417         | declaration_list statement_list   { $$ = MkCompoundStmt($1, $2); }
1418    ;
1419
1420 compound_start:
1421     '{' { $<context>$ = PushContext(); } 
1422     ;
1423
1424 compound_statement:
1425    '{' '}'
1426    { 
1427       $$ = MkCompoundStmt(null, null); 
1428       $$.compound.context = PushContext(); 
1429       PopContext($$.compound.context);
1430       $$.loc = @$; 
1431    }
1432
1433         | compound_start compound_inside '}' 
1434       { $$ = $2; $$.compound.context = $<context>1; PopContext($<context>1); $$.loc = @$; }
1435         ;
1436
1437 expression_statement:
1438           ';'                         { $$ = MkExpressionStmt(null); $$.loc = @$; }
1439         | expression ';'              { $$ = MkExpressionStmt($1); $$.loc = @$; }
1440         ;
1441
1442 selection_statement:
1443           IF '(' expression ')' statement %prec IFX        { $$ = MkIfStmt($3, $5, null); $$.loc = @$; }
1444         | IF '(' expression ')' statement ELSE statement   { $$ = MkIfStmt($3, $5, $7); $$.loc = @$; }
1445         | SWITCH '(' expression ')' statement              { $$ = MkSwitchStmt($3, $5); $$.loc = @$; }
1446         ;
1447
1448 iteration_statement:
1449           WHILE '(' expression ')' statement           { $$ = MkWhileStmt($3, $5); $$.loc = @$; }
1450         | DO statement WHILE '(' expression ')' ';'     { $$ = MkDoWhileStmt($2, $5); $$.loc = @$; }
1451         | FOR '(' expression_statement expression_statement ')' statement                   { $$ = MkForStmt($3, $4, null, $6); $$.loc = @$; }
1452         | FOR '(' expression_statement expression_statement expression ')' statement        { $$ = MkForStmt($3, $4, $5, $7); $$.loc = @$; }
1453
1454    | WHILE '(' ')' statement     { $$ = MkWhileStmt(null, $4); $$.loc = @$; }
1455    | FOR '(' expression_statement ')' statement                   { $$ = MkForStmt($3, null, null, $5); $$.loc = @$; }
1456    | FOR '(' ')' statement  { $$ = MkForStmt(null, null, null, $4); $$.loc = @$; }
1457         ;
1458
1459 jump_statement:
1460           GOTO identifier ';'   { $$ = MkGotoStmt($2); $$.loc = @$; }
1461         | CONTINUE ';'          { $$ = MkContinueStmt(); $$.loc = @$; }
1462         | BREAK ';'             { $$ = MkBreakStmt(); $$.loc = @$; }
1463         | RETURN ';'            { Expression exp = MkExpDummy(); $$ = MkReturnStmt(MkListOne(exp)); $$.loc = @$; exp.loc = @2; }
1464         | RETURN expression ';' { $$ = MkReturnStmt($2); $$.loc = @$; }
1465         ;
1466
1467 string_literal:
1468    STRING_LITERAL { $$ = CopyString(yytext); }
1469    ;
1470
1471 instantiation_named:
1472      declaration_specifiers identifier '{' members_initialization_list '}'
1473       { $$ = MkInstantiationNamed($1, MkExpIdentifier($2), $4); $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @5.start;}
1474    | declaration_specifiers identifier '{' '}'
1475       { $$ = MkInstantiationNamed($1, MkExpIdentifier($2), MkList());  $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @4.start;}
1476    ;
1477
1478 guess_instantiation_named:
1479      guess_declaration_specifiers identifier '{' members_initialization_list '}'
1480       { $$ = MkInstantiationNamed($1, MkExpIdentifier($2), $4); $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @5.start;}
1481    |  guess_declaration_specifiers identifier '{' '}'
1482       { $$ = MkInstantiationNamed($1, MkExpIdentifier($2), MkList());  $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @4.start;}
1483       
1484    /*| guess_declaration_specifiers identifier '{' members_initialization_list error
1485       { 
1486          int l = 0;
1487          $$ = MkInstantiationNamed($1, MkExpIdentifier($2), $4); $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @5.start;
1488
1489          for(;;)
1490          {
1491             if(yychar == '}') 
1492                l--;
1493             else if(yychar == '{')
1494                l++;
1495             if(l<0)
1496                break;
1497             yychar = yylex();
1498             yyerrok;
1499          }
1500          if(yychar == '}')
1501             yychar = yylex();
1502       }*/
1503    ;
1504
1505 instantiation_unnamed:
1506      type '{' members_initialization_list '}' 
1507       { $$ = MkInstantiation($1, null, $3);  $$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @4.start; }
1508    | type '{' '}' 
1509       { $$ = MkInstantiation($1, null, MkList());  $$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @3.start;}
1510    | identifier '{' members_initialization_list '}' 
1511       { Location tmpLoc = yylloc; yylloc = @1; yylloc = tmpLoc;  $$ = MkInstantiation(MkSpecifierName($1.string), null, $3);$$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @4.start; FreeIdentifier($1); }
1512    | identifier '{' '}' 
1513       { Location tmpLoc = yylloc; yylloc = @1; yylloc = tmpLoc;  $$ = MkInstantiation(MkSpecifierName($1.string), null, MkList());  $$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @3.start; FreeIdentifier($1); }
1514    ;
1515
1516 instantiation_anon:
1517      '{' members_initialization_list '}' 
1518       { $$ = MkInstantiation(null, null, $2);  $$.loc = @$; $$.insideLoc.start = @1.end; $$.insideLoc.end = @3.start; }
1519    | '{' '}' 
1520       { $$ = MkInstantiation(null, null, MkList());  $$.loc = @$; $$.insideLoc.start = @1.end; $$.insideLoc.end = @2.start;}
1521    ;
1522 class_function_definition:
1523           class_function_definition_start compound_statement
1524       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1525         | virtual_class_function_definition_start compound_statement
1526       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1527    | virtual_class_function_definition_start ';'
1528       { ProcessClassFunctionBody($1, null); $$.loc = @$; }
1529         | constructor_function_definition_start compound_statement
1530       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1531         | destructor_function_definition_start compound_statement
1532       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1533         ;
1534
1535 instance_class_function_definition_start:
1536    // Guess here conflicts with an expression...
1537      declaration_specifiers declarator_function
1538       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
1539     | declaration_specifiers declarator_nofunction
1540       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
1541       ; 
1542
1543 instance_class_function_definition:
1544           instance_class_function_definition_start compound_statement
1545       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1546         ;
1547
1548 data_member_initialization:
1549      postfix_expression '=' initializer_condition { $$ = MkMemberInitExp($1, $3); $$.loc = @$; $$.realLoc = @$; $$.initializer.loc.start = @2.end;}
1550    | initializer_condition                { $$ = MkMemberInit(null, $1); $$.loc = @$; $$.realLoc = @$;}
1551    ;
1552
1553 data_member_initialization_list:
1554      data_member_initialization
1555       { $$ = MkList(); ListAdd($$, $1); }
1556    | data_member_initialization_list ',' data_member_initialization
1557       { ((MemberInit)$1->last).loc.end = @3.start; ListAdd($1, $3); $$ = $1; }
1558    ;
1559
1560 data_member_initialization_list_coloned:
1561    data_member_initialization_list ';'
1562       { if($1->last) ((MemberInit)$1->last).loc.end = @2.end; $$ = $1; }
1563    ;
1564
1565 members_initialization_list_coloned:
1566      data_member_initialization_list_coloned                                        { MembersInit members = MkMembersInitList($1); $$ = MkList(); ListAdd($$, members); members.loc = @1; }
1567    | instance_class_function_definition                                             { $$ = MkList(); ListAdd($$, MkMembersInitMethod($1)); ((MembersInit)$$->last).loc = @1; }
1568    | members_initialization_list_coloned  data_member_initialization_list_coloned   { MembersInit members = MkMembersInitList($2); ListAdd($$, members); members.loc = @2; $$ = $1;  }
1569    | members_initialization_list_coloned  instance_class_function_definition        { ListAdd($$, MkMembersInitMethod($2)); ((MembersInit)$$->last).loc = @2;$$ = $1;  }
1570    | ';'                                                                            { MembersInit members = MkMembersInitList(MkList()); $$ = MkList(); ListAdd($$, members); members.loc = @1;  }
1571    | members_initialization_list_coloned ';'                                        { MembersInit members = MkMembersInitList(MkList()); ListAdd($$, members); members.loc = @2; $$ = $1; }
1572    ;
1573
1574 members_initialization_list:
1575      members_initialization_list_coloned 
1576    | data_member_initialization_list                                       { $$ = MkList(); ListAdd($$, MkMembersInitList($1)); ((MembersInit)$$->last).loc = @1; }
1577    | members_initialization_list_coloned data_member_initialization_list   { ListAdd($1, MkMembersInitList($2));   ((MembersInit)$$->last).loc = @2; }
1578    ;
1579
1580 type_unit:
1581      parameter_declaration                            { parsedType = $1; }
1582    | parameter_declaration ':' constant_expression    { parsedType = $1; parsedType.bitCount = $3; }
1583    ;
1584
1585 %%