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