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>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
35 #include "sourcescanner.h"
36 #include "scannerparser.h"
42 extern int yylex (GISourceScanner *scanner);
43 static void yyerror (GISourceScanner *scanner, const char *str);
45 static int last_enum_value = -1;
46 static GHashTable *const_table = NULL;
53 GISourceSymbol *symbol;
55 StorageClassSpecifier storage_class_specifier;
56 TypeQualifier type_qualifier;
57 FunctionSpecifier function_specifier;
58 UnaryOperator unary_operator;
61 %parse-param { GISourceScanner* scanner }
62 %lex-param { GISourceScanner* scanner }
64 %token <str> IDENTIFIER "identifier"
65 %token <str> TYPEDEF_NAME "typedef-name"
67 %token INTEGER FLOATING CHARACTER STRING
69 %token ELLIPSIS ADDEQ SUBEQ MULEQ DIVEQ MODEQ XOREQ ANDEQ OREQ SL SR
70 %token SLEQ SREQ EQ NOTEQ LTEQ GTEQ ANDAND OROR PLUSPLUS MINUSMINUS ARROW
72 %token AUTO BOOL BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM
73 %token EXTENSION EXTERN FLOAT FOR GOTO IF INLINE INT LONG REGISTER RESTRICT
74 %token RETURN SHORT SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION UNSIGNED
75 %token VOID VOLATILE WHILE
77 %token FUNCTION_MACRO OBJECT_MACRO
79 %start translation_unit
81 %type <ctype> declaration_specifiers
82 %type <ctype> enum_specifier
84 %type <ctype> specifier_qualifier_list
85 %type <ctype> type_name
86 %type <ctype> struct_or_union
87 %type <ctype> struct_or_union_specifier
88 %type <ctype> type_specifier
89 %type <str> identifier
90 %type <str> typedef_name
91 %type <str> identifier_or_typedef_name
92 %type <symbol> abstract_declarator
93 %type <symbol> init_declarator
94 %type <symbol> declarator
95 %type <symbol> enumerator
96 %type <symbol> direct_abstract_declarator
97 %type <symbol> direct_declarator
98 %type <symbol> parameter_declaration
99 %type <symbol> struct_declarator
100 %type <list> enumerator_list
101 %type <list> identifier_list
102 %type <list> init_declarator_list
103 %type <list> parameter_list
104 %type <list> struct_declaration
105 %type <list> struct_declaration_list
106 %type <list> struct_declarator_list
107 %type <storage_class_specifier> storage_class_specifier
108 %type <type_qualifier> type_qualifier
109 %type <type_qualifier> type_qualifier_list
110 %type <function_specifier> function_specifier
111 %type <symbol> expression
112 %type <symbol> constant_expression
113 %type <symbol> conditional_expression
114 %type <symbol> logical_and_expression
115 %type <symbol> logical_or_expression
116 %type <symbol> inclusive_or_expression
117 %type <symbol> exclusive_or_expression
118 %type <symbol> multiplicative_expression
119 %type <symbol> additive_expression
120 %type <symbol> shift_expression
121 %type <symbol> relational_expression
122 %type <symbol> equality_expression
123 %type <symbol> and_expression
124 %type <symbol> cast_expression
125 %type <symbol> assignment_expression
126 %type <symbol> unary_expression
127 %type <symbol> postfix_expression
128 %type <symbol> primary_expression
129 %type <unary_operator> unary_operator
130 %type <str> function_macro
131 %type <str> object_macro
132 %type <symbol> strings
136 /* A.2.1 Expressions. */
141 $$ = g_hash_table_lookup (const_table, $1);
143 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
145 $$ = gi_source_symbol_ref ($$);
150 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
151 $$->const_int_set = TRUE;
152 if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) {
153 $$->const_int = strtol (yytext + 2, NULL, 16);
154 } else if (g_str_has_prefix (yytext, "0") && strlen (yytext) > 1) {
155 $$->const_int = strtol (yytext + 1, NULL, 8);
157 $$->const_int = atoi (yytext);
162 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
166 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
175 /* concatenate adjacent string literal tokens */
179 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
180 yytext[strlen (yytext) - 1] = '\0';
181 $$->const_string = g_strcompress (yytext + 1);
185 char *strings, *string2;
187 yytext[strlen (yytext) - 1] = '\0';
188 string2 = g_strcompress (yytext + 1);
189 strings = g_strconcat ($$->const_string, string2, NULL);
190 g_free ($$->const_string);
192 $$->const_string = strings;
199 $$ = g_strdup (yytext);
203 identifier_or_typedef_name
210 | postfix_expression '[' expression ']'
212 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
214 | postfix_expression '(' argument_expression_list ')'
216 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
218 | postfix_expression '(' ')'
220 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
222 | postfix_expression '.' identifier_or_typedef_name
224 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
226 | postfix_expression ARROW identifier_or_typedef_name
228 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
230 | postfix_expression PLUSPLUS
232 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
234 | postfix_expression MINUSMINUS
236 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
240 argument_expression_list
241 : assignment_expression
242 | argument_expression_list ',' assignment_expression
247 | PLUSPLUS unary_expression
249 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
251 | MINUSMINUS unary_expression
253 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
255 | unary_operator cast_expression
263 $$->const_int = -$2->const_int;
265 case UNARY_BITWISE_COMPLEMENT:
267 $$->const_int = ~$2->const_int;
269 case UNARY_LOGICAL_NEGATION:
271 $$->const_int = !gi_source_symbol_get_const_boolean ($2);
274 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
278 | SIZEOF unary_expression
280 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
282 | SIZEOF '(' type_name ')'
285 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
292 $$ = UNARY_ADDRESS_OF;
296 $$ = UNARY_POINTER_INDIRECTION;
308 $$ = UNARY_BITWISE_COMPLEMENT;
312 $$ = UNARY_LOGICAL_NEGATION;
318 | '(' type_name ')' cast_expression
325 multiplicative_expression
327 | multiplicative_expression '*' cast_expression
329 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
330 $$->const_int_set = TRUE;
331 $$->const_int = $1->const_int * $3->const_int;
333 | multiplicative_expression '/' cast_expression
335 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
336 $$->const_int_set = TRUE;
337 if ($3->const_int != 0) {
338 $$->const_int = $1->const_int / $3->const_int;
341 | multiplicative_expression '%' cast_expression
343 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
344 $$->const_int_set = TRUE;
345 $$->const_int = $1->const_int % $3->const_int;
350 : multiplicative_expression
351 | additive_expression '+' multiplicative_expression
353 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
354 $$->const_int_set = TRUE;
355 $$->const_int = $1->const_int + $3->const_int;
357 | additive_expression '-' multiplicative_expression
359 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
360 $$->const_int_set = TRUE;
361 $$->const_int = $1->const_int - $3->const_int;
366 : additive_expression
367 | shift_expression SL additive_expression
369 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
370 $$->const_int_set = TRUE;
371 $$->const_int = $1->const_int << $3->const_int;
373 | shift_expression SR additive_expression
375 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
376 $$->const_int_set = TRUE;
377 $$->const_int = $1->const_int >> $3->const_int;
381 relational_expression
383 | relational_expression '<' shift_expression
385 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
386 $$->const_int_set = TRUE;
387 $$->const_int = $1->const_int < $3->const_int;
389 | relational_expression '>' shift_expression
391 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
392 $$->const_int_set = TRUE;
393 $$->const_int = $1->const_int > $3->const_int;
395 | relational_expression LTEQ shift_expression
397 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
398 $$->const_int_set = TRUE;
399 $$->const_int = $1->const_int <= $3->const_int;
401 | relational_expression GTEQ shift_expression
403 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
404 $$->const_int_set = TRUE;
405 $$->const_int = $1->const_int >= $3->const_int;
410 : relational_expression
411 | equality_expression EQ relational_expression
413 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
414 $$->const_int_set = TRUE;
415 $$->const_int = $1->const_int == $3->const_int;
417 | equality_expression NOTEQ relational_expression
419 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
420 $$->const_int_set = TRUE;
421 $$->const_int = $1->const_int != $3->const_int;
426 : equality_expression
427 | and_expression '&' equality_expression
429 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
430 $$->const_int_set = TRUE;
431 $$->const_int = $1->const_int & $3->const_int;
435 exclusive_or_expression
437 | exclusive_or_expression '^' and_expression
439 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
440 $$->const_int_set = TRUE;
441 $$->const_int = $1->const_int ^ $3->const_int;
445 inclusive_or_expression
446 : exclusive_or_expression
447 | inclusive_or_expression '|' exclusive_or_expression
449 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
450 $$->const_int_set = TRUE;
451 $$->const_int = $1->const_int | $3->const_int;
455 logical_and_expression
456 : inclusive_or_expression
457 | logical_and_expression ANDAND inclusive_or_expression
459 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
460 $$->const_int_set = TRUE;
462 gi_source_symbol_get_const_boolean ($1) &&
463 gi_source_symbol_get_const_boolean ($3);
467 logical_or_expression
468 : logical_and_expression
469 | logical_or_expression OROR logical_and_expression
471 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
472 $$->const_int_set = TRUE;
474 gi_source_symbol_get_const_boolean ($1) ||
475 gi_source_symbol_get_const_boolean ($3);
479 conditional_expression
480 : logical_or_expression
481 | logical_or_expression '?' expression ':' conditional_expression
483 $$ = gi_source_symbol_get_const_boolean ($1) ? $3 : $5;
487 assignment_expression
488 : conditional_expression
489 | unary_expression assignment_operator assignment_expression
491 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
510 : assignment_expression
511 | expression ',' assignment_expression
513 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
518 : conditional_expression
521 /* A.2.2 Declarations. */
524 : declaration_specifiers init_declarator_list ';'
527 for (l = $2; l != NULL; l = l->next) {
528 GISourceSymbol *sym = l->data;
529 gi_source_symbol_merge_type (sym, gi_source_type_copy ($1));
530 if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) {
531 sym->type = CSYMBOL_TYPE_TYPEDEF;
532 } else if (sym->base_type->type == CTYPE_FUNCTION) {
533 sym->type = CSYMBOL_TYPE_FUNCTION;
535 sym->type = CSYMBOL_TYPE_OBJECT;
537 gi_source_scanner_add_symbol (scanner, sym);
538 gi_source_symbol_unref (sym);
542 | declaration_specifiers ';'
548 declaration_specifiers
549 : storage_class_specifier declaration_specifiers
552 $$->storage_class_specifier |= $1;
554 | storage_class_specifier
556 $$ = gi_source_type_new (CTYPE_INVALID);
557 $$->storage_class_specifier |= $1;
559 | type_specifier declaration_specifiers
562 /* combine basic types like unsigned int and long long */
563 if ($$->type == CTYPE_BASIC_TYPE && $2->type == CTYPE_BASIC_TYPE) {
564 char *name = g_strdup_printf ("%s %s", $$->name, $2->name);
573 | type_qualifier declaration_specifiers
576 $$->type_qualifier |= $1;
580 $$ = gi_source_type_new (CTYPE_INVALID);
581 $$->type_qualifier |= $1;
583 | function_specifier declaration_specifiers
586 $$->function_specifier |= $1;
590 $$ = gi_source_type_new (CTYPE_INVALID);
591 $$->function_specifier |= $1;
598 $$ = g_list_append (NULL, $1);
600 | init_declarator_list ',' init_declarator
602 $$ = g_list_append ($1, $3);
608 | declarator '=' initializer
611 storage_class_specifier
614 $$ = STORAGE_CLASS_TYPEDEF;
618 $$ = STORAGE_CLASS_EXTERN;
622 $$ = STORAGE_CLASS_STATIC;
626 $$ = STORAGE_CLASS_AUTO;
630 $$ = STORAGE_CLASS_REGISTER;
637 $$ = gi_source_type_new (CTYPE_VOID);
641 $$ = gi_source_basic_type_new ("char");
645 $$ = gi_source_basic_type_new ("short");
649 $$ = gi_source_basic_type_new ("int");
653 $$ = gi_source_basic_type_new ("long");
657 $$ = gi_source_basic_type_new ("float");
661 $$ = gi_source_basic_type_new ("double");
665 $$ = gi_source_basic_type_new ("signed");
669 $$ = gi_source_basic_type_new ("unsigned");
673 $$ = gi_source_basic_type_new ("bool");
675 | struct_or_union_specifier
679 $$ = gi_source_typedef_new ($1);
684 struct_or_union_specifier
685 : struct_or_union identifier_or_typedef_name '{' struct_declaration_list '}'
691 GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
692 if ($$->type == CTYPE_STRUCT) {
693 sym->type = CSYMBOL_TYPE_STRUCT;
694 } else if ($$->type == CTYPE_UNION) {
695 sym->type = CSYMBOL_TYPE_UNION;
697 g_assert_not_reached ();
699 sym->ident = g_strdup ($$->name);
700 sym->base_type = gi_source_type_copy ($$);
701 gi_source_scanner_add_symbol (scanner, sym);
702 gi_source_symbol_unref (sym);
704 | struct_or_union '{' struct_declaration_list '}'
709 | struct_or_union identifier_or_typedef_name
719 $$ = gi_source_struct_new (NULL);
723 $$ = gi_source_union_new (NULL);
727 struct_declaration_list
729 | struct_declaration_list struct_declaration
731 $$ = g_list_concat ($1, $2);
736 : specifier_qualifier_list struct_declarator_list ';'
740 for (l = $2; l != NULL; l = l->next)
742 GISourceSymbol *sym = l->data;
743 if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF)
744 sym->type = CSYMBOL_TYPE_TYPEDEF;
746 sym->type = CSYMBOL_TYPE_MEMBER;
747 gi_source_symbol_merge_type (sym, gi_source_type_copy ($1));
748 $$ = g_list_append ($$, sym);
754 specifier_qualifier_list
755 : type_specifier specifier_qualifier_list
761 | type_qualifier specifier_qualifier_list
764 $$->type_qualifier |= $1;
768 $$ = gi_source_type_new (CTYPE_INVALID);
769 $$->type_qualifier |= $1;
773 struct_declarator_list
776 $$ = g_list_append (NULL, $1);
778 | struct_declarator_list ',' struct_declarator
780 $$ = g_list_append ($1, $3);
785 : /* empty, support for anonymous structs and unions */
787 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
790 | ':' constant_expression
792 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
794 | declarator ':' constant_expression
798 : ENUM identifier_or_typedef_name '{' enumerator_list '}'
800 $$ = gi_source_enum_new ($2);
802 last_enum_value = -1;
804 | ENUM '{' enumerator_list '}'
806 $$ = gi_source_enum_new (NULL);
808 last_enum_value = -1;
810 | ENUM identifier_or_typedef_name '{' enumerator_list ',' '}'
812 $$ = gi_source_enum_new ($2);
814 last_enum_value = -1;
816 | ENUM '{' enumerator_list ',' '}'
818 $$ = gi_source_enum_new (NULL);
820 last_enum_value = -1;
822 | ENUM identifier_or_typedef_name
824 $$ = gi_source_enum_new ($2);
831 $$ = g_list_append (NULL, $1);
833 | enumerator_list ',' enumerator
835 $$ = g_list_append ($1, $3);
842 $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
844 $$->const_int_set = TRUE;
845 $$->const_int = ++last_enum_value;
846 g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$));
848 | identifier '=' constant_expression
850 $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
852 $$->const_int_set = TRUE;
853 $$->const_int = $3->const_int;
854 last_enum_value = $$->const_int;
855 g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$));
862 $$ = TYPE_QUALIFIER_CONST;
866 $$ = TYPE_QUALIFIER_RESTRICT;
870 $$ = TYPE_QUALIFIER_EXTENSION;
874 $$ = TYPE_QUALIFIER_VOLATILE;
881 $$ = FUNCTION_INLINE;
886 : pointer direct_declarator
889 gi_source_symbol_merge_type ($$, $1);
897 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
904 | direct_declarator '[' assignment_expression ']'
907 gi_source_symbol_merge_type ($$, gi_source_array_new ());
909 | direct_declarator '[' ']'
912 gi_source_symbol_merge_type ($$, gi_source_array_new ());
914 | direct_declarator '(' parameter_list ')'
916 GISourceType *func = gi_source_function_new ();
917 // ignore (void) parameter list
918 if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
919 func->child_list = $3;
922 gi_source_symbol_merge_type ($$, func);
924 | direct_declarator '(' identifier_list ')'
926 GISourceType *func = gi_source_function_new ();
927 func->child_list = $3;
929 gi_source_symbol_merge_type ($$, func);
931 | direct_declarator '(' ')'
933 GISourceType *func = gi_source_function_new ();
935 gi_source_symbol_merge_type ($$, func);
940 : '*' type_qualifier_list
942 $$ = gi_source_pointer_new (NULL);
943 $$->type_qualifier = $2;
947 $$ = gi_source_pointer_new (NULL);
949 | '*' type_qualifier_list pointer
951 $$ = gi_source_pointer_new ($3);
952 $$->type_qualifier = $2;
956 $$ = gi_source_pointer_new ($2);
962 | type_qualifier_list type_qualifier
969 : parameter_declaration
971 $$ = g_list_append (NULL, $1);
973 | parameter_list ',' parameter_declaration
975 $$ = g_list_append ($1, $3);
979 parameter_declaration
980 : declaration_specifiers declarator
983 gi_source_symbol_merge_type ($$, $1);
985 | declaration_specifiers abstract_declarator
988 gi_source_symbol_merge_type ($$, $1);
990 | declaration_specifiers
992 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
997 $$ = gi_source_symbol_new (CSYMBOL_TYPE_ELLIPSIS);
1004 GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1006 $$ = g_list_append (NULL, sym);
1008 | identifier_list ',' identifier
1010 GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1012 $$ = g_list_append ($1, sym);
1017 : specifier_qualifier_list
1018 | specifier_qualifier_list abstract_declarator
1024 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1025 gi_source_symbol_merge_type ($$, $1);
1027 | direct_abstract_declarator
1028 | pointer direct_abstract_declarator
1031 gi_source_symbol_merge_type ($$, $1);
1035 direct_abstract_declarator
1036 : '(' abstract_declarator ')'
1042 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1043 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1045 | '[' assignment_expression ']'
1047 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1048 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1050 | direct_abstract_declarator '[' ']'
1053 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1055 | direct_abstract_declarator '[' assignment_expression ']'
1058 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1062 GISourceType *func = gi_source_function_new ();
1063 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1064 gi_source_symbol_merge_type ($$, func);
1066 | '(' parameter_list ')'
1068 GISourceType *func = gi_source_function_new ();
1069 // ignore (void) parameter list
1070 if ($2 != NULL && ($2->next != NULL || ((GISourceSymbol *) $2->data)->base_type->type != CTYPE_VOID)) {
1071 func->child_list = $2;
1073 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1074 gi_source_symbol_merge_type ($$, func);
1076 | direct_abstract_declarator '(' ')'
1078 GISourceType *func = gi_source_function_new ();
1080 gi_source_symbol_merge_type ($$, func);
1082 | direct_abstract_declarator '(' parameter_list ')'
1084 GISourceType *func = gi_source_function_new ();
1085 // ignore (void) parameter list
1086 if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
1087 func->child_list = $3;
1090 gi_source_symbol_merge_type ($$, func);
1097 $$ = g_strdup (yytext);
1102 : assignment_expression
1103 | '{' initializer_list '}'
1104 | '{' initializer_list ',' '}'
1109 | initializer_list ',' initializer
1112 /* A.2.3 Statements. */
1116 | compound_statement
1117 | expression_statement
1118 | selection_statement
1119 | iteration_statement
1124 : identifier_or_typedef_name ':' statement
1125 | CASE constant_expression ':' statement
1126 | DEFAULT ':' statement
1131 | '{' block_item_list '}'
1136 | block_item_list block_item
1144 expression_statement
1150 : IF '(' expression ')' statement
1151 | IF '(' expression ')' statement ELSE statement
1152 | SWITCH '(' expression ')' statement
1156 : WHILE '(' expression ')' statement
1157 | DO statement WHILE '(' expression ')' ';'
1158 | FOR '(' ';' ';' ')' statement
1159 | FOR '(' expression ';' ';' ')' statement
1160 | FOR '(' ';' expression ';' ')' statement
1161 | FOR '(' expression ';' expression ';' ')' statement
1162 | FOR '(' ';' ';' expression ')' statement
1163 | FOR '(' expression ';' ';' expression ')' statement
1164 | FOR '(' ';' expression ';' expression ')' statement
1165 | FOR '(' expression ';' expression ';' expression ')' statement
1169 : GOTO identifier_or_typedef_name ';'
1173 | RETURN expression ';'
1176 /* A.2.4 External definitions. */
1179 : external_declaration
1180 | translation_unit external_declaration
1183 external_declaration
1184 : function_definition
1190 : declaration_specifiers declarator declaration_list compound_statement
1191 | declaration_specifiers declarator compound_statement
1196 | declaration_list declaration
1204 $$ = g_strdup (yytext + strlen ("#define "));
1211 $$ = g_strdup (yytext + strlen ("#define "));
1215 function_macro_define
1216 : function_macro '(' identifier_list ')'
1220 : object_macro constant_expression
1222 if ($2->const_int_set || $2->const_string != NULL) {
1224 gi_source_scanner_add_symbol (scanner, $2);
1225 gi_source_symbol_unref ($2);
1231 : function_macro_define
1232 | object_macro_define
1238 yyerror (GISourceScanner *scanner, const char *s)
1240 /* ignore errors while doing a macro scan as not all object macros
1241 * have valid expressions */
1242 if (!scanner->macro_scan)
1244 fprintf(stderr, "%s:%d: %s\n",
1245 scanner->current_filename, lineno, s);
1250 gi_source_scanner_parse_file (GISourceScanner *scanner, FILE *file)
1252 g_return_val_if_fail (file != NULL, FALSE);
1254 const_table = g_hash_table_new_full (g_str_hash, g_str_equal,
1255 g_free, (GDestroyNotify)gi_source_symbol_unref);
1261 g_hash_table_destroy (const_table);
1270 gi_source_scanner_lex_filename (GISourceScanner *scanner, const gchar *filename)
1272 yyin = fopen (filename, "r");
1274 while (yylex (scanner) != YYEOF)