compiler: (WIP) Fixes for MinGW/GCC 5
[sdk] / compiler / libec / src / expression.y
1 %{
2
3 import "ecdefs"
4
5 #define YYSIZE_T size_t
6 #define YYLTYPE Location
7 #include "grammar.h"
8
9 #ifndef YYLLOC_DEFAULT
10 # define YYLLOC_DEFAULT(Current, Rhs, N)         \
11   (Current).start = (Rhs)[1].start;      \
12   (Current).end = (Rhs)[N].end;
13 #endif
14
15 Expression parsedExpression;
16
17 #define yyparse expression_yyparse
18 #define yylval  expression_yylval
19 #define yychar  expression_yychar
20 #define yydebug expression_yydebug
21 #define yynerrs expression_yynerrs
22 #define yylloc expression_yylloc
23
24 // #define PRECOMPILER
25 extern File fileInput;
26 extern char * yytext;
27
28 int yylex();
29 int yyerror();
30
31 #define uint _uint
32 default:
33
34 %}
35
36 %debug
37 %union
38 {
39    int i;
40    AccessMode declMode;
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 }
71
72 // *** Types ***
73
74 %type <specifierType> struct_or_union
75 %type <i>   unary_operator assignment_operator
76 %type <id>  identifier
77 %type <exp> primary_expression postfix_expression unary_expression cast_expression
78             multiplicative_expression additive_expression shift_expression
79             relational_expression equality_expression and_expression
80             exclusive_or_expression inclusive_or_expression logical_and_expression
81             logical_or_expression conditional_expression assignment_expression
82             constant_expression
83             common_unary_expression simple_primary_expression
84             anon_instantiation_expression
85
86 // simple_postfix_expression simple_unary_expression
87
88 %type <list> argument_expression_list expression enumerator_list
89              struct_declarator_list struct_declaration_list
90              declaration_specifiers identifier_list initializer_list init_declarator_list
91              parameter_list parameter_type_list declaration_list statement_list
92              members_initialization_list members_initialization_list_coloned data_member_initialization_list data_member_initialization_list_coloned
93              specifier_qualifier_list
94              type_qualifier_list property_specifiers
95              renew_specifiers
96              default_property_list attribs_list
97
98
99 %type <specifier> storage_class_specifier enum_specifier_compound enum_specifier_nocompound type_qualifier type_specifier strict_type_specifier
100                   struct_or_union_specifier_compound struct_or_union_specifier_nocompound type strict_type
101 %type <enumerator> enumerator
102 %type <declarator> declarator direct_declarator direct_abstract_declarator abstract_declarator
103                    struct_declarator direct_declarator_function direct_declarator_function_start declarator_function direct_declarator_nofunction
104                    direct_abstract_declarator_noarray abstract_declarator_noarray
105
106 %type <pointer> pointer
107 %type <initializer> initializer initializer_condition
108 %type <initDeclarator> init_declarator
109 %type <typeName> type_name parameter_declaration
110 %type <stmt> statement labeled_statement compound_statement expression_statement
111              selection_statement iteration_statement jump_statement compound_inside
112
113 %type <declaration> declaration
114 %type <classDef> struct_declaration
115 %type <string> string_literal attribute_word
116 %type <extDecl> ext_decl
117 %type <attrib> attrib
118 %type <attribute> attribute
119
120 %type <instance> instantiation_named instantiation_unnamed instantiation_anon
121 /* %type <membersInit>  members_initialization */
122 %type <memberInit> data_member_initialization default_property
123 %type <classFunction> class_function_definition class_function_definition_start
124                      virtual_class_function_definition_start
125                      constructor_function_definition_start destructor_function_definition_start
126 %type <classFunction> instance_class_function_definition instance_class_function_definition_start
127 %type <prop> property
128
129 %type <context> compound_start
130
131 %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
132 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
133 %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
134 %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
135 %token XOR_ASSIGN OR_ASSIGN TYPE_NAME
136
137 %token TYPEDEF EXTERN STATIC AUTO REGISTER
138 %token CHAR SHORT INT UINT INT64 INT128 LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID VALIST
139 %token STRUCT UNION ENUM ELLIPSIS
140
141 %token CASE DEFAULT IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
142
143 %nonassoc IFX
144 %nonassoc ELSE
145 %token CLASS THISCLASS CLASS_NAME
146 %token PROPERTY SETPROP GETPROP NEWOP RENEW DELETE EXT_DECL EXT_STORAGE IMPORT DEFINE VIRTUAL ATTRIB
147 %token PUBLIC PRIVATE
148 %token TYPED_OBJECT ANY_OBJECT _INCREF EXTENSION ASM TYPEOF
149 %token WATCH STOPWATCHING FIREWATCHERS WATCHABLE CLASS_DESIGNER CLASS_NO_EXPANSION CLASS_FIXED ISPROPSET
150 %token CLASS_DEFAULT_PROPERTY PROPERTY_CATEGORY CLASS_DATA CLASS_PROPERTY SUBCLASS NAMESPACE
151 %token NEW0OP RENEW0 VAARG
152 %token DBTABLE DBFIELD DBINDEX DATABASE_OPEN
153 %token ALIGNOF ATTRIB_DEP __ATTRIB
154 %token BOOL _BOOL _COMPLEX _IMAGINARY RESTRICT THREAD
155 %token WIDE_STRING_LITERAL
156 %token BUILTIN_OFFSETOF
157
158 %destructor { FreeIdentifier($$); } identifier
159 %destructor { FreePointer($$); } pointer
160 %destructor { FreeExpression($$); } primary_expression postfix_expression unary_expression cast_expression
161                                     multiplicative_expression additive_expression shift_expression
162                                     relational_expression equality_expression and_expression
163                                     exclusive_or_expression inclusive_or_expression logical_and_expression
164                                     logical_or_expression conditional_expression assignment_expression
165                                     constant_expression
166 %destructor { FreeSpecifier($$); }  storage_class_specifier enum_specifier_compound enum_specifier_nocompound type_qualifier type_specifier
167                                     struct_or_union_specifier_compound struct_or_union_specifier_nocompound type strict_type strict_type_specifier
168 %destructor { FreeEnumerator($$); } enumerator
169 %destructor { FreeDeclarator($$); } declarator direct_declarator direct_abstract_declarator abstract_declarator
170                                     direct_abstract_declarator_noarray abstract_declarator_noarray
171                                     struct_declarator direct_declarator_function direct_declarator_function_start declarator_function direct_declarator_nofunction
172
173 %destructor { FreeInitializer($$); } initializer initializer_condition
174 %destructor { FreeInitDeclarator($$); } init_declarator
175 %destructor { FreeTypeName($$); } type_name parameter_declaration
176 %destructor { FreeStatement($$); }  statement labeled_statement compound_statement expression_statement
177                                     selection_statement iteration_statement jump_statement compound_inside
178
179 %destructor { FreeDeclaration($$); } declaration
180
181 %destructor { FreeInstance($$); } instantiation_named instantiation_unnamed
182
183 %destructor { FreeMemberInit($$); } data_member_initialization default_property
184
185 %destructor { FreeClassFunction($$); } class_function_definition class_function_definition_start
186                                        virtual_class_function_definition_start
187                                        constructor_function_definition_start destructor_function_definition_start
188                                        instance_class_function_definition instance_class_function_definition_start
189 %destructor { FreeClassDef($$); } struct_declaration
190 %destructor { delete $$; } string_literal attribute_word
191 %destructor { FreeProperty($$); } property
192
193 %destructor { FreeList($$, FreeExpression); }  argument_expression_list expression
194 %destructor { FreeList($$, FreeEnumerator); }  enumerator_list
195 %destructor { FreeList($$, FreeSpecifier); }   type_qualifier_list specifier_qualifier_list declaration_specifiers
196 %destructor { FreeList($$, FreeDeclarator); }  struct_declarator_list
197 %destructor { FreeList($$, FreeDeclaration); } declaration_list
198 %destructor { FreeList($$, FreeInitializer); } initializer_list
199 %destructor { FreeList($$, FreeInitDeclarator); } init_declarator_list
200 %destructor { FreeList($$, FreeTypeName); } parameter_list parameter_type_list identifier_list
201 %destructor { FreeList($$, FreeStatement); } statement_list
202 %destructor { FreeList($$, FreeClassDef); } struct_declaration_list
203 %destructor { FreeList($$, FreeMemberInit); } default_property_list data_member_initialization_list data_member_initialization_list_coloned
204 %destructor { FreeList($$, FreeMembersInit); } members_initialization_list members_initialization_list_coloned
205 %destructor { PopContext($$); FreeContext($$); delete $$; } compound_start
206 %destructor { FreeAttrib($$); } attrib
207 %destructor { FreeExtDecl($$); } ext_decl
208 %destructor { FreeAttribute($$); } attribute
209 %destructor { FreeList($$, FreeAttribute); }  attribs_list
210
211 %start expression_unit
212
213 %%
214
215 identifier:
216    IDENTIFIER
217       { $$ = MkIdentifier(yytext); $$.loc = @1; }
218    ;
219
220 primary_expression:
221      simple_primary_expression
222         | '(' expression ')'
223       { $$ = MkExpBrackets($2); $$.loc = @$; }
224    ;
225
226 simple_primary_expression:
227           identifier
228       { $$ = MkExpIdentifier($1); $$.loc = @$; }
229    | instantiation_unnamed
230       { $$ = MkExpInstance($1); $$.loc = @$; }
231         | CONSTANT
232       { $$ = MkExpConstant(yytext); $$.loc = @$; }
233    | WIDE_STRING_LITERAL { $$ = MkExpWideString(yytext); $$.loc = @$; }
234         | string_literal
235       { $$ = MkExpString($1); delete $1; $$.loc = @$; }
236    | '$' string_literal     { $$ = MkExpIntlString($2, null); delete $2; $$.loc = @$; }
237    | '$' string_literal '.' string_literal     { $$ = MkExpIntlString($4, $2); delete $2; delete $4; $$.loc = @$; }
238    | '(' ')'
239       { Expression exp = MkExpDummy(); exp.loc.start = @1.end; exp.loc.end = @2.start; $$ = MkExpBrackets(MkListOne(exp)); $$.loc = @$; yyerror(); }
240
241    | NEWOP declaration_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpNew(MkTypeName($2,$3), $5); $$.loc = @$; }
242    | NEWOP declaration_specifiers '[' constant_expression ']' { $$ = MkExpNew(MkTypeName($2,null), $4); $$.loc = @$; }
243    | NEW0OP declaration_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpNew0(MkTypeName($2,$3), $5); $$.loc = @$; }
244    | NEW0OP declaration_specifiers '[' constant_expression ']' { $$ = MkExpNew0(MkTypeName($2,null), $4); $$.loc = @$; }
245    | RENEW constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpRenew($2, MkTypeName($3,$4), $6); $$.loc = @$; }
246    | RENEW constant_expression renew_specifiers '[' constant_expression ']' { $$ = MkExpRenew($2, MkTypeName($3,null), $5); $$.loc = @$; }
247    | RENEW0 constant_expression renew_specifiers abstract_declarator_noarray '[' constant_expression ']' { $$ = MkExpRenew0($2, MkTypeName($3,$4), $6); $$.loc = @$; }
248    | RENEW0 constant_expression renew_specifiers '[' constant_expression ']' { $$ = MkExpRenew0($2, MkTypeName($3,null), $5); $$.loc = @$; }
249    | error { $$ = MkExpDummy(); yyerror(); }
250    ;
251
252 anon_instantiation_expression:
253    instantiation_anon            { $$ = MkExpInstance($1); $$.loc = @$; }
254    ;
255
256 postfix_expression:
257           primary_expression
258    | postfix_expression '[' expression ']'               { $$ = MkExpIndex($1, $3); $$.loc = @$; }
259         | postfix_expression '(' ')'                          { $$ = MkExpCall($1, MkList()); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @3.end; $$.loc = @$; }
260         | postfix_expression '(' argument_expression_list ')' { $$ = MkExpCall($1, $3); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @4.end; $$.loc = @$; }
261         | postfix_expression '.' identifier                   { $$ = MkExpMember($1, $3); $$.loc = @$; }
262    | postfix_expression identifier
263    {
264       char * constant = $1.type == constantExp ? $1.constant : null;
265       int len = constant ? strlen(constant) : 0;
266       if(constant && constant[len-1] == '.')
267       {
268          constant[len-1] = 0;
269          $$ = MkExpMember($1, $2);
270          $$.loc = @$;
271       }
272       else
273          yyerror();
274    }
275         | postfix_expression PTR_OP identifier                { $$ = MkExpPointer($1, $3); $$.loc = @$; }
276         | postfix_expression INC_OP                           { $$ = MkExpOp($1, INC_OP, null); $$.loc = @$; }
277         | postfix_expression DEC_OP                           { $$ = MkExpOp($1, DEC_OP, null); $$.loc = @$; }
278         ;
279
280 /*
281 simple_postfix_expression:
282           simple_primary_expression
283    | simple_postfix_expression '[' expression ']'               { $$ = MkExpIndex($1, $3); $$.loc = @$; }
284         | simple_postfix_expression '(' ')'                          { $$ = MkExpCall($1, MkList()); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @3.end; $$.loc = @$; }
285         | simple_postfix_expression '(' argument_expression_list ')' { $$ = MkExpCall($1, $3); $$.call.argLoc.start = @2.start; $$.call.argLoc.end = @4.end; $$.loc = @$; }
286         | simple_postfix_expression '.' identifier                   { $$ = MkExpMember($1, $3); $$.loc = @$; }
287    | simple_postfix_expression identifier
288    {
289       char * constant = $1.type == constantExp ? $1.constant : null;
290       int len = constant ? strlen(constant) : 0;
291       if(constant && constant[len-1] == '.')
292       {
293          constant[len-1] = 0;
294          $$ = MkExpMember($1, $2);
295          $$.loc = @$;
296       }
297       else
298          yyerror();
299    }
300         | simple_postfix_expression PTR_OP identifier                { $$ = MkExpPointer($1, $3); $$.loc = @$; }
301         | simple_postfix_expression INC_OP                           { $$ = MkExpOp($1, INC_OP, null); $$.loc = @$; }
302         | simple_postfix_expression DEC_OP                           { $$ = MkExpOp($1, DEC_OP, null); $$.loc = @$; }
303         ;
304 */
305
306 argument_expression_list:
307           assignment_expression          { $$ = MkList(); ListAdd($$, $1); }
308    | anon_instantiation_expression  { $$ = MkList(); ListAdd($$, $1); }
309         | argument_expression_list ',' assignment_expression   { $$ = $1; ListAdd($1, $3);  }
310    | argument_expression_list ',' anon_instantiation_expression   { $$ = $1; ListAdd($1, $3);  }
311         ;
312
313 common_unary_expression:
314           INC_OP unary_expression           { $$ = MkExpOp(null, INC_OP, $2); $$.loc = @$; }
315         | DEC_OP unary_expression           { $$ = MkExpOp(null, DEC_OP, $2); $$.loc = @$; }
316         | unary_operator cast_expression    { $$ = MkExpOp(null, $1, $2); $$.loc = @$; }
317         //| SIZEOF '(' unary_expression ')'         { $$ = MkExpOp(null, SIZEOF, $3); $$.loc = @$; }
318    //| SIZEOF simple_unary_expression          { $$ = MkExpOp(null, SIZEOF, $2); $$.loc = @$; }
319    | SIZEOF unary_expression          { $$ = MkExpOp(null, SIZEOF, $2); $$.loc = @$; }
320    | SIZEOF '(' type_name ')'          { $$ = MkExpTypeSize($3); $$.loc = @$; }
321         //| ALIGNOF '(' unary_expression ')'         { $$ = MkExpOp(null, ALIGNOF, $3); $$.loc = @$; }
322    //| ALIGNOF simple_unary_expression          { $$ = MkExpOp(null, ALIGNOF, $2); $$.loc = @$; }
323    | ALIGNOF unary_expression          { $$ = MkExpOp(null, ALIGNOF, $2); $$.loc = @$; }
324    | ALIGNOF '(' type_name ')'          { $$ = MkExpTypeAlign($3); $$.loc = @$; }
325    ;
326
327 unary_expression:
328        common_unary_expression
329           | postfix_expression
330         ;
331
332 /*simple_unary_expression:
333      common_unary_expression
334         | simple_postfix_expression
335         ;*/
336
337 unary_operator:
338           '&'     { $$ = '&'; }
339         | '*'     { $$ = '*'; }
340         | '+'     { $$ = '+'; }
341         | '-'     { $$ = '-'; }
342         | '~'     { $$ = '~'; }
343         | '!'     { $$ = '!'; }
344    | DELETE  { $$ = DELETE; }
345         ;
346
347 cast_expression:
348      unary_expression
349         | '(' type_name ')' cast_expression    { $$ = MkExpCast($2, $4); $$.loc = @$; }
350         ;
351
352 multiplicative_expression:
353           cast_expression
354         | multiplicative_expression '*' cast_expression { $$ = MkExpOp($1, '*', $3); $$.loc = @$; }
355         | multiplicative_expression '/' cast_expression { $$ = MkExpOp($1, '/', $3); $$.loc = @$; }
356         | multiplicative_expression '%' cast_expression { $$ = MkExpOp($1, '%', $3); $$.loc = @$; }
357         ;
358
359 additive_expression:
360           multiplicative_expression
361         | additive_expression '+' multiplicative_expression  { $$ = MkExpOp($1, '+', $3); $$.loc = @$; }
362         | additive_expression '-' multiplicative_expression  { $$ = MkExpOp($1, '-', $3); $$.loc = @$; }
363         ;
364
365 shift_expression:
366           additive_expression
367         | shift_expression LEFT_OP additive_expression  { $$ = MkExpOp($1, LEFT_OP, $3); $$.loc = @$; }
368         | shift_expression RIGHT_OP additive_expression { $$ = MkExpOp($1, RIGHT_OP, $3); $$.loc = @$; }
369         ;
370
371 relational_expression:
372           shift_expression
373         | relational_expression '<' shift_expression    { $$ = MkExpOp($1, '<', $3); $$.loc = @$; }
374         | relational_expression '>' shift_expression    { $$ = MkExpOp($1, '>', $3); $$.loc = @$; }
375         | relational_expression LE_OP shift_expression  { $$ = MkExpOp($1, LE_OP, $3); $$.loc = @$; }
376         | relational_expression GE_OP shift_expression  { $$ = MkExpOp($1, GE_OP, $3); $$.loc = @$; }
377         ;
378
379 equality_expression:
380           relational_expression
381         | equality_expression EQ_OP relational_expression  { $$ = MkExpOp($1, EQ_OP, $3); $$.loc = @$; }
382         | equality_expression NE_OP relational_expression  { $$ = MkExpOp($1, NE_OP, $3); $$.loc = @$; }
383         ;
384
385 and_expression:
386           equality_expression
387         | and_expression '&' equality_expression  { $$ = MkExpOp($1, '&', $3); $$.loc = @$; }
388         ;
389
390 exclusive_or_expression:
391           and_expression
392         | exclusive_or_expression '^' and_expression { $$ = MkExpOp($1, '^', $3); $$.loc = @$; }
393         ;
394
395 inclusive_or_expression:
396           exclusive_or_expression
397         | inclusive_or_expression '|' exclusive_or_expression { $$ = MkExpOp($1, '|', $3); $$.loc = @$; }
398         ;
399
400 logical_and_expression:
401           inclusive_or_expression
402         | logical_and_expression AND_OP inclusive_or_expression  { $$ = MkExpOp($1, AND_OP, $3); $$.loc = @$; }
403         ;
404
405 logical_or_expression:
406           logical_and_expression
407         | logical_or_expression OR_OP logical_and_expression     { $$ = MkExpOp($1, OR_OP, $3); $$.loc = @$; }
408         ;
409
410 conditional_expression:
411           logical_or_expression
412         | logical_or_expression '?' expression ':' conditional_expression { $$ = MkExpCondition($1, $3, $5); $$.loc = @$; }
413         ;
414
415 assignment_expression:
416           conditional_expression
417         | unary_expression assignment_operator assignment_expression   { $$ = MkExpOp($1, $2, $3); $$.loc = @$; }
418         | conditional_expression assignment_operator assignment_expression   { yyerror(); $$ = MkExpOp($1, $2, $3); $$.loc = @$; }
419
420         | unary_expression assignment_operator anon_instantiation_expression   { $$ = MkExpOp($1, $2, $3); $$.loc = @$; }
421         | conditional_expression assignment_operator anon_instantiation_expression   { $$ = MkExpOp($1, $2, $3); $$.loc = @$; }
422         ;
423
424 assignment_operator:
425           '='                   { $$ = '='; }
426         | MUL_ASSIGN            { $$ = MUL_ASSIGN; }
427         | DIV_ASSIGN            { $$ = DIV_ASSIGN; }
428         | MOD_ASSIGN            { $$ = MOD_ASSIGN; }
429         | ADD_ASSIGN            { $$ = ADD_ASSIGN; }
430         | SUB_ASSIGN            { $$ = SUB_ASSIGN; }
431         | LEFT_ASSIGN           { $$ = LEFT_ASSIGN; }
432         | RIGHT_ASSIGN          { $$ = RIGHT_ASSIGN; }
433         | AND_ASSIGN            { $$ = AND_ASSIGN; }
434         | XOR_ASSIGN            { $$ = XOR_ASSIGN; }
435         | OR_ASSIGN             { $$ = OR_ASSIGN; }
436         ;
437
438 expression:
439      assignment_expression                 { $$ = MkList(); ListAdd($$, $1); }
440         | expression ',' assignment_expression  { $$ = $1; ListAdd($1, $3); }
441         ;
442
443 constant_expression:
444           conditional_expression
445         ;
446
447 declaration:
448           declaration_specifiers ';'                       { $$ = MkDeclaration($1, null); $$.loc = @$; }
449         | declaration_specifiers init_declarator_list ';'  { $$ = MkDeclaration($1, $2); $$.loc = @$; }
450    | instantiation_named ';'                          { $$ = MkDeclarationInst($1); $$.loc = @$; }
451    | DEFINE identifier '=' constant_expression ';'           { $$ = MkDeclarationDefine($2, $4); $$.loc = @$; }
452         ;
453
454 specifier_qualifier_list:
455      type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
456    | specifier_qualifier_list  type_qualifier            { $$ = $1; ListAdd($1, $2); }
457    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
458    | specifier_qualifier_list  type_specifier            { $$ = $1; ListAdd($1, $2); }
459    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
460         | specifier_qualifier_list enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
461    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
462         | specifier_qualifier_list struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
463    ;
464
465 declaration_specifiers:
466      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
467    | declaration_specifiers storage_class_specifier    { $$ = $1; ListAdd($1, $2); }
468    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
469    | declaration_specifiers  type_qualifier            { $$ = $1; ListAdd($1, $2); }
470    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
471    | declaration_specifiers  type_specifier            { $$ = $1; ListAdd($1, $2); }
472    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
473         | declaration_specifiers enum_specifier_compound          { $$ = $1; ListAdd($1, $2); }
474    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
475         | declaration_specifiers struct_or_union_specifier_compound          { $$ = $1; ListAdd($1, $2); }
476    ;
477
478
479 property_specifiers:
480      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
481    | property_specifiers storage_class_specifier     { ListAdd($1, $2); }
482    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
483    | property_specifiers type_qualifier            { ListAdd($1, $2); }
484    | type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
485    | property_specifiers type_specifier            { ListAdd($1, $2); }
486    | type                                       { $$ = MkList(); ListAdd($$, $1); }
487         | property_specifiers type          { ListAdd($1, $2); }
488    ;
489
490 renew_specifiers:
491      storage_class_specifier                          { $$ = MkList(); ListAdd($$, $1); }
492    | renew_specifiers storage_class_specifier    { ListAdd($1, $2); }
493    | type_qualifier                                   { $$ = MkList(); ListAdd($$, $1); }
494    | renew_specifiers type_qualifier            { ListAdd($1, $2); }
495    | strict_type_specifier                                   { $$ = MkList(); ListAdd($$, $1); }
496    | renew_specifiers strict_type_specifier            { ListAdd($1, $2); }
497    | struct_or_union_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
498         | renew_specifiers struct_or_union_specifier_compound          { ListAdd($1, $2); }
499    | enum_specifier_compound              { $$ = MkList(); ListAdd($$, $1); }
500         | renew_specifiers enum_specifier_compound          { ListAdd($1, $2); }
501    ;
502
503 init_declarator_list:
504           init_declarator                            { $$ = MkList(); ListAdd($$, $1); }
505         | init_declarator_list ',' init_declarator   { $$ = $1; ListAdd($1, $3); }
506         ;
507
508 init_declarator:
509           declarator                        { $$ = MkInitDeclarator($1, null); $$.loc = @$; }
510         | declarator '=' initializer                 { $$ = MkInitDeclarator($1, $3); $$.loc = @$; $$.initializer.loc.start = @2.end; }
511         ;
512
513 storage_class_specifier:
514           TYPEDEF       { $$ = MkSpecifier(TYPEDEF); }
515         | EXTERN        { $$ = MkSpecifier(EXTERN); }
516         | STATIC        { $$ = MkSpecifier(STATIC); }
517         | AUTO          { $$ = MkSpecifier(AUTO); }
518         | REGISTER      { $$ = MkSpecifier(REGISTER); }
519         | THREAD        { $$ = MkSpecifier(THREAD); }
520         ;
521
522 ext_decl:
523      EXT_DECL { $$ = MkExtDeclString(CopyString(yytext)); }
524    | attrib { $$ = MkExtDeclAttrib($1); }
525    ;
526
527 _attrib:
528    ATTRIB      { $<i>$ = ATTRIB; }
529  | ATTRIB_DEP  { $<i>$ = ATTRIB_DEP; }
530  | __ATTRIB    { $<i>$ = __ATTRIB; }
531  ;
532
533
534 attribute_word:
535      IDENTIFIER   { $$  = CopyString(yytext); }
536    | TYPE_NAME    { $$  = CopyString(yytext); }
537    | EXT_STORAGE  { $$  = CopyString(yytext); }
538    | EXT_DECL     { $$  = CopyString(yytext); }
539    | CONST        { $$  = CopyString(yytext); }
540    ;
541
542 attribute:
543      attribute_word  { $$ = MkAttribute($1, null); $$.loc = @$; }
544    | attribute_word '(' expression ')'  { $$ = MkAttribute($1, MkExpBrackets($3)); $$.loc = @$; }
545    ;
546
547 attribs_list:
548      attribute { $$ = MkListOne($1); }
549    | attribs_list attribute { ListAdd($1, $2); $$ = $1; }
550    | attribs_list ',' attribute { ListAdd($1, $3); $$ = $1; }
551    ;
552
553 attrib:
554      _attrib '(' '(' attribs_list ')' ')' { $$ = MkAttrib($<i>1, $4); $$.loc = @$; }
555    | _attrib '(' '('              ')' ')'  { $$ = MkAttrib($<i>1, null); $$.loc = @$; }
556    ;
557
558 type_qualifier:
559           CONST        { $$ = MkSpecifier(CONST); }
560         | VOLATILE     { $$ = MkSpecifier(VOLATILE); }
561    | EXT_STORAGE  { $$ = MkSpecifierExtended(MkExtDeclString(CopyString(yytext))); }
562         ;
563
564 type:
565    strict_type       { $$ = $1; }
566   /* | identifier identifier
567    {
568    #ifdef PRECOMPILER
569       DeclClass($1._class, $1.string);
570       fileInput.Seek(@1.start.pos, start);
571       resetScannerPos(&@1.start);
572       yyclearin;
573
574       YYPOPSTACK(1);
575       yystate = *yyssp;
576       YY_STACK_PRINT (yyss, yyssp);
577       YYPOPSTACK(1);
578       yystate = *yyssp;
579       YY_STACK_PRINT (yyss, yyssp);
580       goto yysetstate;
581    #else
582       Location tmpLoc = yylloc; $$ = $2; yylloc = @1;
583       Compiler_Error($"Not a type: %s\n", $1.string);
584       yylloc = tmpLoc; $2.badID = $1; // FreeIdentifier($1);
585    #endif
586    }*/
587    ;
588
589 strict_type:
590    TYPE_NAME       { $$ = MkSpecifierName(yytext); }
591    ;
592
593 type_specifier:
594           VOID            { $$ = MkSpecifier(VOID); }
595         | CHAR            { $$ = MkSpecifier(CHAR); }
596         | SHORT           { $$ = MkSpecifier(SHORT); }
597         | INT             { $$ = MkSpecifier(INT); }
598    | UINT            { $$ = MkSpecifier(UINT); }
599    | INT64           { $$ = MkSpecifier(INT64); }
600    | INT128          { $$ = MkSpecifier(INT128); }
601    | VALIST          { $$ = MkSpecifier(VALIST); }
602         | LONG            { $$ = MkSpecifier(LONG); }
603         | FLOAT           { $$ = MkSpecifier(FLOAT); }
604         | DOUBLE          { $$ = MkSpecifier(DOUBLE); }
605         | SIGNED          { $$ = MkSpecifier(SIGNED); }
606         | UNSIGNED        { $$ = MkSpecifier(UNSIGNED); }
607    | EXTENSION       { $$ = MkSpecifier(EXTENSION); }
608    | _BOOL           { $$ = MkSpecifier(_BOOL); }
609    | BOOL            { $$ = MkSpecifier(BOOL); }
610         | struct_or_union_specifier_nocompound
611         | enum_specifier_nocompound
612         | type
613    | SUBCLASS '(' type ')'                { $$ = MkSpecifierSubClass($3); }
614    | THISCLASS       { $$ = MkSpecifier(THISCLASS); }
615         ;
616
617 strict_type_specifier:
618           VOID            { $$ = MkSpecifier(VOID); }
619         | CHAR            { $$ = MkSpecifier(CHAR); }
620         | SHORT           { $$ = MkSpecifier(SHORT); }
621         | INT             { $$ = MkSpecifier(INT); }
622    | UINT            { $$ = MkSpecifier(UINT); }
623    | INT64           { $$ = MkSpecifier(INT64); }
624    | INT128          { $$ = MkSpecifier(INT128); }
625    | VALIST          { $$ = MkSpecifier(VALIST); }
626         | LONG            { $$ = MkSpecifier(LONG); }
627         | FLOAT           { $$ = MkSpecifier(FLOAT); }
628         | DOUBLE          { $$ = MkSpecifier(DOUBLE); }
629         | SIGNED          { $$ = MkSpecifier(SIGNED); }
630         | UNSIGNED        { $$ = MkSpecifier(UNSIGNED); }
631    | _BOOL           { $$ = MkSpecifier(_BOOL); }
632    | BOOL            { $$ = MkSpecifier(BOOL); }
633         | struct_or_union_specifier_nocompound
634         | enum_specifier_nocompound
635         | strict_type
636    | SUBCLASS '(' type ')'                { $$ = MkSpecifierSubClass($3); }
637    | THISCLASS       { $$ = MkSpecifier(THISCLASS); }
638         ;
639
640
641 struct_or_union_specifier_compound:
642           struct_or_union identifier '{' struct_declaration_list '}'   { $$ = MkStructOrUnion($1, $2, $4); if(declMode) DeclClass($2._class, $2.string); }
643         | struct_or_union '{' struct_declaration_list '}'              { $$ = MkStructOrUnion($1, null, $3); }
644    | struct_or_union identifier '{' '}'   { $$ = MkStructOrUnion($1, $2, null); if(declMode) DeclClass($2._class, $2.string); }
645    | struct_or_union '{' '}'              { $$ = MkStructOrUnion($1, null, null); }
646         | struct_or_union strict_type '{' struct_declaration_list '}'
647       { $$ = MkStructOrUnion($1, MkIdentifier($2.name), $4); if(declMode) DeclClass($2.nsSpec, $2.name); FreeSpecifier($2); }
648
649         | struct_or_union ext_decl identifier '{' struct_declaration_list '}'   { $$ = MkStructOrUnion($1, $3, $5); $$.extDeclStruct = $2; if(declMode) DeclClass($3._class, $3.string); }
650         | struct_or_union ext_decl '{' struct_declaration_list '}'              { $$ = MkStructOrUnion($1, null, $4); $$.extDeclStruct = $2; }
651    | struct_or_union ext_decl identifier '{' '}'   { $$ = MkStructOrUnion($1, $3, null); $$.extDeclStruct = $2; if(declMode) DeclClass($3._class, $3.string); }
652    | struct_or_union ext_decl '{' '}'              { $$ = MkStructOrUnion($1, null, null); $$.extDeclStruct = $2; }
653         | struct_or_union ext_decl strict_type '{' struct_declaration_list '}'
654       { $$ = MkStructOrUnion($1, MkIdentifier($3.name), $5); $$.extDeclStruct = $2; if(declMode) DeclClass($3.nsSpec, $3.name); FreeSpecifier($3); }
655         ;
656
657 struct_or_union_specifier_nocompound:
658           struct_or_union identifier                                   { $$ = MkStructOrUnion($1, $2, null); if(declMode) DeclClass($2._class, $2.string); }
659         | struct_or_union strict_type
660       { $$ = MkStructOrUnion($1, MkIdentifier($2.name), null); if(declMode) DeclClass($2.nsSpec, $2.name); FreeSpecifier($2); }
661
662         | struct_or_union ext_decl identifier
663       { $$ = MkStructOrUnion($1, $3, null); $$.extDeclStruct = $2;if(declMode) DeclClass($3._class, $3.string); }
664         | struct_or_union ext_decl strict_type
665       { $$ = MkStructOrUnion($1, MkIdentifier($3.name), null); $$.extDeclStruct = $2; if(declMode) DeclClass($3.nsSpec, $3.name); FreeSpecifier($3); }
666         ;
667
668 struct_or_union:
669           STRUCT    { $$ = structSpecifier; }
670         | UNION     { $$ = unionSpecifier; }
671         ;
672
673 struct_declaration_list:
674           struct_declaration                            { $$ = MkList(); ListAdd($$, $1); }
675         | struct_declaration_list struct_declaration    { $$ = $1; ListAdd($1, $2); }
676         ;
677
678 default_property:
679    postfix_expression '=' initializer_condition { $$ = MkMemberInitExp($1, $3); $$.loc = @$; $$.realLoc = @$; $$.initializer.loc.start = @2.end; }
680    ;
681
682 default_property_list:
683      default_property        { $$ = MkList(); ListAdd($$, $1); ((MemberInit)$$->last).loc = @$; }
684    | default_property_list ',' default_property      { $$ = $1; ((MemberInit)$1->last).loc.end = @3.start; ListAdd($1, $3); }
685    ;
686
687 property:
688    PROPERTY property_specifiers identifier '{' SETPROP compound_statement GETPROP compound_statement '}'
689       { $$ = MkProperty($2, null, $3, $6, $8); $$.loc = @$; }
690    | PROPERTY property_specifiers identifier '{' GETPROP compound_statement SETPROP compound_statement '}'
691       { $$ = MkProperty($2, null, $3, $8, $6); $$.loc = @$; }
692    | PROPERTY property_specifiers identifier '{' SETPROP compound_statement '}'
693       { $$ = MkProperty($2, null, $3, $6, null); $$.loc = @$; }
694    | PROPERTY property_specifiers identifier '{' GETPROP compound_statement '}'
695       { $$ = MkProperty($2, null, $3, null, $6); $$.loc = @$; }
696    | PROPERTY property_specifiers identifier '{' '}'
697       { $$ = MkProperty($2, null, $3, null, null); $$.loc = @$; }
698
699    | PROPERTY property_specifiers abstract_declarator identifier '{' SETPROP compound_statement GETPROP compound_statement '}'
700       { $$ = MkProperty($2, $3, $4, $7, $9); $$.loc = @$; }
701    | PROPERTY property_specifiers abstract_declarator identifier '{' GETPROP compound_statement SETPROP compound_statement '}'
702       { $$ = MkProperty($2, $3, $4, $9, $7); $$.loc = @$; }
703    | PROPERTY property_specifiers abstract_declarator identifier '{' SETPROP compound_statement '}'
704       { $$ = MkProperty($2, $3, $4, $7, null); $$.loc = @$; }
705    | PROPERTY property_specifiers abstract_declarator identifier '{' GETPROP compound_statement '}'
706       { $$ = MkProperty($2, $3, $4, null, $7); $$.loc = @$; }
707    | PROPERTY property_specifiers abstract_declarator identifier '{' '}'
708       { $$ = MkProperty($2, $3, $4, null, null); $$.loc = @$; }
709
710    | PROPERTY property_specifiers '{' SETPROP compound_statement GETPROP compound_statement '}'
711       { $$ = MkProperty($2, null, null, $5, $7); $$.loc = @$; }
712    | PROPERTY property_specifiers '{' GETPROP compound_statement SETPROP compound_statement '}'
713       { $$ = MkProperty($2, null, null, $7, $5); $$.loc = @$; }
714    | PROPERTY property_specifiers '{' SETPROP compound_statement '}'
715       { $$ = MkProperty($2, null, null, $5, null); $$.loc = @$; }
716    | PROPERTY property_specifiers '{' GETPROP compound_statement '}'
717       { $$ = MkProperty($2, null, null, null, $5); $$.loc = @$; }
718    | PROPERTY property_specifiers '{' '}'
719       { $$ = MkProperty($2, null, null, null, null); $$.loc = @$; }
720
721    | PROPERTY property_specifiers abstract_declarator '{' SETPROP compound_statement GETPROP compound_statement '}'
722       { $$ = MkProperty($2, $3, null, $6, $8); $$.loc = @$; }
723    | PROPERTY property_specifiers abstract_declarator '{' GETPROP compound_statement SETPROP compound_statement '}'
724       { $$ = MkProperty($2, $3, null, $8, $6); $$.loc = @$; }
725    | PROPERTY property_specifiers abstract_declarator '{' SETPROP compound_statement '}'
726       { $$ = MkProperty($2, $3, null, $6, null); $$.loc = @$; }
727    | PROPERTY property_specifiers abstract_declarator '{' GETPROP compound_statement '}'
728       { $$ = MkProperty($2, $3, null, null, $6); $$.loc = @$; }
729    | PROPERTY property_specifiers abstract_declarator '{' '}'
730       { $$ = MkProperty($2, $3, null, null, null); $$.loc = @$; }
731 ;
732
733 struct_declaration:
734           declaration_specifiers struct_declarator_list ';'         { $$ = MkClassDefDeclaration(MkStructDeclaration($1, $2, null)); $$.decl.loc = @$; $$.loc = @$; }
735    | declaration_specifiers ';'                                { $$ = MkClassDefDeclaration(MkStructDeclaration($1, null, null)); $$.decl.loc = @$; $$.loc = @$; }
736    | instantiation_unnamed ';'                                       { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; }
737    | instantiation_named ';'                                   { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; }
738    | class_function_definition                                       { $$ = MkClassDefFunction($1); $$.loc = @$; }
739    | default_property_list ';' { $$ = MkClassDefDefaultProperty($1); if($1->last) ((MemberInit)$1->last).loc.end = @2.start; $$.loc = @$; }
740    | property { $$ = MkClassDefProperty($1); $$.loc = @$; }
741    | ';' { $$ = null; }
742         ;
743
744 struct_declarator_list:
745           struct_declarator
746       { $$ = MkList(); ListAdd($$, $1); }
747         | struct_declarator_list ',' struct_declarator
748       { $$ = $1; ListAdd($1, $3); }
749         ;
750
751 struct_declarator:
752           declarator
753       { $$ = MkStructDeclarator($1, null); $$.loc = @$; }
754         | declarator attrib
755       { $$ = MkStructDeclarator($1, null); $$.structDecl.attrib = $2; $$.loc = @$; }
756         | ':' constant_expression
757       { $$ = MkStructDeclarator(null, $2);  $$.loc = @$; }
758         | declarator ':' constant_expression
759       { $$ = MkStructDeclarator($1, $3);  $$.loc = @$; }
760    | declarator ':' constant_expression ':' constant_expression
761       { $$ = MkStructDeclarator($1, $3); $$.structDecl.posExp = $5; $$.loc = @$; }
762         ;
763
764 enum_specifier_nocompound:
765      ENUM identifier                            { $$ = MkEnum($2, null); if(declMode) DeclClass($2._class, $2.string); }
766    | ENUM strict_type                           { $$ = MkEnum(MkIdentifier($2.name), null); if(declMode) DeclClass($2.nsSpec, $2.name); FreeSpecifier($2); }
767    ;
768
769 enum_specifier_compound:
770           ENUM '{' enumerator_list '}'
771       { $$ = MkEnum(null, $3); }
772         | ENUM identifier '{' enumerator_list '}'    { $$ = MkEnum($2, $4); if(declMode) DeclClass($2._class, $2.string); }
773    | ENUM identifier '{' enumerator_list ';' struct_declaration_list '}'    { $$ = MkEnum($2, $4); $$.definitions = $6; if(declMode) DeclClass($2._class, $2.string); }
774         | ENUM strict_type '{' enumerator_list ';' struct_declaration_list '}'          { $$ = MkEnum(MkIdentifier($2.name), $4); $$.definitions = $6; if(declMode) DeclClass($2.nsSpec, $2.name); FreeSpecifier($2); }
775    | ENUM strict_type '{' enumerator_list '}'          { $$ = MkEnum(MkIdentifier($2.name), $4); if(declMode) DeclClass($2.nsSpec, $2.name); FreeSpecifier($2); }
776         ;
777
778 enumerator_list:
779           enumerator
780       { $$ = MkList(); ListAdd($$, $1); }
781         | enumerator_list ',' enumerator
782       { $$ = $1; ListAdd($1, $3); }
783         ;
784
785 enumerator:
786           identifier
787       { $$ = MkEnumerator($1, null); }
788         | identifier '=' constant_expression
789       { $$ = MkEnumerator($1, $3); }
790         ;
791
792
793 direct_abstract_declarator:
794           '(' abstract_declarator ')'
795                                  { $$ = MkDeclaratorBrackets($2); }
796         | '[' ']'
797                                  { $$ = MkDeclaratorArray(null, null); }
798    | '[' constant_expression ']'
799                                  { $$ = MkDeclaratorArray(null, $2); }
800    | '[' type ']'
801                                  { $$ = MkDeclaratorEnumArray(null, $2); }
802         | direct_abstract_declarator '[' ']'
803                                  { $$ = MkDeclaratorArray($1, null); }
804         | direct_abstract_declarator '[' constant_expression ']'
805                                  { $$ = MkDeclaratorArray($1, $3); }
806         | direct_abstract_declarator '[' type']'
807                                  { $$ = MkDeclaratorEnumArray($1, $3); }
808         | '(' ')'
809                                  { $$ = MkDeclaratorFunction(null, null); }
810         | '(' parameter_type_list ')'
811                                  { $$ = MkDeclaratorFunction(null, $2); }
812         | direct_abstract_declarator '(' ')'
813                                  { $$ = MkDeclaratorFunction($1, null); }
814         | direct_abstract_declarator '(' parameter_type_list ')'
815                                  { $$ = MkDeclaratorFunction($1, $3); }
816         ;
817
818 direct_abstract_declarator_noarray:
819           '(' abstract_declarator_noarray ')'
820                                  { $$ = MkDeclaratorBrackets($2); }
821         | '(' ')'
822                                  { $$ = MkDeclaratorFunction(null, null); }
823         | '(' parameter_type_list ')'
824                                  { $$ = MkDeclaratorFunction(null, $2); }
825         | direct_abstract_declarator_noarray '(' ')'
826                                  { $$ = MkDeclaratorFunction($1, null); }
827         | direct_abstract_declarator_noarray '(' parameter_type_list ')'
828                                  { $$ = MkDeclaratorFunction($1, $3); }
829         ;
830
831 abstract_declarator:
832           pointer                              { $$ = MkDeclaratorPointer($1, null); }
833         | direct_abstract_declarator
834         | pointer direct_abstract_declarator   { $$ = MkDeclaratorPointer($1, $2); }
835    | ext_decl pointer                     { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
836    | ext_decl direct_abstract_declarator  { $$ = MkDeclaratorExtended($1, $2); }
837         | ext_decl pointer direct_abstract_declarator { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
838         ;
839
840 abstract_declarator_noarray:
841           pointer                              { $$ = MkDeclaratorPointer($1, null); }
842         | direct_abstract_declarator_noarray
843         | pointer direct_abstract_declarator_noarray   { $$ = MkDeclaratorPointer($1, $2); }
844    | ext_decl pointer { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
845    | ext_decl direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, $2); }
846         | ext_decl pointer direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
847         ;
848
849 /*
850 abstract_declarator:
851           pointer
852       { $$ = MkDeclaratorPointer($1, null); }
853         | direct_abstract_declarator
854         | pointer direct_abstract_declarator
855       { $$ = MkDeclaratorPointer($1, $2); }
856
857    | ext_decl pointer
858       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
859         | ext_decl direct_abstract_declarator
860       { $$ = MkDeclaratorExtended($1, $2); }
861         | ext_decl pointer direct_abstract_declarator
862       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
863
864         ;
865
866 direct_abstract_declarator:
867           '(' abstract_declarator ')'
868       { $$ = MkDeclaratorBrackets($2); }
869         | '[' ']'
870       { $$ = MkDeclaratorArray(null, null); }
871         | '[' constant_expression ']'
872       { $$ = MkDeclaratorArray(null, $2); }
873    | '[' type ']'
874       { $$ = MkDeclaratorEnumArray(null, $2); }
875         | direct_abstract_declarator '[' ']'
876       { $$ = MkDeclaratorArray($1, null); }
877         | direct_abstract_declarator '[' constant_expression ']'
878       { $$ = MkDeclaratorArray($1, $3); }
879         | direct_abstract_declarator '[' type ']'
880       { $$ = MkDeclaratorEnumArray($1, $3); }
881         | '(' ')'
882       { $$ = MkDeclaratorFunction(null, null); }
883         | '(' parameter_type_list ')'
884       { $$ = MkDeclaratorFunction(null, $2); }
885         | direct_abstract_declarator '(' ')'
886       { $$ = MkDeclaratorFunction($1, null); }
887         | direct_abstract_declarator '(' parameter_type_list ')'
888       { $$ = MkDeclaratorFunction($1, $3); }
889         ;
890 */
891 declarator:
892           direct_declarator
893         | pointer direct_declarator
894       { $$ = MkDeclaratorPointer($1, $2); }
895    | ext_decl pointer direct_declarator
896       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
897
898    ;
899
900 direct_declarator_nofunction:
901           identifier
902       { $$ = MkDeclaratorIdentifier($1); }
903         | '(' declarator ')'
904       { $$ = MkDeclaratorBrackets($2); }
905         | direct_declarator_nofunction '[' constant_expression ']'
906       { $$ = MkDeclaratorArray($1, $3); }
907         | direct_declarator_nofunction '[' ']'
908       { $$ = MkDeclaratorArray($1, null); }
909    | direct_declarator_nofunction '[' type ']'
910       { $$ = MkDeclaratorEnumArray($1, $3); }
911         ;
912
913 declarator_function:
914      direct_declarator_function
915         | pointer direct_declarator_function
916       { $$ = MkDeclaratorPointer($1, $2); }
917
918    | ext_decl direct_declarator_function
919       { $$ = MkDeclaratorExtended($1, $2); }
920         | ext_decl pointer direct_declarator_function
921       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
922         | pointer ext_decl direct_declarator_function
923       { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
924
925    ;
926
927 direct_declarator:
928      direct_declarator_function
929    | direct_declarator_nofunction
930    | ext_decl direct_declarator_function
931       { $$ = MkDeclaratorExtended($1, $2); }
932    | ext_decl direct_declarator_nofunction
933       { $$ = MkDeclaratorExtended($1, $2); }
934         ;
935
936 direct_declarator_function_start:
937      direct_declarator_nofunction '('
938    ;
939
940 direct_declarator_function:
941           direct_declarator_function_start parameter_type_list ')'
942       { $$ = MkDeclaratorFunction($1, $2); }
943         | direct_declarator_function_start identifier_list ')'
944       { $$ = MkDeclaratorFunction($1, $2); }
945         | direct_declarator_function_start ')'
946       { $$ = MkDeclaratorFunction($1, null); }
947         ;
948
949 type_qualifier_list:
950           type_qualifier                          { $$ = MkList(); ListAdd($$, $1); }
951         | type_qualifier_list type_qualifier      { $$ = $1; ListAdd($1, $2);  }
952         ;
953
954 pointer:
955           '*'                               { $$ = MkPointer(null, null); }
956         | '*' type_qualifier_list           { $$ = MkPointer($2, null); }
957         | '*' pointer                       { $$ = MkPointer(null, $2); }
958         | '*' type_qualifier_list pointer   { $$ = MkPointer($2, $3); }
959         ;
960
961 parameter_type_list:
962           parameter_list
963         | parameter_list ',' ELLIPSIS { $$ = $1; ListAdd($1, MkTypeName(null, null)); }
964         ;
965
966 parameter_list:
967           parameter_declaration                      { $$ = MkList(); ListAdd($$, $1); }
968         | parameter_list ',' parameter_declaration   { $$ = $1; ListAdd($1, $3); }
969         ;
970
971 parameter_declaration:
972           declaration_specifiers declarator          { $$ = MkTypeName($1, $2); }
973         | declaration_specifiers abstract_declarator { $$ = MkTypeName($1, $2); }
974         | declaration_specifiers                     { $$ = MkTypeName($1, null); }
975         ;
976
977 identifier_list:
978           identifier                        { $$ = MkList(); ListAdd($$, MkTypeName(null, MkDeclaratorIdentifier($1))); }
979         | identifier_list ',' identifier    { $$ = $1; ListAdd($1, MkTypeName(null, MkDeclaratorIdentifier($3))); }
980         ;
981
982 type_name:
983           specifier_qualifier_list                      { $$ = MkTypeName($1, null); }
984         | specifier_qualifier_list abstract_declarator  { $$ = MkTypeName($1, $2); }
985         ;
986 /*
987 guess_type_name:
988           guess_specifier_qualifier_list                         { $$ = MkTypeName($1, null); }
989         | guess_specifier_qualifier_list abstract_declarator     { $$ = MkTypeName($1, $2); }
990         ;
991 */
992 initializer:
993           assignment_expression
994       { $$ = MkInitializerAssignment($1); $$.loc = @$; }
995         | '{' initializer_list '}'
996       { $$ = MkInitializerList($2); $$.loc = @$; }
997         | '{' initializer_list ',' '}'
998       {
999          $$ = MkInitializerList($2);
1000          $$.loc = @$;
1001
1002          {
1003             Expression exp = MkExpDummy();
1004             Initializer init = MkInitializerAssignment(exp);
1005             init.loc = @3;
1006             exp.loc = @3;
1007             ListAdd($2, init);
1008          }
1009       }
1010         ;
1011
1012 initializer_condition:
1013           conditional_expression          { $$ = MkInitializerAssignment($1); $$.loc = @$; }
1014    | anon_instantiation_expression
1015       { $$ = MkInitializerAssignment($1); $$.loc = @$; }
1016 /*
1017         | '{' initializer_list '}'       { $$ = MkInitializerList($2); $$.loc = @$; }
1018         | '{' initializer_list ',' '}'
1019       {
1020          $$ = MkInitializerList($2);
1021          $$.loc = @$;
1022
1023          {
1024             Expression exp = MkExpDummy();
1025             Initializer init = MkInitializerAssignment(exp);
1026             init.loc = @3;
1027             exp.loc = @3;
1028             ListAdd($2, init);
1029          }
1030       }
1031 */
1032         ;
1033
1034 initializer_list:
1035           initializer
1036       { $$ = MkList(); ListAdd($$, $1); }
1037         | initializer_list ',' initializer
1038       { $$ = $1; ListAdd($1, $3); }
1039         ;
1040
1041 statement:
1042           labeled_statement
1043         | compound_statement
1044         | expression_statement
1045         | selection_statement
1046         | iteration_statement
1047         | jump_statement
1048         ;
1049
1050 labeled_statement:
1051           identifier ':' statement
1052       { $$ = MkLabeledStmt($1, $3); $$.loc = @$; }
1053         | CASE constant_expression ':' statement
1054       { $$ = MkCaseStmt($2, $4); $$.loc = @$; $2.loc.start = @1.end; }
1055         | DEFAULT ':' statement
1056       { $$ = MkCaseStmt(null, $3); $$.loc = @$; }
1057         ;
1058
1059 declaration_list:
1060           declaration                       { $$ = MkList(); ListAdd($$, $1); }
1061         | declaration_list declaration      { $$ = $1; ListAdd($1, $2); }
1062         ;
1063
1064 statement_list:
1065           statement                         { $$ = MkList(); ListAdd($$, $1); }
1066         | statement_list statement          { $$ = $1; ListAdd($1, $2); }
1067
1068    // declaration not allowed after statements
1069    | statement_list declaration              { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; /*yyerror(); */ ListAdd($1, stmt); $$ = $1; }
1070         ;
1071
1072 compound_inside:
1073           statement_list                      { $$ = MkCompoundStmt(null, $1); }
1074         | declaration_list                  { $$ = MkCompoundStmt($1, null); }
1075         | declaration_list statement_list   { $$ = MkCompoundStmt($1, $2); }
1076    ;
1077
1078 compound_start:
1079     '{' { $<context>$ = PushContext(); }
1080     ;
1081
1082 compound_statement:
1083    '{' '}'
1084    {
1085       $$ = MkCompoundStmt(null, null);
1086       $$.compound.context = PushContext();
1087       PopContext($$.compound.context);
1088       $$.loc = @$;
1089    }
1090
1091         | compound_start compound_inside '}'
1092       { $$ = $2; $$.compound.context = $<context>1; PopContext($<context>1); $$.loc = @$; }
1093         ;
1094
1095 expression_statement:
1096           ';'                         { $$ = MkExpressionStmt(null); $$.loc = @$; }
1097         | expression ';'              { $$ = MkExpressionStmt($1); $$.loc = @$; }
1098         ;
1099
1100 selection_statement:
1101           IF '(' expression ')' statement %prec IFX        { $$ = MkIfStmt($3, $5, null); $$.loc = @$; }
1102         | IF '(' expression ')' statement ELSE statement   { $$ = MkIfStmt($3, $5, $7); $$.loc = @$; }
1103         | SWITCH '(' expression ')' statement              { $$ = MkSwitchStmt($3, $5); $$.loc = @$; }
1104         ;
1105
1106 iteration_statement:
1107           WHILE '(' expression ')' statement           { $$ = MkWhileStmt($3, $5); $$.loc = @$; }
1108         | DO statement WHILE '(' expression ')' ';'     { $$ = MkDoWhileStmt($2, $5); $$.loc = @$; }
1109         | FOR '(' expression_statement expression_statement ')' statement                   { $$ = MkForStmt($3, $4, null, $6); $$.loc = @$; }
1110         | FOR '(' expression_statement expression_statement expression ')' statement        { $$ = MkForStmt($3, $4, $5, $7); $$.loc = @$; }
1111
1112    | WHILE '(' ')' statement     { $$ = MkWhileStmt(null, $4); $$.loc = @$; }
1113    | FOR '(' expression_statement ')' statement                   { $$ = MkForStmt($3, null, null, $5); $$.loc = @$; }
1114    | FOR '(' ')' statement  { $$ = MkForStmt(null, null, null, $4); $$.loc = @$; }
1115         ;
1116
1117 jump_statement:
1118           GOTO identifier ';'   { $$ = MkGotoStmt($2); $$.loc = @$; }
1119         | CONTINUE ';'          { $$ = MkContinueStmt(); $$.loc = @$; }
1120         | BREAK ';'             { $$ = MkBreakStmt(); $$.loc = @$; }
1121         | RETURN ';'            { Expression exp = MkExpDummy(); $$ = MkReturnStmt(MkListOne(exp)); $$.loc = @$; exp.loc = @2; }
1122         | RETURN expression ';' { $$ = MkReturnStmt($2); $$.loc = @$; }
1123         ;
1124
1125 string_literal:
1126    STRING_LITERAL { $$ = CopyString(yytext); }
1127    ;
1128
1129 instantiation_named:
1130      declaration_specifiers identifier '{' members_initialization_list '}'
1131       { $$ = MkInstantiationNamed($1, MkExpIdentifier($2), $4); $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @5.start;}
1132    | declaration_specifiers identifier '{' '}'
1133       { $$ = MkInstantiationNamed($1, MkExpIdentifier($2), MkList());  $$.loc = @$; $$.nameLoc = @2; $$.insideLoc.start = @3.end; $$.insideLoc.end = @4.start;}
1134    ;
1135
1136 instantiation_unnamed:
1137      type '{' members_initialization_list '}'
1138       { $$ = MkInstantiation($1, null, $3);  $$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @4.start; }
1139    | type '{' '}'
1140       { $$ = MkInstantiation($1, null, MkList());  $$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @3.start;}
1141    | identifier '{' members_initialization_list '}'
1142       { Location tmpLoc = yylloc; yylloc = @1; yylloc = tmpLoc;  $$ = MkInstantiation(MkSpecifierName($1.string), null, $3);$$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @4.start; FreeIdentifier($1); }
1143    | identifier '{' '}'
1144       { Location tmpLoc = yylloc; yylloc = @1; yylloc = tmpLoc;  $$ = MkInstantiation(MkSpecifierName($1.string), null, MkList());  $$.loc = @$; $$.insideLoc.start = @2.end; $$.insideLoc.end = @3.start; FreeIdentifier($1); }
1145    ;
1146
1147 instantiation_anon:
1148      '{' members_initialization_list '}'
1149       { $$ = MkInstantiation(null, null, $2);  $$.loc = @$; $$.insideLoc.start = @1.end; $$.insideLoc.end = @3.start; }
1150    | '{' '}'
1151       { $$ = MkInstantiation(null, null, MkList());  $$.loc = @$; $$.insideLoc.start = @1.end; $$.insideLoc.end = @2.start;}
1152    ;
1153
1154 class_function_definition_start:
1155      declaration_specifiers declarator_function
1156       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; }
1157    | declarator_function
1158       { $$ = MkClassFunction(null, null, $1, null); $$.loc = @$; }
1159    ;
1160
1161 constructor_function_definition_start:
1162    declaration_specifiers '(' ')'
1163       { $$ = MkClassFunction(null, null, null, null); $$.isConstructor = true; $$.loc = @$; FreeList /*FreeSpecifier*/($1, FreeSpecifier); }
1164    ;
1165
1166 destructor_function_definition_start:
1167    '~' declaration_specifiers '(' ')'
1168       { $$ = MkClassFunction(null, null, null, null); $$.isDestructor = true; $$.loc = @$; FreeList /*FreeSpecifier*/($2, FreeSpecifier); }
1169    ;
1170
1171 virtual_class_function_definition_start:
1172      VIRTUAL declaration_specifiers declarator_function
1173       { $$ = MkClassFunction($2, null, $3, null); $$.isVirtual = true; $$.loc = @$; }
1174    | VIRTUAL declarator_function
1175       { $$ = MkClassFunction(null, null, $2, null); $$.isVirtual = true; $$.loc = @$; }
1176       ;
1177
1178 class_function_definition:
1179           class_function_definition_start compound_statement
1180       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1181         | virtual_class_function_definition_start compound_statement
1182       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1183    | virtual_class_function_definition_start ';'
1184       { ProcessClassFunctionBody($1, null); $$.loc = @$; }
1185         | constructor_function_definition_start compound_statement
1186       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1187         | destructor_function_definition_start compound_statement
1188       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1189         ;
1190
1191 instance_class_function_definition_start:
1192    // Guess here conflicts with an expression...
1193      declaration_specifiers declarator_function
1194       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; }
1195       ;
1196
1197 instance_class_function_definition:
1198           instance_class_function_definition_start compound_statement
1199       { ProcessClassFunctionBody($1, $2); $$.loc = @$; }
1200         ;
1201
1202 data_member_initialization:
1203      postfix_expression '=' initializer_condition { $$ = MkMemberInitExp($1, $3); $$.loc = @$; $$.realLoc = @$; $$.initializer.loc.start = @2.end;}
1204    | initializer_condition                { $$ = MkMemberInit(null, $1); $$.loc = @$; $$.realLoc = @$;}
1205    ;
1206
1207 data_member_initialization_list:
1208      data_member_initialization
1209       { $$ = MkList(); ListAdd($$, $1); }
1210    | data_member_initialization_list ',' data_member_initialization
1211       { ((MemberInit)$1->last).loc.end = @3.start; ListAdd($1, $3); $$ = $1; }
1212    ;
1213
1214 data_member_initialization_list_coloned:
1215    data_member_initialization_list ';'
1216       { if($1->last) ((MemberInit)$1->last).loc.end = @2.end; $$ = $1; }
1217    ;
1218
1219 members_initialization_list_coloned:
1220      data_member_initialization_list_coloned                                        { MembersInit members = MkMembersInitList($1); $$ = MkList(); ListAdd($$, members); members.loc = @1; }
1221    | instance_class_function_definition                                             { $$ = MkList(); ListAdd($$, MkMembersInitMethod($1)); ((MembersInit)$$->last).loc = @1; }
1222    | members_initialization_list_coloned  data_member_initialization_list_coloned   { MembersInit members = MkMembersInitList($2); ListAdd($$, members); members.loc = @2; $$ = $1; }
1223    | members_initialization_list_coloned  instance_class_function_definition        { ListAdd($$, MkMembersInitMethod($2)); ((MembersInit)$$->last).loc = @2; $$ = $1; }
1224    | ';'                                                                            { MembersInit members = MkMembersInitList(MkList()); $$ = MkList(); ListAdd($$, members); members.loc = @1;  }
1225    | members_initialization_list_coloned ';'                                        { MembersInit members = MkMembersInitList(MkList()); ListAdd($$, members); members.loc = @2; $$ = $1; }
1226    ;
1227
1228 members_initialization_list:
1229      members_initialization_list_coloned
1230    | data_member_initialization_list                                       { $$ = MkList(); ListAdd($$, MkMembersInitList($1)); ((MembersInit)$$->last).loc = @1; }
1231    | members_initialization_list_coloned data_member_initialization_list   { ListAdd($1, MkMembersInitList($2));   ((MembersInit)$$->last).loc = @2; }
1232    ;
1233
1234 expression_unit:
1235    assignment_expression { parsedExpression = $1; }
1236    ;
1237 %%