Release 0.41.92
[vala-gnome.git] / gobject-introspection / scannerparser.y
blob47a97b60193b6646b3f3272901f9802d6bbe51fb
1 /* GObject introspection: C parser
3 * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it>
4 * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch>
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include "scanner.h"
36 extern FILE *yyin;
37 extern int lineno;
38 extern char *yytext;
40 extern int yylex (GIGenerator *igenerator);
41 static void yyerror(GIGenerator *igenerator, const char *s);
43 static int last_enum_value = -1;
44 static GHashTable *const_table = NULL;
46 CSymbol *
47 csymbol_new (CSymbolType type)
49 CSymbol *s = g_new0 (CSymbol, 1);
50 s->type = type;
51 return s;
54 static void
55 ctype_free (CType * type)
57 g_free (type);
58 g_free (type->name);
59 g_list_foreach (type->child_list, (GFunc)ctype_free, NULL);
60 g_list_free (type->child_list);
63 void
64 csymbol_free (CSymbol * symbol)
66 g_free (symbol->ident);
67 ctype_free (symbol->base_type);
68 g_free (symbol->const_string);
69 g_free (symbol);
70 g_slist_foreach (symbol->directives, (GFunc)cdirective_free, NULL);
71 g_slist_free (symbol->directives);
74 gboolean
75 csymbol_get_const_boolean (CSymbol * symbol)
77 return (symbol->const_int_set && symbol->const_int) || symbol->const_string;
80 CType *
81 ctype_new (CTypeType type)
83 CType *t = g_new0 (CType, 1);
84 t->type = type;
85 return t;
88 CType *
89 ctype_copy (CType * type)
91 return g_memdup (type, sizeof (CType));
94 CType *
95 cbasic_type_new (const char *name)
97 CType *basic_type = ctype_new (CTYPE_BASIC_TYPE);
98 basic_type->name = g_strdup (name);
99 return basic_type;
102 CType *
103 ctypedef_new (const char *name)
105 CType *typedef_ = ctype_new (CTYPE_TYPEDEF);
106 typedef_->name = g_strdup (name);
107 return typedef_;
110 CType *
111 cstruct_new (const char *name)
113 CType *struct_ = ctype_new (CTYPE_STRUCT);
114 struct_->name = g_strdup (name);
115 return struct_;
118 CType *
119 cunion_new (const char *name)
121 CType *union_ = ctype_new (CTYPE_UNION);
122 union_->name = g_strdup (name);
123 return union_;
126 CType *
127 cenum_new (const char *name)
129 CType *enum_ = ctype_new (CTYPE_ENUM);
130 enum_->name = g_strdup (name);
131 return enum_;
134 CType *
135 cpointer_new (CType * base_type)
137 CType *pointer = ctype_new (CTYPE_POINTER);
138 pointer->base_type = ctype_copy (base_type);
139 return pointer;
142 CType *
143 carray_new (void)
145 CType *array = ctype_new (CTYPE_ARRAY);
146 return array;
149 CType *
150 cfunction_new (void)
152 CType *func = ctype_new (CTYPE_FUNCTION);
153 return func;
156 /* use specified type as base type of symbol */
157 static void
158 csymbol_merge_type (CSymbol *symbol, CType *type)
160 CType **foundation_type = &(symbol->base_type);
161 while (*foundation_type != NULL) {
162 foundation_type = &((*foundation_type)->base_type);
164 *foundation_type = ctype_copy (type);
167 CDirective *
168 cdirective_new (const gchar *name,
169 const gchar *value)
171 CDirective *directive;
173 directive = g_slice_new (CDirective);
174 directive->name = g_strdup (name);
175 directive->value = g_strdup (value);
176 return directive;
179 void
180 cdirective_free (CDirective *directive)
182 g_free (directive->name);
183 g_free (directive->value);
184 g_slice_free (CDirective, directive);
189 %error-verbose
190 %union {
191 char *str;
192 GList *list;
193 CSymbol *symbol;
194 CType *ctype;
195 StorageClassSpecifier storage_class_specifier;
196 TypeQualifier type_qualifier;
197 FunctionSpecifier function_specifier;
198 UnaryOperator unary_operator;
201 %parse-param { GIGenerator* igenerator }
202 %lex-param { GIGenerator* igenerator }
204 %token <str> IDENTIFIER "identifier"
205 %token <str> TYPEDEF_NAME "typedef-name"
207 %token INTEGER FLOATING CHARACTER STRING
209 %token ELLIPSIS ADDEQ SUBEQ MULEQ DIVEQ MODEQ XOREQ ANDEQ OREQ SL SR
210 %token SLEQ SREQ EQ NOTEQ LTEQ GTEQ ANDAND OROR PLUSPLUS MINUSMINUS ARROW
212 %token AUTO BOOL BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM
213 %token EXTERN FLOAT FOR GOTO IF INLINE INT LONG REGISTER RESTRICT RETURN SHORT
214 %token SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION UNSIGNED VOID VOLATILE
215 %token WHILE
217 %token FUNCTION_MACRO OBJECT_MACRO
219 %start translation_unit
221 %type <ctype> declaration_specifiers
222 %type <ctype> enum_specifier
223 %type <ctype> pointer
224 %type <ctype> specifier_qualifier_list
225 %type <ctype> struct_or_union
226 %type <ctype> struct_or_union_specifier
227 %type <ctype> type_specifier
228 %type <str> identifier
229 %type <str> typedef_name
230 %type <str> identifier_or_typedef_name
231 %type <symbol> abstract_declarator
232 %type <symbol> init_declarator
233 %type <symbol> declarator
234 %type <symbol> enumerator
235 %type <symbol> direct_abstract_declarator
236 %type <symbol> direct_declarator
237 %type <symbol> parameter_declaration
238 %type <symbol> struct_declarator
239 %type <list> enumerator_list
240 %type <list> identifier_list
241 %type <list> init_declarator_list
242 %type <list> parameter_type_list
243 %type <list> parameter_list
244 %type <list> struct_declaration
245 %type <list> struct_declaration_list
246 %type <list> struct_declarator_list
247 %type <storage_class_specifier> storage_class_specifier
248 %type <type_qualifier> type_qualifier
249 %type <type_qualifier> type_qualifier_list
250 %type <function_specifier> function_specifier
251 %type <symbol> expression
252 %type <symbol> constant_expression
253 %type <symbol> conditional_expression
254 %type <symbol> logical_and_expression
255 %type <symbol> logical_or_expression
256 %type <symbol> inclusive_or_expression
257 %type <symbol> exclusive_or_expression
258 %type <symbol> multiplicative_expression
259 %type <symbol> additive_expression
260 %type <symbol> shift_expression
261 %type <symbol> relational_expression
262 %type <symbol> equality_expression
263 %type <symbol> and_expression
264 %type <symbol> cast_expression
265 %type <symbol> assignment_expression
266 %type <symbol> unary_expression
267 %type <symbol> postfix_expression
268 %type <symbol> primary_expression
269 %type <unary_operator> unary_operator
270 %type <str> function_macro
271 %type <str> object_macro
272 %type <symbol> strings
276 /* A.2.1 Expressions. */
278 primary_expression
279 : identifier
281 $$ = g_hash_table_lookup (const_table, $1);
282 if ($$ == NULL) {
283 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
286 | INTEGER
288 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
289 $$->const_int_set = TRUE;
290 if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) {
291 $$->const_int = strtol (yytext + 2, NULL, 16);
292 } else if (g_str_has_prefix (yytext, "0") && strlen (yytext) > 1) {
293 $$->const_int = strtol (yytext + 1, NULL, 8);
294 } else {
295 $$->const_int = atoi (yytext);
298 | CHARACTER
300 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
302 | FLOATING
304 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
306 | strings
307 | '(' expression ')'
309 $$ = $2;
313 /* concatenate adjacent string literal tokens */
314 strings
315 : STRING
317 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
318 yytext[strlen (yytext) - 1] = '\0';
319 $$->const_string = g_strcompress (yytext + 1);
321 | strings STRING
323 char *strings, *string2;
324 $$ = $1;
325 yytext[strlen (yytext) - 1] = '\0';
326 string2 = g_strcompress (yytext + 1);
327 strings = g_strconcat ($$->const_string, string2, NULL);
328 g_free ($$->const_string);
329 g_free (string2);
330 $$->const_string = strings;
334 identifier
335 : IDENTIFIER
337 $$ = g_strdup (yytext);
341 identifier_or_typedef_name
342 : identifier
343 | typedef_name
346 postfix_expression
347 : primary_expression
348 | postfix_expression '[' expression ']'
350 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
352 | postfix_expression '(' argument_expression_list ')'
354 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
356 | postfix_expression '(' ')'
358 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
360 | postfix_expression '.' identifier_or_typedef_name
362 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
364 | postfix_expression ARROW identifier_or_typedef_name
366 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
368 | postfix_expression PLUSPLUS
370 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
372 | postfix_expression MINUSMINUS
374 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
378 argument_expression_list
379 : assignment_expression
380 | argument_expression_list ',' assignment_expression
383 unary_expression
384 : postfix_expression
385 | PLUSPLUS unary_expression
387 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
389 | MINUSMINUS unary_expression
391 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
393 | unary_operator cast_expression
395 switch ($1) {
396 case UNARY_PLUS:
397 $$ = $2;
398 break;
399 case UNARY_MINUS:
400 $$ = $2;
401 $$->const_int = -$2->const_int;
402 break;
403 case UNARY_BITWISE_COMPLEMENT:
404 $$ = $2;
405 $$->const_int = ~$2->const_int;
406 break;
407 case UNARY_LOGICAL_NEGATION:
408 $$ = $2;
409 $$->const_int = !csymbol_get_const_boolean ($2);
410 break;
411 default:
412 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
413 break;
416 | SIZEOF unary_expression
418 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
420 | SIZEOF '(' type_name ')'
422 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
426 unary_operator
427 : '&'
429 $$ = UNARY_ADDRESS_OF;
431 | '*'
433 $$ = UNARY_POINTER_INDIRECTION;
435 | '+'
437 $$ = UNARY_PLUS;
439 | '-'
441 $$ = UNARY_MINUS;
443 | '~'
445 $$ = UNARY_BITWISE_COMPLEMENT;
447 | '!'
449 $$ = UNARY_LOGICAL_NEGATION;
453 cast_expression
454 : unary_expression
455 | '(' type_name ')' cast_expression
457 $$ = $4;
461 multiplicative_expression
462 : cast_expression
463 | multiplicative_expression '*' cast_expression
465 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
466 $$->const_int_set = TRUE;
467 $$->const_int = $1->const_int * $3->const_int;
469 | multiplicative_expression '/' cast_expression
471 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
472 $$->const_int_set = TRUE;
473 if ($3->const_int != 0) {
474 $$->const_int = $1->const_int / $3->const_int;
477 | multiplicative_expression '%' cast_expression
479 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
480 $$->const_int_set = TRUE;
481 $$->const_int = $1->const_int % $3->const_int;
485 additive_expression
486 : multiplicative_expression
487 | additive_expression '+' multiplicative_expression
489 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
490 $$->const_int_set = TRUE;
491 $$->const_int = $1->const_int + $3->const_int;
493 | additive_expression '-' multiplicative_expression
495 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
496 $$->const_int_set = TRUE;
497 $$->const_int = $1->const_int - $3->const_int;
501 shift_expression
502 : additive_expression
503 | shift_expression SL additive_expression
505 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
506 $$->const_int_set = TRUE;
507 $$->const_int = $1->const_int << $3->const_int;
509 | shift_expression SR additive_expression
511 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
512 $$->const_int_set = TRUE;
513 $$->const_int = $1->const_int >> $3->const_int;
517 relational_expression
518 : shift_expression
519 | relational_expression '<' shift_expression
521 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
522 $$->const_int_set = TRUE;
523 $$->const_int = $1->const_int < $3->const_int;
525 | relational_expression '>' shift_expression
527 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
528 $$->const_int_set = TRUE;
529 $$->const_int = $1->const_int > $3->const_int;
531 | relational_expression LTEQ shift_expression
533 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
534 $$->const_int_set = TRUE;
535 $$->const_int = $1->const_int <= $3->const_int;
537 | relational_expression GTEQ shift_expression
539 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
540 $$->const_int_set = TRUE;
541 $$->const_int = $1->const_int >= $3->const_int;
545 equality_expression
546 : relational_expression
547 | equality_expression EQ relational_expression
549 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
550 $$->const_int_set = TRUE;
551 $$->const_int = $1->const_int == $3->const_int;
553 | equality_expression NOTEQ relational_expression
555 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
556 $$->const_int_set = TRUE;
557 $$->const_int = $1->const_int != $3->const_int;
561 and_expression
562 : equality_expression
563 | and_expression '&' equality_expression
565 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
566 $$->const_int_set = TRUE;
567 $$->const_int = $1->const_int & $3->const_int;
571 exclusive_or_expression
572 : and_expression
573 | exclusive_or_expression '^' and_expression
575 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
576 $$->const_int_set = TRUE;
577 $$->const_int = $1->const_int ^ $3->const_int;
581 inclusive_or_expression
582 : exclusive_or_expression
583 | inclusive_or_expression '|' exclusive_or_expression
585 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
586 $$->const_int_set = TRUE;
587 $$->const_int = $1->const_int | $3->const_int;
591 logical_and_expression
592 : inclusive_or_expression
593 | logical_and_expression ANDAND inclusive_or_expression
595 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
596 $$->const_int_set = TRUE;
597 $$->const_int = csymbol_get_const_boolean ($1) && csymbol_get_const_boolean ($3);
601 logical_or_expression
602 : logical_and_expression
603 | logical_or_expression OROR logical_and_expression
605 $$ = csymbol_new (CSYMBOL_TYPE_CONST);
606 $$->const_int_set = TRUE;
607 $$->const_int = csymbol_get_const_boolean ($1) || csymbol_get_const_boolean ($3);
611 conditional_expression
612 : logical_or_expression
613 | logical_or_expression '?' expression ':' conditional_expression
615 $$ = csymbol_get_const_boolean ($1) ? $3 : $5;
619 assignment_expression
620 : conditional_expression
621 | unary_expression assignment_operator assignment_expression
623 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
627 assignment_operator
628 : '='
629 | MULEQ
630 | DIVEQ
631 | MODEQ
632 | ADDEQ
633 | SUBEQ
634 | SLEQ
635 | SREQ
636 | ANDEQ
637 | XOREQ
638 | OREQ
641 expression
642 : assignment_expression
643 | expression ',' assignment_expression
645 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
649 constant_expression
650 : conditional_expression
653 /* A.2.2 Declarations. */
655 declaration
656 : declaration_specifiers init_declarator_list ';'
658 GList *l;
659 for (l = $2; l != NULL; l = l->next) {
660 CSymbol *sym = l->data;
661 csymbol_merge_type (sym, $1);
662 if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) {
663 sym->type = CSYMBOL_TYPE_TYPEDEF;
664 } else if (sym->base_type->type == CTYPE_FUNCTION) {
665 sym->type = CSYMBOL_TYPE_FUNCTION;
666 } else {
667 sym->type = CSYMBOL_TYPE_OBJECT;
669 g_igenerator_add_symbol (igenerator, sym);
672 | declaration_specifiers ';'
675 declaration_specifiers
676 : storage_class_specifier declaration_specifiers
678 $$ = $2;
679 $$->storage_class_specifier |= $1;
681 | storage_class_specifier
683 $$ = ctype_new (CTYPE_INVALID);
684 $$->storage_class_specifier |= $1;
686 | type_specifier declaration_specifiers
688 $$ = $1;
689 $$->base_type = $2;
691 | type_specifier
692 | type_qualifier declaration_specifiers
694 $$ = $2;
695 $$->type_qualifier |= $1;
697 | type_qualifier
699 $$ = ctype_new (CTYPE_INVALID);
700 $$->type_qualifier |= $1;
702 | function_specifier declaration_specifiers
704 $$ = $2;
705 $$->function_specifier |= $1;
707 | function_specifier
709 $$ = ctype_new (CTYPE_INVALID);
710 $$->function_specifier |= $1;
714 init_declarator_list
715 : init_declarator
717 $$ = g_list_append (NULL, $1);
719 | init_declarator_list ',' init_declarator
721 $$ = g_list_append ($1, $3);
725 init_declarator
726 : declarator
727 | declarator '=' initializer
730 storage_class_specifier
731 : TYPEDEF
733 $$ = STORAGE_CLASS_TYPEDEF;
735 | EXTERN
737 $$ = STORAGE_CLASS_EXTERN;
739 | STATIC
741 $$ = STORAGE_CLASS_STATIC;
743 | AUTO
745 $$ = STORAGE_CLASS_AUTO;
747 | REGISTER
749 $$ = STORAGE_CLASS_REGISTER;
753 type_specifier
754 : VOID
756 $$ = ctype_new (CTYPE_VOID);
758 | CHAR
760 $$ = cbasic_type_new ("char");
762 | SHORT
764 $$ = cbasic_type_new ("short");
766 | INT
768 $$ = cbasic_type_new ("int");
770 | LONG
772 $$ = cbasic_type_new ("long");
774 | FLOAT
776 $$ = cbasic_type_new ("float");
778 | DOUBLE
780 $$ = cbasic_type_new ("double");
782 | SIGNED
784 $$ = cbasic_type_new ("signed");
786 | UNSIGNED
788 $$ = cbasic_type_new ("unsigned");
790 | BOOL
792 $$ = cbasic_type_new ("bool");
794 | struct_or_union_specifier
795 | enum_specifier
796 | typedef_name
798 $$ = ctypedef_new ($1);
802 struct_or_union_specifier
803 : struct_or_union identifier_or_typedef_name '{' struct_declaration_list '}'
805 $$ = $1;
806 $$->name = $2;
807 $$->child_list = $4;
809 CSymbol *sym = csymbol_new (CSYMBOL_TYPE_INVALID);
810 if ($$->type == CTYPE_STRUCT) {
811 sym->type = CSYMBOL_TYPE_STRUCT;
812 } else if ($$->type == CTYPE_UNION) {
813 sym->type = CSYMBOL_TYPE_UNION;
814 } else {
815 g_assert_not_reached ();
817 sym->ident = g_strdup ($$->name);
818 sym->base_type = ctype_copy ($$);
819 g_igenerator_add_symbol (igenerator, sym);
821 | struct_or_union '{' struct_declaration_list '}'
823 $$ = $1;
824 $$->child_list = $3;
826 | struct_or_union identifier_or_typedef_name
828 $$ = $1;
829 $$->name = $2;
833 struct_or_union
834 : STRUCT
836 $$ = cstruct_new (NULL);
838 | UNION
840 $$ = cunion_new (NULL);
844 struct_declaration_list
845 : struct_declaration
846 | struct_declaration_list struct_declaration
848 $$ = g_list_concat ($1, $2);
852 struct_declaration
853 : specifier_qualifier_list struct_declarator_list ';'
855 GList *l;
856 $$ = NULL;
857 for (l = $2; l != NULL; l = l->next) {
858 CSymbol *sym = l->data;
859 if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) {
860 sym->type = CSYMBOL_TYPE_TYPEDEF;
862 csymbol_merge_type (sym, $1);
863 $$ = g_list_append ($$, sym);
868 specifier_qualifier_list
869 : type_specifier specifier_qualifier_list
871 $$ = $1;
872 $$->base_type = $2;
874 | type_specifier
875 | type_qualifier specifier_qualifier_list
877 $$ = $2;
878 $$->type_qualifier |= $1;
880 | type_qualifier
882 $$ = ctype_new (CTYPE_INVALID);
883 $$->type_qualifier |= $1;
887 struct_declarator_list
888 : struct_declarator
890 $$ = g_list_append (NULL, $1);
892 | struct_declarator_list ',' struct_declarator
894 $$ = g_list_append ($1, $3);
898 struct_declarator
899 : /* empty, support for anonymous structs and unions */
901 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
903 | declarator
904 | ':' constant_expression
906 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
908 | declarator ':' constant_expression
911 enum_specifier
912 : ENUM identifier_or_typedef_name '{' enumerator_list '}'
914 $$ = cenum_new ($2);
915 $$->child_list = $4;
916 last_enum_value = -1;
918 | ENUM '{' enumerator_list '}'
920 $$ = cenum_new (NULL);
921 $$->child_list = $3;
922 last_enum_value = -1;
924 | ENUM identifier_or_typedef_name '{' enumerator_list ',' '}'
926 $$ = cenum_new ($2);
927 $$->child_list = $4;
928 last_enum_value = -1;
930 | ENUM '{' enumerator_list ',' '}'
932 $$ = cenum_new (NULL);
933 $$->child_list = $3;
934 last_enum_value = -1;
936 | ENUM identifier_or_typedef_name
938 $$ = cenum_new ($2);
942 enumerator_list
943 : enumerator
945 $$ = g_list_append (NULL, $1);
947 | enumerator_list ',' enumerator
949 $$ = g_list_append ($1, $3);
953 enumerator
954 : identifier
956 $$ = csymbol_new (CSYMBOL_TYPE_OBJECT);
957 $$->ident = $1;
958 $$->const_int_set = TRUE;
959 $$->const_int = ++last_enum_value;
960 g_hash_table_insert (const_table, g_strdup ($$->ident), $$);
962 | identifier '=' constant_expression
964 $$ = csymbol_new (CSYMBOL_TYPE_OBJECT);
965 $$->ident = $1;
966 $$->const_int_set = TRUE;
967 $$->const_int = $3->const_int;
968 last_enum_value = $$->const_int;
969 g_hash_table_insert (const_table, g_strdup ($$->ident), $$);
973 type_qualifier
974 : CONST
976 $$ = TYPE_QUALIFIER_CONST;
978 | RESTRICT
980 $$ = TYPE_QUALIFIER_RESTRICT;
982 | VOLATILE
984 $$ = TYPE_QUALIFIER_VOLATILE;
988 function_specifier
989 : INLINE
991 $$ = FUNCTION_INLINE;
995 declarator
996 : pointer direct_declarator
998 $$ = $2;
999 csymbol_merge_type ($$, $1);
1001 | direct_declarator
1004 direct_declarator
1005 : identifier
1007 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1008 $$->ident = $1;
1010 | '(' declarator ')'
1012 $$ = $2;
1014 | direct_declarator '[' assignment_expression ']'
1016 $$ = $1;
1017 csymbol_merge_type ($$, carray_new ());
1019 | direct_declarator '[' ']'
1021 $$ = $1;
1022 csymbol_merge_type ($$, carray_new ());
1024 | direct_declarator '(' parameter_type_list ')'
1026 CType *func = cfunction_new ();
1027 // ignore (void) parameter list
1028 if ($3 != NULL && ($3->next != NULL || ((CSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
1029 func->child_list = $3;
1031 $$ = $1;
1032 csymbol_merge_type ($$, func);
1034 | direct_declarator '(' identifier_list ')'
1036 CType *func = cfunction_new ();
1037 func->child_list = $3;
1038 $$ = $1;
1039 csymbol_merge_type ($$, func);
1041 | direct_declarator '(' ')'
1043 CType *func = cfunction_new ();
1044 $$ = $1;
1045 csymbol_merge_type ($$, func);
1049 pointer
1050 : '*' type_qualifier_list
1052 $$ = cpointer_new (NULL);
1053 $$->type_qualifier = $2;
1055 | '*'
1057 $$ = cpointer_new (NULL);
1059 | '*' type_qualifier_list pointer
1061 $$ = cpointer_new ($3);
1062 $$->type_qualifier = $2;
1064 | '*' pointer
1066 $$ = cpointer_new ($2);
1070 type_qualifier_list
1071 : type_qualifier
1072 | type_qualifier_list type_qualifier
1074 $$ = $1 | $2;
1078 parameter_type_list
1079 : parameter_list
1080 | parameter_list ',' ELLIPSIS
1083 parameter_list
1084 : parameter_declaration
1086 $$ = g_list_append (NULL, $1);
1088 | parameter_list ',' parameter_declaration
1090 $$ = g_list_append ($1, $3);
1094 parameter_declaration
1095 : declaration_specifiers declarator
1097 $$ = $2;
1098 csymbol_merge_type ($$, $1);
1100 | declaration_specifiers abstract_declarator
1102 $$ = $2;
1103 csymbol_merge_type ($$, $1);
1105 | declaration_specifiers
1107 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1108 $$->base_type = $1;
1112 identifier_list
1113 : identifier
1115 CSymbol *sym = csymbol_new (CSYMBOL_TYPE_INVALID);
1116 sym->ident = $1;
1117 $$ = g_list_append (NULL, sym);
1119 | identifier_list ',' identifier
1121 CSymbol *sym = csymbol_new (CSYMBOL_TYPE_INVALID);
1122 sym->ident = $3;
1123 $$ = g_list_append ($1, sym);
1127 type_name
1128 : specifier_qualifier_list
1129 | specifier_qualifier_list abstract_declarator
1132 abstract_declarator
1133 : pointer
1135 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1136 csymbol_merge_type ($$, $1);
1138 | direct_abstract_declarator
1139 | pointer direct_abstract_declarator
1141 $$ = $2;
1142 csymbol_merge_type ($$, $1);
1146 direct_abstract_declarator
1147 : '(' abstract_declarator ')'
1149 $$ = $2;
1151 | '[' ']'
1153 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1154 csymbol_merge_type ($$, carray_new ());
1156 | '[' assignment_expression ']'
1158 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1159 csymbol_merge_type ($$, carray_new ());
1161 | direct_abstract_declarator '[' ']'
1163 $$ = $1;
1164 csymbol_merge_type ($$, carray_new ());
1166 | direct_abstract_declarator '[' assignment_expression ']'
1168 $$ = $1;
1169 csymbol_merge_type ($$, carray_new ());
1171 | '(' ')'
1173 CType *func = cfunction_new ();
1174 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1175 csymbol_merge_type ($$, func);
1177 | '(' parameter_type_list ')'
1179 CType *func = cfunction_new ();
1180 // ignore (void) parameter list
1181 if ($2 != NULL && ($2->next != NULL || ((CSymbol *) $2->data)->base_type->type != CTYPE_VOID)) {
1182 func->child_list = $2;
1184 $$ = csymbol_new (CSYMBOL_TYPE_INVALID);
1185 csymbol_merge_type ($$, func);
1187 | direct_abstract_declarator '(' ')'
1189 CType *func = cfunction_new ();
1190 $$ = $1;
1191 csymbol_merge_type ($$, func);
1193 | direct_abstract_declarator '(' parameter_type_list ')'
1195 CType *func = cfunction_new ();
1196 // ignore (void) parameter list
1197 if ($3 != NULL && ($3->next != NULL || ((CSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
1198 func->child_list = $3;
1200 $$ = $1;
1201 csymbol_merge_type ($$, func);
1205 typedef_name
1206 : TYPEDEF_NAME
1208 $$ = g_strdup (yytext);
1212 initializer
1213 : assignment_expression
1214 | '{' initializer_list '}'
1215 | '{' initializer_list ',' '}'
1218 initializer_list
1219 : initializer
1220 | initializer_list ',' initializer
1223 /* A.2.3 Statements. */
1225 statement
1226 : labeled_statement
1227 | compound_statement
1228 | expression_statement
1229 | selection_statement
1230 | iteration_statement
1231 | jump_statement
1234 labeled_statement
1235 : identifier_or_typedef_name ':' statement
1236 | CASE constant_expression ':' statement
1237 | DEFAULT ':' statement
1240 compound_statement
1241 : '{' '}'
1242 | '{' block_item_list '}'
1245 block_item_list
1246 : block_item
1247 | block_item_list block_item
1250 block_item
1251 : declaration
1252 | statement
1255 expression_statement
1256 : ';'
1257 | expression ';'
1260 selection_statement
1261 : IF '(' expression ')' statement
1262 | IF '(' expression ')' statement ELSE statement
1263 | SWITCH '(' expression ')' statement
1266 iteration_statement
1267 : WHILE '(' expression ')' statement
1268 | DO statement WHILE '(' expression ')' ';'
1269 | FOR '(' ';' ';' ')' statement
1270 | FOR '(' expression ';' ';' ')' statement
1271 | FOR '(' ';' expression ';' ')' statement
1272 | FOR '(' expression ';' expression ';' ')' statement
1273 | FOR '(' ';' ';' expression ')' statement
1274 | FOR '(' expression ';' ';' expression ')' statement
1275 | FOR '(' ';' expression ';' expression ')' statement
1276 | FOR '(' expression ';' expression ';' expression ')' statement
1279 jump_statement
1280 : GOTO identifier_or_typedef_name ';'
1281 | CONTINUE ';'
1282 | BREAK ';'
1283 | RETURN ';'
1284 | RETURN expression ';'
1287 /* A.2.4 External definitions. */
1289 translation_unit
1290 : external_declaration
1291 | translation_unit external_declaration
1294 external_declaration
1295 : function_definition
1296 | declaration
1297 | macro
1300 function_definition
1301 : declaration_specifiers declarator declaration_list compound_statement
1302 | declaration_specifiers declarator compound_statement
1305 declaration_list
1306 : declaration
1307 | declaration_list declaration
1310 /* Macros */
1312 function_macro
1313 : FUNCTION_MACRO
1315 $$ = g_strdup (yytext + strlen ("#define "));
1319 object_macro
1320 : OBJECT_MACRO
1322 $$ = g_strdup (yytext + strlen ("#define "));
1326 function_macro_define
1327 : function_macro '(' identifier_list ')'
1330 object_macro_define
1331 : object_macro constant_expression
1333 if ($2->const_int_set || $2->const_string != NULL) {
1334 $2->ident = $1;
1335 g_igenerator_add_symbol (igenerator, $2);
1340 macro
1341 : function_macro_define
1342 | object_macro_define
1343 | error
1348 static void
1349 yyerror (GIGenerator *igenerator, const char *s)
1351 /* ignore errors while doing a macro scan as not all object macros
1352 * have valid expressions */
1353 if (!igenerator->macro_scan)
1355 fprintf(stderr, "%s:%d: %s\n",
1356 igenerator->current_filename, lineno, s);
1360 gboolean
1361 g_igenerator_parse_file (GIGenerator *igenerator, FILE *file)
1363 g_return_val_if_fail (file != NULL, FALSE);
1365 const_table = g_hash_table_new_full (g_str_hash, g_str_equal,
1366 g_free, NULL);
1368 lineno = 1;
1369 yyin = file;
1370 yyparse (igenerator);
1372 g_hash_table_destroy (const_table);
1373 const_table = NULL;
1375 yyin = NULL;
1377 return TRUE;