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_type_list
104 %type <list> parameter_list
105 %type <list> struct_declaration
106 %type <list> struct_declaration_list
107 %type <list> struct_declarator_list
108 %type <storage_class_specifier> storage_class_specifier
109 %type <type_qualifier> type_qualifier
110 %type <type_qualifier> type_qualifier_list
111 %type <function_specifier> function_specifier
112 %type <symbol> expression
113 %type <symbol> constant_expression
114 %type <symbol> conditional_expression
115 %type <symbol> logical_and_expression
116 %type <symbol> logical_or_expression
117 %type <symbol> inclusive_or_expression
118 %type <symbol> exclusive_or_expression
119 %type <symbol> multiplicative_expression
120 %type <symbol> additive_expression
121 %type <symbol> shift_expression
122 %type <symbol> relational_expression
123 %type <symbol> equality_expression
124 %type <symbol> and_expression
125 %type <symbol> cast_expression
126 %type <symbol> assignment_expression
127 %type <symbol> unary_expression
128 %type <symbol> postfix_expression
129 %type <symbol> primary_expression
130 %type <unary_operator> unary_operator
131 %type <str> function_macro
132 %type <str> object_macro
133 %type <symbol> strings
137 /* A.2.1 Expressions. */
142 $$ = g_hash_table_lookup (const_table, $1);
144 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
146 $$ = gi_source_symbol_ref ($$);
151 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
152 $$->const_int_set = TRUE;
153 if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) {
154 $$->const_int = strtol (yytext + 2, NULL, 16);
155 } else if (g_str_has_prefix (yytext, "0") && strlen (yytext) > 1) {
156 $$->const_int = strtol (yytext + 1, NULL, 8);
158 $$->const_int = atoi (yytext);
163 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
167 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
176 /* concatenate adjacent string literal tokens */
180 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
181 yytext[strlen (yytext) - 1] = '\0';
182 $$->const_string = g_strcompress (yytext + 1);
186 char *strings, *string2;
188 yytext[strlen (yytext) - 1] = '\0';
189 string2 = g_strcompress (yytext + 1);
190 strings = g_strconcat ($$->const_string, string2, NULL);
191 g_free ($$->const_string);
193 $$->const_string = strings;
200 $$ = g_strdup (yytext);
204 identifier_or_typedef_name
211 | postfix_expression '[' expression ']'
213 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
215 | postfix_expression '(' argument_expression_list ')'
217 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
219 | postfix_expression '(' ')'
221 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
223 | postfix_expression '.' identifier_or_typedef_name
225 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
227 | postfix_expression ARROW identifier_or_typedef_name
229 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
231 | postfix_expression PLUSPLUS
233 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
235 | postfix_expression MINUSMINUS
237 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
241 argument_expression_list
242 : assignment_expression
243 | argument_expression_list ',' assignment_expression
248 | PLUSPLUS unary_expression
250 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
252 | MINUSMINUS unary_expression
254 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
256 | unary_operator cast_expression
264 $$->const_int = -$2->const_int;
266 case UNARY_BITWISE_COMPLEMENT:
268 $$->const_int = ~$2->const_int;
270 case UNARY_LOGICAL_NEGATION:
272 $$->const_int = !gi_source_symbol_get_const_boolean ($2);
275 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
279 | SIZEOF unary_expression
281 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
283 | SIZEOF '(' type_name ')'
286 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
293 $$ = UNARY_ADDRESS_OF;
297 $$ = UNARY_POINTER_INDIRECTION;
309 $$ = UNARY_BITWISE_COMPLEMENT;
313 $$ = UNARY_LOGICAL_NEGATION;
319 | '(' type_name ')' cast_expression
326 multiplicative_expression
328 | multiplicative_expression '*' cast_expression
330 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
331 $$->const_int_set = TRUE;
332 $$->const_int = $1->const_int * $3->const_int;
334 | multiplicative_expression '/' cast_expression
336 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
337 $$->const_int_set = TRUE;
338 if ($3->const_int != 0) {
339 $$->const_int = $1->const_int / $3->const_int;
342 | multiplicative_expression '%' cast_expression
344 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
345 $$->const_int_set = TRUE;
346 $$->const_int = $1->const_int % $3->const_int;
351 : multiplicative_expression
352 | additive_expression '+' multiplicative_expression
354 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
355 $$->const_int_set = TRUE;
356 $$->const_int = $1->const_int + $3->const_int;
358 | additive_expression '-' multiplicative_expression
360 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
361 $$->const_int_set = TRUE;
362 $$->const_int = $1->const_int - $3->const_int;
367 : additive_expression
368 | shift_expression SL additive_expression
370 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
371 $$->const_int_set = TRUE;
372 $$->const_int = $1->const_int << $3->const_int;
374 | shift_expression SR additive_expression
376 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
377 $$->const_int_set = TRUE;
378 $$->const_int = $1->const_int >> $3->const_int;
382 relational_expression
384 | relational_expression '<' shift_expression
386 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
387 $$->const_int_set = TRUE;
388 $$->const_int = $1->const_int < $3->const_int;
390 | relational_expression '>' shift_expression
392 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
393 $$->const_int_set = TRUE;
394 $$->const_int = $1->const_int > $3->const_int;
396 | relational_expression LTEQ shift_expression
398 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
399 $$->const_int_set = TRUE;
400 $$->const_int = $1->const_int <= $3->const_int;
402 | relational_expression GTEQ shift_expression
404 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
405 $$->const_int_set = TRUE;
406 $$->const_int = $1->const_int >= $3->const_int;
411 : relational_expression
412 | equality_expression EQ relational_expression
414 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
415 $$->const_int_set = TRUE;
416 $$->const_int = $1->const_int == $3->const_int;
418 | equality_expression NOTEQ relational_expression
420 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
421 $$->const_int_set = TRUE;
422 $$->const_int = $1->const_int != $3->const_int;
427 : equality_expression
428 | and_expression '&' equality_expression
430 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
431 $$->const_int_set = TRUE;
432 $$->const_int = $1->const_int & $3->const_int;
436 exclusive_or_expression
438 | exclusive_or_expression '^' and_expression
440 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
441 $$->const_int_set = TRUE;
442 $$->const_int = $1->const_int ^ $3->const_int;
446 inclusive_or_expression
447 : exclusive_or_expression
448 | inclusive_or_expression '|' exclusive_or_expression
450 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
451 $$->const_int_set = TRUE;
452 $$->const_int = $1->const_int | $3->const_int;
456 logical_and_expression
457 : inclusive_or_expression
458 | logical_and_expression ANDAND inclusive_or_expression
460 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
461 $$->const_int_set = TRUE;
463 gi_source_symbol_get_const_boolean ($1) &&
464 gi_source_symbol_get_const_boolean ($3);
468 logical_or_expression
469 : logical_and_expression
470 | logical_or_expression OROR logical_and_expression
472 $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
473 $$->const_int_set = TRUE;
475 gi_source_symbol_get_const_boolean ($1) ||
476 gi_source_symbol_get_const_boolean ($3);
480 conditional_expression
481 : logical_or_expression
482 | logical_or_expression '?' expression ':' conditional_expression
484 $$ = gi_source_symbol_get_const_boolean ($1) ? $3 : $5;
488 assignment_expression
489 : conditional_expression
490 | unary_expression assignment_operator assignment_expression
492 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
511 : assignment_expression
512 | expression ',' assignment_expression
514 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
519 : conditional_expression
522 /* A.2.2 Declarations. */
525 : declaration_specifiers init_declarator_list ';'
528 for (l = $2; l != NULL; l = l->next) {
529 GISourceSymbol *sym = l->data;
530 gi_source_symbol_merge_type (sym, gi_source_type_copy ($1));
531 if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) {
532 sym->type = CSYMBOL_TYPE_TYPEDEF;
533 } else if (sym->base_type->type == CTYPE_FUNCTION) {
534 sym->type = CSYMBOL_TYPE_FUNCTION;
536 sym->type = CSYMBOL_TYPE_OBJECT;
538 gi_source_scanner_add_symbol (scanner, sym);
539 gi_source_symbol_unref (sym);
543 | declaration_specifiers ';'
549 declaration_specifiers
550 : storage_class_specifier declaration_specifiers
553 $$->storage_class_specifier |= $1;
555 | storage_class_specifier
557 $$ = gi_source_type_new (CTYPE_INVALID);
558 $$->storage_class_specifier |= $1;
560 | type_specifier declaration_specifiers
566 | type_qualifier declaration_specifiers
569 $$->type_qualifier |= $1;
573 $$ = gi_source_type_new (CTYPE_INVALID);
574 $$->type_qualifier |= $1;
576 | function_specifier declaration_specifiers
579 $$->function_specifier |= $1;
583 $$ = gi_source_type_new (CTYPE_INVALID);
584 $$->function_specifier |= $1;
591 $$ = g_list_append (NULL, $1);
593 | init_declarator_list ',' init_declarator
595 $$ = g_list_append ($1, $3);
601 | declarator '=' initializer
604 storage_class_specifier
607 $$ = STORAGE_CLASS_TYPEDEF;
611 $$ = STORAGE_CLASS_EXTERN;
615 $$ = STORAGE_CLASS_STATIC;
619 $$ = STORAGE_CLASS_AUTO;
623 $$ = STORAGE_CLASS_REGISTER;
630 $$ = gi_source_type_new (CTYPE_VOID);
634 $$ = gi_source_basic_type_new ("char");
638 $$ = gi_source_basic_type_new ("short");
642 $$ = gi_source_basic_type_new ("int");
646 $$ = gi_source_basic_type_new ("long");
650 $$ = gi_source_basic_type_new ("float");
654 $$ = gi_source_basic_type_new ("double");
658 $$ = gi_source_basic_type_new ("signed");
662 $$ = gi_source_basic_type_new ("unsigned");
666 $$ = gi_source_basic_type_new ("bool");
668 | struct_or_union_specifier
672 $$ = gi_source_typedef_new ($1);
677 struct_or_union_specifier
678 : struct_or_union identifier_or_typedef_name '{' struct_declaration_list '}'
684 GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
685 if ($$->type == CTYPE_STRUCT) {
686 sym->type = CSYMBOL_TYPE_STRUCT;
687 } else if ($$->type == CTYPE_UNION) {
688 sym->type = CSYMBOL_TYPE_UNION;
690 g_assert_not_reached ();
692 sym->ident = g_strdup ($$->name);
693 sym->base_type = gi_source_type_copy ($$);
694 gi_source_scanner_add_symbol (scanner, sym);
695 gi_source_symbol_unref (sym);
697 | struct_or_union '{' struct_declaration_list '}'
702 | struct_or_union identifier_or_typedef_name
712 $$ = gi_source_struct_new (NULL);
716 $$ = gi_source_union_new (NULL);
720 struct_declaration_list
722 | struct_declaration_list struct_declaration
724 $$ = g_list_concat ($1, $2);
729 : specifier_qualifier_list struct_declarator_list ';'
733 for (l = $2; l != NULL; l = l->next)
735 GISourceSymbol *sym = l->data;
736 if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF)
737 sym->type = CSYMBOL_TYPE_TYPEDEF;
739 sym->type = CSYMBOL_TYPE_MEMBER;
740 gi_source_symbol_merge_type (sym, gi_source_type_copy ($1));
741 $$ = g_list_append ($$, sym);
747 specifier_qualifier_list
748 : type_specifier specifier_qualifier_list
754 | type_qualifier specifier_qualifier_list
757 $$->type_qualifier |= $1;
761 $$ = gi_source_type_new (CTYPE_INVALID);
762 $$->type_qualifier |= $1;
766 struct_declarator_list
769 $$ = g_list_append (NULL, $1);
771 | struct_declarator_list ',' struct_declarator
773 $$ = g_list_append ($1, $3);
778 : /* empty, support for anonymous structs and unions */
780 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
783 | ':' constant_expression
785 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
787 | declarator ':' constant_expression
791 : ENUM identifier_or_typedef_name '{' enumerator_list '}'
793 $$ = gi_source_enum_new ($2);
795 last_enum_value = -1;
797 | ENUM '{' enumerator_list '}'
799 $$ = gi_source_enum_new (NULL);
801 last_enum_value = -1;
803 | ENUM identifier_or_typedef_name '{' enumerator_list ',' '}'
805 $$ = gi_source_enum_new ($2);
807 last_enum_value = -1;
809 | ENUM '{' enumerator_list ',' '}'
811 $$ = gi_source_enum_new (NULL);
813 last_enum_value = -1;
815 | ENUM identifier_or_typedef_name
817 $$ = gi_source_enum_new ($2);
824 $$ = g_list_append (NULL, $1);
826 | enumerator_list ',' enumerator
828 $$ = g_list_append ($1, $3);
835 $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
837 $$->const_int_set = TRUE;
838 $$->const_int = ++last_enum_value;
839 g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$));
841 | identifier '=' constant_expression
843 $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
845 $$->const_int_set = TRUE;
846 $$->const_int = $3->const_int;
847 last_enum_value = $$->const_int;
848 g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$));
855 $$ = TYPE_QUALIFIER_CONST;
859 $$ = TYPE_QUALIFIER_RESTRICT;
863 $$ = TYPE_QUALIFIER_EXTENSION;
867 $$ = TYPE_QUALIFIER_VOLATILE;
874 $$ = FUNCTION_INLINE;
879 : pointer direct_declarator
882 gi_source_symbol_merge_type ($$, $1);
890 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
897 | direct_declarator '[' assignment_expression ']'
900 gi_source_symbol_merge_type ($$, gi_source_array_new ());
902 | direct_declarator '[' ']'
905 gi_source_symbol_merge_type ($$, gi_source_array_new ());
907 | direct_declarator '(' parameter_type_list ')'
909 GISourceType *func = gi_source_function_new ();
910 // ignore (void) parameter list
911 if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
912 func->child_list = $3;
915 gi_source_symbol_merge_type ($$, func);
917 | direct_declarator '(' identifier_list ')'
919 GISourceType *func = gi_source_function_new ();
920 func->child_list = $3;
922 gi_source_symbol_merge_type ($$, func);
924 | direct_declarator '(' ')'
926 GISourceType *func = gi_source_function_new ();
928 gi_source_symbol_merge_type ($$, func);
933 : '*' type_qualifier_list
935 $$ = gi_source_pointer_new (NULL);
936 $$->type_qualifier = $2;
940 $$ = gi_source_pointer_new (NULL);
942 | '*' type_qualifier_list pointer
944 $$ = gi_source_pointer_new ($3);
945 $$->type_qualifier = $2;
949 $$ = gi_source_pointer_new ($2);
955 | type_qualifier_list type_qualifier
963 | parameter_list ',' ELLIPSIS
967 : parameter_declaration
969 $$ = g_list_append (NULL, $1);
971 | parameter_list ',' parameter_declaration
973 $$ = g_list_append ($1, $3);
977 parameter_declaration
978 : declaration_specifiers declarator
981 gi_source_symbol_merge_type ($$, $1);
983 | declaration_specifiers abstract_declarator
986 gi_source_symbol_merge_type ($$, $1);
988 | declaration_specifiers
990 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
998 GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1000 $$ = g_list_append (NULL, sym);
1002 | identifier_list ',' identifier
1004 GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1006 $$ = g_list_append ($1, sym);
1011 : specifier_qualifier_list
1012 | specifier_qualifier_list abstract_declarator
1018 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1019 gi_source_symbol_merge_type ($$, $1);
1021 | direct_abstract_declarator
1022 | pointer direct_abstract_declarator
1025 gi_source_symbol_merge_type ($$, $1);
1029 direct_abstract_declarator
1030 : '(' abstract_declarator ')'
1036 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1037 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1039 | '[' assignment_expression ']'
1041 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1042 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1044 | direct_abstract_declarator '[' ']'
1047 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1049 | direct_abstract_declarator '[' assignment_expression ']'
1052 gi_source_symbol_merge_type ($$, gi_source_array_new ());
1056 GISourceType *func = gi_source_function_new ();
1057 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1058 gi_source_symbol_merge_type ($$, func);
1060 | '(' parameter_type_list ')'
1062 GISourceType *func = gi_source_function_new ();
1063 // ignore (void) parameter list
1064 if ($2 != NULL && ($2->next != NULL || ((GISourceSymbol *) $2->data)->base_type->type != CTYPE_VOID)) {
1065 func->child_list = $2;
1067 $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
1068 gi_source_symbol_merge_type ($$, func);
1070 | direct_abstract_declarator '(' ')'
1072 GISourceType *func = gi_source_function_new ();
1074 gi_source_symbol_merge_type ($$, func);
1076 | direct_abstract_declarator '(' parameter_type_list ')'
1078 GISourceType *func = gi_source_function_new ();
1079 // ignore (void) parameter list
1080 if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
1081 func->child_list = $3;
1084 gi_source_symbol_merge_type ($$, func);
1091 $$ = g_strdup (yytext);
1096 : assignment_expression
1097 | '{' initializer_list '}'
1098 | '{' initializer_list ',' '}'
1103 | initializer_list ',' initializer
1106 /* A.2.3 Statements. */
1110 | compound_statement
1111 | expression_statement
1112 | selection_statement
1113 | iteration_statement
1118 : identifier_or_typedef_name ':' statement
1119 | CASE constant_expression ':' statement
1120 | DEFAULT ':' statement
1125 | '{' block_item_list '}'
1130 | block_item_list block_item
1138 expression_statement
1144 : IF '(' expression ')' statement
1145 | IF '(' expression ')' statement ELSE statement
1146 | SWITCH '(' expression ')' statement
1150 : WHILE '(' expression ')' statement
1151 | DO statement WHILE '(' expression ')' ';'
1152 | FOR '(' ';' ';' ')' statement
1153 | FOR '(' expression ';' ';' ')' statement
1154 | FOR '(' ';' expression ';' ')' statement
1155 | FOR '(' expression ';' expression ';' ')' statement
1156 | FOR '(' ';' ';' expression ')' statement
1157 | FOR '(' expression ';' ';' expression ')' statement
1158 | FOR '(' ';' expression ';' expression ')' statement
1159 | FOR '(' expression ';' expression ';' expression ')' statement
1163 : GOTO identifier_or_typedef_name ';'
1167 | RETURN expression ';'
1170 /* A.2.4 External definitions. */
1173 : external_declaration
1174 | translation_unit external_declaration
1177 external_declaration
1178 : function_definition
1184 : declaration_specifiers declarator declaration_list compound_statement
1185 | declaration_specifiers declarator compound_statement
1190 | declaration_list declaration
1198 $$ = g_strdup (yytext + strlen ("#define "));
1205 $$ = g_strdup (yytext + strlen ("#define "));
1209 function_macro_define
1210 : function_macro '(' identifier_list ')'
1214 : object_macro constant_expression
1216 if ($2->const_int_set || $2->const_string != NULL) {
1218 gi_source_scanner_add_symbol (scanner, $2);
1219 gi_source_symbol_unref ($2);
1225 : function_macro_define
1226 | object_macro_define
1232 yyerror (GISourceScanner *scanner, const char *s)
1234 /* ignore errors while doing a macro scan as not all object macros
1235 * have valid expressions */
1236 if (!scanner->macro_scan)
1238 fprintf(stderr, "%s:%d: %s\n",
1239 scanner->current_filename, lineno, s);
1244 gi_source_scanner_parse_file (GISourceScanner *scanner, FILE *file)
1246 g_return_val_if_fail (file != NULL, FALSE);
1248 const_table = g_hash_table_new_full (g_str_hash, g_str_equal,
1249 g_free, (GDestroyNotify)gi_source_symbol_unref);
1255 g_hash_table_destroy (const_table);
1264 gi_source_scanner_lex_filename (GISourceScanner *scanner, const gchar *filename)
1266 yyin = fopen (filename, "r");
1268 while (yylex (scanner) != YYEOF)