+++ /dev/null
-/* -*- Mode: C -*-
-/* GObject introspection: C lexer
- *
- * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it>
- * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-%{
-#include <ctype.h>
-#include <stdio.h>
-
-#include <glib.h>
-#include "sourcescanner.h"
-#include "scannerparser.h"
-#include "grealpath.h"
-
-int lineno;
-
-extern int yylex (GISourceScanner *scanner);
-#define YY_DECL int yylex (GISourceScanner *scanner)
-static int yywrap (void);
-static void parse_comment (GISourceScanner *scanner);
-static void process_directive (GISourceScanner *scanner);
-static int check_identifier (GISourceScanner *scanner, const char *);
-%}
-
-intsuffix ([uU][lL]?)|([lL][uU]?)
-fracconst ([0-9]*\.[0-9]+)|([0-9]+\.)
-exppart [eE][-+]?[0-9]+
-floatsuffix [fFlL]
-chartext ([^\'])|(\\.)
-stringtext ([^\"])|(\\.)
-
-%%
-
-"\n" { ++lineno; } /* " */
-[\t\f\v\r ]+ { /* Ignore whitespace. */ }
-
-"/*" { parse_comment(scanner); }
-"//".* { }
-
-"#define "[a-zA-Z_][a-zA-Z_0-9]*"(" { yyless (yyleng - 1); return FUNCTION_MACRO; }
-"#define "[a-zA-Z_][a-zA-Z_0-9]* { return OBJECT_MACRO; }
-
-"#" { process_directive(scanner); }
-
-"{" { return '{'; }
-"<%" { return '{'; }
-"}" { return '}'; }
-"%>" { return '}'; }
-"[" { return '['; }
-"<:" { return '['; }
-"]" { return ']'; }
-":>" { return ']'; }
-"(" { return '('; }
-")" { return ')'; }
-";" { return ';'; }
-":" { return ':'; }
-"..." { return ELLIPSIS; }
-"?" { return '?'; }
-"." { return '.'; }
-"+" { return '+'; }
-"-" { return '-'; }
-"*" { return '*'; }
-"/" { return '/'; }
-"%" { return '%'; }
-"^" { return '^'; }
-"&" { return '&'; }
-"|" { return '|'; }
-"~" { return '~'; }
-"!" { return '!'; }
-"=" { return '='; }
-"<" { return '<'; }
-">" { return '>'; }
-"+=" { return ADDEQ; }
-"-=" { return SUBEQ; }
-"*=" { return MULEQ; }
-"/=" { return DIVEQ; }
-"%=" { return MODEQ; }
-"^=" { return XOREQ; }
-"&=" { return ANDEQ; }
-"|=" { return OREQ; }
-"<<" { return SL; }
-">>" { return SR; }
-"<<=" { return SLEQ; }
-">>=" { return SREQ; }
-"==" { return EQ; }
-"!=" { return NOTEQ; }
-"<=" { return LTEQ; }
-">=" { return GTEQ; }
-"&&" { return ANDAND; }
-"||" { return OROR; }
-"++" { return PLUSPLUS; }
-"--" { return MINUSMINUS; }
-"," { return ','; }
-"->" { return ARROW; }
-
-[a-zA-Z_][a-zA-Z_0-9]* { if (scanner->macro_scan) return IDENTIFIER; else REJECT; }
-
-"auto" { return AUTO; }
-"_Bool" { return BOOL; }
-"break" { return BREAK; }
-"case" { return CASE; }
-"char" { return CHAR; }
-"const" { return CONST; }
-"continue" { return CONTINUE; }
-"default" { return DEFAULT; }
-"do" { return DO; }
-"double" { return DOUBLE; }
-"else" { return ELSE; }
-"enum" { return ENUM; }
-"extern" { return EXTERN; }
-"float" { return FLOAT; }
-"for" { return FOR; }
-"goto" { return GOTO; }
-"if" { return IF; }
-"inline" { return INLINE; }
-"int" { return INT; }
-"long" { return LONG; }
-"register" { return REGISTER; }
-"restrict" { return RESTRICT; }
-"return" { return RETURN; }
-"short" { return SHORT; }
-"signed" { return SIGNED; }
-"sizeof" { return SIZEOF; }
-"static" { return STATIC; }
-"struct" { return STRUCT; }
-"switch" { return SWITCH; }
-"typedef" { return TYPEDEF; }
-"union" { return UNION; }
-"unsigned" { return UNSIGNED; }
-"void" { return VOID; }
-"volatile" { return VOLATILE; }
-"while" { return WHILE; }
-
-[a-zA-Z_][a-zA-Z_0-9]* { return check_identifier(scanner, yytext); }
-
-"0"[xX][0-9a-fA-F]+{intsuffix}? { return INTEGER; }
-"0"[0-7]+{intsuffix}? { return INTEGER; }
-[0-9]+{intsuffix}? { return INTEGER; }
-
-{fracconst}{exppart}?{floatsuffix}? { return FLOATING; }
-[0-9]+{exppart}{floatsuffix}? { return FLOATING; }
-
-"'"{chartext}*"'" { return CHARACTER; }
-"L'"{chartext}*"'" { return CHARACTER; }
-
-"\""{stringtext}*"\"" { return STRING; }
-"L\""{stringtext}*"\"" { return STRING; }
-
-. { fprintf(stderr, "%s:%d: unexpected character `%c'\n", scanner->current_filename, lineno, yytext[0]); }
-
-%%
-
-static int
-yywrap (void)
-{
- return 1;
-}
-
-
-static void
-parse_gtkdoc (GISourceScanner *scanner,
- gchar *symbol,
- int *c1,
- int *c2)
-{
- gboolean isline = FALSE;
- gchar line[256];
- int i;
- gchar **parts;
- GISourceDirective *directive;
- char *name,*value;
- GSList *directives;
- GSList *options = NULL;
- char *rname;
-
- i = 0;
- do
- {
- *c1 = *c2;
- if (*c1 == '\n')
- {
- isline = TRUE;
- break;
- }
- if (i >= 256)
- break;
- line[i++] = *c1;
- *c2 = input();
- } while (*c2 != EOF && !(*c1 == '*' && *c2 == '/'));
-
- if (!isline)
- return;
-
- line[i] = '\0';
-
- parts = g_strsplit (line, ": ", 3);
-
- if (g_strv_length (parts) >= 2)
- {
- name = parts[0];
-
- if (g_strv_length (parts) == 3)
- {
- char *ptr = parts[1];
- GString *current = NULL;
- gboolean open = (*ptr == '(');
-
- current = g_string_new ("");
- value = parts[2];
-
- while (*ptr++)
- {
- if (*ptr == '(')
- open = TRUE;
- else if (*ptr != ')' && open)
- g_string_append_c (current, *ptr);
- else if (*ptr == ')') {
- options = g_slist_prepend (options, g_strdup (current->str));
- open = FALSE;
- }
- }
- g_string_free (current, TRUE);
- }
- else
- value = parts[1];
- }
- else /* parts == 1 */
- {
- name = parts[0];
- value = NULL;
- }
-
- /*
- * This is a special case for return values, name will only be
- * 'eturn' or a valid name, check the call site.
- * Context-sensitive parsing would probably be the right way to go
- */
- if (g_ascii_strncasecmp ("eturn", name, 5) == 0)
- rname = "return";
- else
- rname = name;
-
- directive = gi_source_directive_new (rname, value, options);
- directives = g_hash_table_lookup (scanner->directives_map, symbol);
- directives = g_slist_prepend (directives, directive);
- g_hash_table_replace (scanner->directives_map,
- g_strdup (symbol), directives);
-
- g_strfreev (parts);
-
-}
-
-
-static void
-parse_comment (GISourceScanner *scanner)
-{
- GString *symbol = NULL;
- gboolean startofline = FALSE, have_symbol = FALSE, start1 = FALSE, start_symbol = FALSE;
- int c1, c2;
-
- c1 = input();
- c2 = input();
-
- while (c2 != EOF && !(c1 == '*' && c2 == '/'))
- {
- if (c1 == ':')
- have_symbol = TRUE;
- else if (c1 == '\n')
- start1 = TRUE;
- else if (c1 == '*' && start1)
- start_symbol = TRUE;
- else if (!have_symbol && start_symbol)
- {
- if (!symbol)
- symbol = g_string_new ("");
- if (c1 != ' ')
- g_string_append_c (symbol, c1);
- }
-
- if (c1 == '\n')
- {
- ++lineno;
- startofline = TRUE;
- }
-
- c1 = c2;
- c2 = input();
-
- if ((c1 != '*' && c1 != ' '))
- startofline = FALSE;
-
- if (startofline && (c1 == ' ') && (c2 == '@' || (c2 == 'r') || (c2 == 'R')))
- {
- c1 = c2;
- c2 = input();
- if (symbol)
- parse_gtkdoc (scanner, symbol->str, &c1, &c2);
- }
- }
-
- if (symbol)
- g_string_free (symbol, TRUE);
-
-}
-
-static int
-check_identifier (GISourceScanner *scanner,
- const char *s)
-{
- /*
- * This function checks if `s' is a type name or an
- * identifier.
- */
-
- if (gi_source_scanner_is_typedef (scanner, s)) {
- return TYPEDEF_NAME;
- } else if (strcmp (s, "__builtin_va_list") == 0) {
- return TYPEDEF_NAME;
- }
-
- return IDENTIFIER;
-}
-
-static void
-process_directive (GISourceScanner *scanner)
-{
- /* extract current filename from #line directives */
- GString *filename_builder;
- gboolean in_string, found_filename;
-
- lineno = 0;
- found_filename = FALSE;
- in_string = FALSE;
- filename_builder = g_string_new ("");
-
- int c = input ();
- while (c != EOF && c != '\n') {
- if (!in_string) {
- if (c == '\"') {
- in_string = TRUE;
- found_filename = TRUE;
- } else if (c >= '0' && c <= '9') {
- if (!found_filename) {
- lineno = lineno * 10 + (c - '0');
- }
- }
- } else {
- if (c == '\"') {
- in_string = FALSE;
- } else if (c == '\\') {
- g_string_append_c (filename_builder, c);
- c = input ();
- g_string_append_c (filename_builder, c);
- } else {
- g_string_append_c (filename_builder, c);
- }
- }
- c = input ();
- }
-
- if (filename_builder->len > 0) {
- char *filename = g_strcompress (filename_builder->str);
- g_free (scanner->current_filename);
- scanner->current_filename = g_realpath(filename);
- g_free(filename);
- }
-
- g_string_free (filename_builder, TRUE);
-}
-
+++ /dev/null
-/* GObject introspection: C parser
- *
- * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it>
- * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-%{
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <glib.h>
-#include "sourcescanner.h"
-#include "scannerparser.h"
-
-extern FILE *yyin;
-extern int lineno;
-extern char *yytext;
-
-extern int yylex (GISourceScanner *scanner);
-static void yyerror (GISourceScanner *scanner, const char *str);
-
-static int last_enum_value = -1;
-static GHashTable *const_table = NULL;
-%}
-
-%error-verbose
-%union {
- char *str;
- GList *list;
- GISourceSymbol *symbol;
- GISourceType *ctype;
- StorageClassSpecifier storage_class_specifier;
- TypeQualifier type_qualifier;
- FunctionSpecifier function_specifier;
- UnaryOperator unary_operator;
-}
-
-%parse-param { GISourceScanner* scanner }
-%lex-param { GISourceScanner* scanner }
-
-%token <str> IDENTIFIER "identifier"
-%token <str> TYPEDEF_NAME "typedef-name"
-
-%token INTEGER FLOATING CHARACTER STRING
-
-%token ELLIPSIS ADDEQ SUBEQ MULEQ DIVEQ MODEQ XOREQ ANDEQ OREQ SL SR
-%token SLEQ SREQ EQ NOTEQ LTEQ GTEQ ANDAND OROR PLUSPLUS MINUSMINUS ARROW
-
-%token AUTO BOOL BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM
-%token EXTERN FLOAT FOR GOTO IF INLINE INT LONG REGISTER RESTRICT RETURN SHORT
-%token SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION UNSIGNED VOID VOLATILE
-%token WHILE
-
-%token FUNCTION_MACRO OBJECT_MACRO
-
-%start translation_unit
-
-%type <ctype> declaration_specifiers
-%type <ctype> enum_specifier
-%type <ctype> pointer
-%type <ctype> specifier_qualifier_list
-%type <ctype> type_name
-%type <ctype> struct_or_union
-%type <ctype> struct_or_union_specifier
-%type <ctype> type_specifier
-%type <str> identifier
-%type <str> typedef_name
-%type <str> identifier_or_typedef_name
-%type <symbol> abstract_declarator
-%type <symbol> init_declarator
-%type <symbol> declarator
-%type <symbol> enumerator
-%type <symbol> direct_abstract_declarator
-%type <symbol> direct_declarator
-%type <symbol> parameter_declaration
-%type <symbol> struct_declarator
-%type <list> enumerator_list
-%type <list> identifier_list
-%type <list> init_declarator_list
-%type <list> parameter_type_list
-%type <list> parameter_list
-%type <list> struct_declaration
-%type <list> struct_declaration_list
-%type <list> struct_declarator_list
-%type <storage_class_specifier> storage_class_specifier
-%type <type_qualifier> type_qualifier
-%type <type_qualifier> type_qualifier_list
-%type <function_specifier> function_specifier
-%type <symbol> expression
-%type <symbol> constant_expression
-%type <symbol> conditional_expression
-%type <symbol> logical_and_expression
-%type <symbol> logical_or_expression
-%type <symbol> inclusive_or_expression
-%type <symbol> exclusive_or_expression
-%type <symbol> multiplicative_expression
-%type <symbol> additive_expression
-%type <symbol> shift_expression
-%type <symbol> relational_expression
-%type <symbol> equality_expression
-%type <symbol> and_expression
-%type <symbol> cast_expression
-%type <symbol> assignment_expression
-%type <symbol> unary_expression
-%type <symbol> postfix_expression
-%type <symbol> primary_expression
-%type <unary_operator> unary_operator
-%type <str> function_macro
-%type <str> object_macro
-%type <symbol> strings
-
-%%
-
-/* A.2.1 Expressions. */
-
-primary_expression
- : identifier
- {
- $$ = g_hash_table_lookup (const_table, $1);
- if ($$ == NULL) {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- } else {
- $$ = gi_source_symbol_ref ($$);
- }
- }
- | INTEGER
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) {
- $$->const_int = strtol (yytext + 2, NULL, 16);
- } else if (g_str_has_prefix (yytext, "0") && strlen (yytext) > 1) {
- $$->const_int = strtol (yytext + 1, NULL, 8);
- } else {
- $$->const_int = atoi (yytext);
- }
- }
- | CHARACTER
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | FLOATING
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | strings
- | '(' expression ')'
- {
- $$ = $2;
- }
- ;
-
-/* concatenate adjacent string literal tokens */
-strings
- : STRING
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- yytext[strlen (yytext) - 1] = '\0';
- $$->const_string = g_strcompress (yytext + 1);
- }
- | strings STRING
- {
- char *strings, *string2;
- $$ = $1;
- yytext[strlen (yytext) - 1] = '\0';
- string2 = g_strcompress (yytext + 1);
- strings = g_strconcat ($$->const_string, string2, NULL);
- g_free ($$->const_string);
- g_free (string2);
- $$->const_string = strings;
- }
- ;
-
-identifier
- : IDENTIFIER
- {
- $$ = g_strdup (yytext);
- }
- ;
-
-identifier_or_typedef_name
- : identifier
- | typedef_name
- ;
-
-postfix_expression
- : primary_expression
- | postfix_expression '[' expression ']'
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | postfix_expression '(' argument_expression_list ')'
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | postfix_expression '(' ')'
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | postfix_expression '.' identifier_or_typedef_name
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | postfix_expression ARROW identifier_or_typedef_name
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | postfix_expression PLUSPLUS
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | postfix_expression MINUSMINUS
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- ;
-
-argument_expression_list
- : assignment_expression
- | argument_expression_list ',' assignment_expression
- ;
-
-unary_expression
- : postfix_expression
- | PLUSPLUS unary_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | MINUSMINUS unary_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | unary_operator cast_expression
- {
- switch ($1) {
- case UNARY_PLUS:
- $$ = $2;
- break;
- case UNARY_MINUS:
- $$ = $2;
- $$->const_int = -$2->const_int;
- break;
- case UNARY_BITWISE_COMPLEMENT:
- $$ = $2;
- $$->const_int = ~$2->const_int;
- break;
- case UNARY_LOGICAL_NEGATION:
- $$ = $2;
- $$->const_int = !gi_source_symbol_get_const_boolean ($2);
- break;
- default:
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- break;
- }
- }
- | SIZEOF unary_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | SIZEOF '(' type_name ')'
- {
- ctype_free ($3);
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- ;
-
-unary_operator
- : '&'
- {
- $$ = UNARY_ADDRESS_OF;
- }
- | '*'
- {
- $$ = UNARY_POINTER_INDIRECTION;
- }
- | '+'
- {
- $$ = UNARY_PLUS;
- }
- | '-'
- {
- $$ = UNARY_MINUS;
- }
- | '~'
- {
- $$ = UNARY_BITWISE_COMPLEMENT;
- }
- | '!'
- {
- $$ = UNARY_LOGICAL_NEGATION;
- }
- ;
-
-cast_expression
- : unary_expression
- | '(' type_name ')' cast_expression
- {
- ctype_free ($2);
- $$ = $4;
- }
- ;
-
-multiplicative_expression
- : cast_expression
- | multiplicative_expression '*' cast_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int * $3->const_int;
- }
- | multiplicative_expression '/' cast_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- if ($3->const_int != 0) {
- $$->const_int = $1->const_int / $3->const_int;
- }
- }
- | multiplicative_expression '%' cast_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int % $3->const_int;
- }
- ;
-
-additive_expression
- : multiplicative_expression
- | additive_expression '+' multiplicative_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int + $3->const_int;
- }
- | additive_expression '-' multiplicative_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int - $3->const_int;
- }
- ;
-
-shift_expression
- : additive_expression
- | shift_expression SL additive_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int << $3->const_int;
- }
- | shift_expression SR additive_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int >> $3->const_int;
- }
- ;
-
-relational_expression
- : shift_expression
- | relational_expression '<' shift_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int < $3->const_int;
- }
- | relational_expression '>' shift_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int > $3->const_int;
- }
- | relational_expression LTEQ shift_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int <= $3->const_int;
- }
- | relational_expression GTEQ shift_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int >= $3->const_int;
- }
- ;
-
-equality_expression
- : relational_expression
- | equality_expression EQ relational_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int == $3->const_int;
- }
- | equality_expression NOTEQ relational_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int != $3->const_int;
- }
- ;
-
-and_expression
- : equality_expression
- | and_expression '&' equality_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int & $3->const_int;
- }
- ;
-
-exclusive_or_expression
- : and_expression
- | exclusive_or_expression '^' and_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int ^ $3->const_int;
- }
- ;
-
-inclusive_or_expression
- : exclusive_or_expression
- | inclusive_or_expression '|' exclusive_or_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int = $1->const_int | $3->const_int;
- }
- ;
-
-logical_and_expression
- : inclusive_or_expression
- | logical_and_expression ANDAND inclusive_or_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int =
- gi_source_symbol_get_const_boolean ($1) &&
- gi_source_symbol_get_const_boolean ($3);
- }
- ;
-
-logical_or_expression
- : logical_and_expression
- | logical_or_expression OROR logical_and_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
- $$->const_int_set = TRUE;
- $$->const_int =
- gi_source_symbol_get_const_boolean ($1) ||
- gi_source_symbol_get_const_boolean ($3);
- }
- ;
-
-conditional_expression
- : logical_or_expression
- | logical_or_expression '?' expression ':' conditional_expression
- {
- $$ = gi_source_symbol_get_const_boolean ($1) ? $3 : $5;
- }
- ;
-
-assignment_expression
- : conditional_expression
- | unary_expression assignment_operator assignment_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- ;
-
-assignment_operator
- : '='
- | MULEQ
- | DIVEQ
- | MODEQ
- | ADDEQ
- | SUBEQ
- | SLEQ
- | SREQ
- | ANDEQ
- | XOREQ
- | OREQ
- ;
-
-expression
- : assignment_expression
- | expression ',' assignment_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- ;
-
-constant_expression
- : conditional_expression
- ;
-
-/* A.2.2 Declarations. */
-
-declaration
- : declaration_specifiers init_declarator_list ';'
- {
- GList *l;
- for (l = $2; l != NULL; l = l->next) {
- GISourceSymbol *sym = l->data;
- gi_source_symbol_merge_type (sym, gi_source_type_copy ($1));
- if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) {
- sym->type = CSYMBOL_TYPE_TYPEDEF;
- } else if (sym->base_type->type == CTYPE_FUNCTION) {
- sym->type = CSYMBOL_TYPE_FUNCTION;
- } else {
- sym->type = CSYMBOL_TYPE_OBJECT;
- }
- gi_source_scanner_add_symbol (scanner, sym);
- gi_source_symbol_unref (sym);
- }
- ctype_free ($1);
- }
- | declaration_specifiers ';'
- {
- ctype_free ($1);
- }
- ;
-
-declaration_specifiers
- : storage_class_specifier declaration_specifiers
- {
- $$ = $2;
- $$->storage_class_specifier |= $1;
- }
- | storage_class_specifier
- {
- $$ = gi_source_type_new (CTYPE_INVALID);
- $$->storage_class_specifier |= $1;
- }
- | type_specifier declaration_specifiers
- {
- $$ = $1;
- $$->base_type = $2;
- }
- | type_specifier
- | type_qualifier declaration_specifiers
- {
- $$ = $2;
- $$->type_qualifier |= $1;
- }
- | type_qualifier
- {
- $$ = gi_source_type_new (CTYPE_INVALID);
- $$->type_qualifier |= $1;
- }
- | function_specifier declaration_specifiers
- {
- $$ = $2;
- $$->function_specifier |= $1;
- }
- | function_specifier
- {
- $$ = gi_source_type_new (CTYPE_INVALID);
- $$->function_specifier |= $1;
- }
- ;
-
-init_declarator_list
- : init_declarator
- {
- $$ = g_list_append (NULL, $1);
- }
- | init_declarator_list ',' init_declarator
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-init_declarator
- : declarator
- | declarator '=' initializer
- ;
-
-storage_class_specifier
- : TYPEDEF
- {
- $$ = STORAGE_CLASS_TYPEDEF;
- }
- | EXTERN
- {
- $$ = STORAGE_CLASS_EXTERN;
- }
- | STATIC
- {
- $$ = STORAGE_CLASS_STATIC;
- }
- | AUTO
- {
- $$ = STORAGE_CLASS_AUTO;
- }
- | REGISTER
- {
- $$ = STORAGE_CLASS_REGISTER;
- }
- ;
-
-type_specifier
- : VOID
- {
- $$ = gi_source_type_new (CTYPE_VOID);
- }
- | CHAR
- {
- $$ = gi_source_basic_type_new ("char");
- }
- | SHORT
- {
- $$ = gi_source_basic_type_new ("short");
- }
- | INT
- {
- $$ = gi_source_basic_type_new ("int");
- }
- | LONG
- {
- $$ = gi_source_basic_type_new ("long");
- }
- | FLOAT
- {
- $$ = gi_source_basic_type_new ("float");
- }
- | DOUBLE
- {
- $$ = gi_source_basic_type_new ("double");
- }
- | SIGNED
- {
- $$ = gi_source_basic_type_new ("signed");
- }
- | UNSIGNED
- {
- $$ = gi_source_basic_type_new ("unsigned");
- }
- | BOOL
- {
- $$ = gi_source_basic_type_new ("bool");
- }
- | struct_or_union_specifier
- | enum_specifier
- | typedef_name
- {
- $$ = gi_source_typedef_new ($1);
- g_free ($1);
- }
- ;
-
-struct_or_union_specifier
- : struct_or_union identifier_or_typedef_name '{' struct_declaration_list '}'
- {
- $$ = $1;
- $$->name = $2;
- $$->child_list = $4;
-
- GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- if ($$->type == CTYPE_STRUCT) {
- sym->type = CSYMBOL_TYPE_STRUCT;
- } else if ($$->type == CTYPE_UNION) {
- sym->type = CSYMBOL_TYPE_UNION;
- } else {
- g_assert_not_reached ();
- }
- sym->ident = g_strdup ($$->name);
- sym->base_type = gi_source_type_copy ($$);
- gi_source_scanner_add_symbol (scanner, sym);
- gi_source_symbol_unref (sym);
- }
- | struct_or_union '{' struct_declaration_list '}'
- {
- $$ = $1;
- $$->child_list = $3;
- }
- | struct_or_union identifier_or_typedef_name
- {
- $$ = $1;
- $$->name = $2;
- }
- ;
-
-struct_or_union
- : STRUCT
- {
- $$ = gi_source_struct_new (NULL);
- }
- | UNION
- {
- $$ = gi_source_union_new (NULL);
- }
- ;
-
-struct_declaration_list
- : struct_declaration
- | struct_declaration_list struct_declaration
- {
- $$ = g_list_concat ($1, $2);
- }
- ;
-
-struct_declaration
- : specifier_qualifier_list struct_declarator_list ';'
- {
- GList *l;
- $$ = NULL;
- for (l = $2; l != NULL; l = l->next) {
- GISourceSymbol *sym = l->data;
- if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) {
- sym->type = CSYMBOL_TYPE_TYPEDEF;
- }
- gi_source_symbol_merge_type (sym, gi_source_type_copy ($1));
- $$ = g_list_append ($$, sym);
- }
- ctype_free ($1);
- }
- ;
-
-specifier_qualifier_list
- : type_specifier specifier_qualifier_list
- {
- $$ = $1;
- $$->base_type = $2;
- }
- | type_specifier
- | type_qualifier specifier_qualifier_list
- {
- $$ = $2;
- $$->type_qualifier |= $1;
- }
- | type_qualifier
- {
- $$ = gi_source_type_new (CTYPE_INVALID);
- $$->type_qualifier |= $1;
- }
- ;
-
-struct_declarator_list
- : struct_declarator
- {
- $$ = g_list_append (NULL, $1);
- }
- | struct_declarator_list ',' struct_declarator
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-struct_declarator
- : /* empty, support for anonymous structs and unions */
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | declarator
- | ':' constant_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- }
- | declarator ':' constant_expression
- ;
-
-enum_specifier
- : ENUM identifier_or_typedef_name '{' enumerator_list '}'
- {
- $$ = gi_source_enum_new ($2);
- $$->child_list = $4;
- last_enum_value = -1;
- }
- | ENUM '{' enumerator_list '}'
- {
- $$ = gi_source_enum_new (NULL);
- $$->child_list = $3;
- last_enum_value = -1;
- }
- | ENUM identifier_or_typedef_name '{' enumerator_list ',' '}'
- {
- $$ = gi_source_enum_new ($2);
- $$->child_list = $4;
- last_enum_value = -1;
- }
- | ENUM '{' enumerator_list ',' '}'
- {
- $$ = gi_source_enum_new (NULL);
- $$->child_list = $3;
- last_enum_value = -1;
- }
- | ENUM identifier_or_typedef_name
- {
- $$ = gi_source_enum_new ($2);
- }
- ;
-
-enumerator_list
- : enumerator
- {
- $$ = g_list_append (NULL, $1);
- }
- | enumerator_list ',' enumerator
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-enumerator
- : identifier
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
- $$->ident = $1;
- $$->const_int_set = TRUE;
- $$->const_int = ++last_enum_value;
- g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$));
- }
- | identifier '=' constant_expression
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
- $$->ident = $1;
- $$->const_int_set = TRUE;
- $$->const_int = $3->const_int;
- last_enum_value = $$->const_int;
- g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$));
- }
- ;
-
-type_qualifier
- : CONST
- {
- $$ = TYPE_QUALIFIER_CONST;
- }
- | RESTRICT
- {
- $$ = TYPE_QUALIFIER_RESTRICT;
- }
- | VOLATILE
- {
- $$ = TYPE_QUALIFIER_VOLATILE;
- }
- ;
-
-function_specifier
- : INLINE
- {
- $$ = FUNCTION_INLINE;
- }
- ;
-
-declarator
- : pointer direct_declarator
- {
- $$ = $2;
- gi_source_symbol_merge_type ($$, $1);
- }
- | direct_declarator
- ;
-
-direct_declarator
- : identifier
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- $$->ident = $1;
- }
- | '(' declarator ')'
- {
- $$ = $2;
- }
- | direct_declarator '[' assignment_expression ']'
- {
- $$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
- }
- | direct_declarator '[' ']'
- {
- $$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
- }
- | direct_declarator '(' parameter_type_list ')'
- {
- GISourceType *func = gi_source_function_new ();
- // ignore (void) parameter list
- if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
- func->child_list = $3;
- }
- $$ = $1;
- gi_source_symbol_merge_type ($$, func);
- }
- | direct_declarator '(' identifier_list ')'
- {
- GISourceType *func = gi_source_function_new ();
- func->child_list = $3;
- $$ = $1;
- gi_source_symbol_merge_type ($$, func);
- }
- | direct_declarator '(' ')'
- {
- GISourceType *func = gi_source_function_new ();
- $$ = $1;
- gi_source_symbol_merge_type ($$, func);
- }
- ;
-
-pointer
- : '*' type_qualifier_list
- {
- $$ = gi_source_pointer_new (NULL);
- $$->type_qualifier = $2;
- }
- | '*'
- {
- $$ = gi_source_pointer_new (NULL);
- }
- | '*' type_qualifier_list pointer
- {
- $$ = gi_source_pointer_new ($3);
- $$->type_qualifier = $2;
- }
- | '*' pointer
- {
- $$ = gi_source_pointer_new ($2);
- }
- ;
-
-type_qualifier_list
- : type_qualifier
- | type_qualifier_list type_qualifier
- {
- $$ = $1 | $2;
- }
- ;
-
-parameter_type_list
- : parameter_list
- | parameter_list ',' ELLIPSIS
- ;
-
-parameter_list
- : parameter_declaration
- {
- $$ = g_list_append (NULL, $1);
- }
- | parameter_list ',' parameter_declaration
- {
- $$ = g_list_append ($1, $3);
- }
- ;
-
-parameter_declaration
- : declaration_specifiers declarator
- {
- $$ = $2;
- gi_source_symbol_merge_type ($$, $1);
- }
- | declaration_specifiers abstract_declarator
- {
- $$ = $2;
- gi_source_symbol_merge_type ($$, $1);
- }
- | declaration_specifiers
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- $$->base_type = $1;
- }
- ;
-
-identifier_list
- : identifier
- {
- GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- sym->ident = $1;
- $$ = g_list_append (NULL, sym);
- }
- | identifier_list ',' identifier
- {
- GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- sym->ident = $3;
- $$ = g_list_append ($1, sym);
- }
- ;
-
-type_name
- : specifier_qualifier_list
- | specifier_qualifier_list abstract_declarator
- ;
-
-abstract_declarator
- : pointer
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, $1);
- }
- | direct_abstract_declarator
- | pointer direct_abstract_declarator
- {
- $$ = $2;
- gi_source_symbol_merge_type ($$, $1);
- }
- ;
-
-direct_abstract_declarator
- : '(' abstract_declarator ')'
- {
- $$ = $2;
- }
- | '[' ']'
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
- }
- | '[' assignment_expression ']'
- {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
- }
- | direct_abstract_declarator '[' ']'
- {
- $$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
- }
- | direct_abstract_declarator '[' assignment_expression ']'
- {
- $$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
- }
- | '(' ')'
- {
- GISourceType *func = gi_source_function_new ();
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, func);
- }
- | '(' parameter_type_list ')'
- {
- GISourceType *func = gi_source_function_new ();
- // ignore (void) parameter list
- if ($2 != NULL && ($2->next != NULL || ((GISourceSymbol *) $2->data)->base_type->type != CTYPE_VOID)) {
- func->child_list = $2;
- }
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, func);
- }
- | direct_abstract_declarator '(' ')'
- {
- GISourceType *func = gi_source_function_new ();
- $$ = $1;
- gi_source_symbol_merge_type ($$, func);
- }
- | direct_abstract_declarator '(' parameter_type_list ')'
- {
- GISourceType *func = gi_source_function_new ();
- // ignore (void) parameter list
- if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) {
- func->child_list = $3;
- }
- $$ = $1;
- gi_source_symbol_merge_type ($$, func);
- }
- ;
-
-typedef_name
- : TYPEDEF_NAME
- {
- $$ = g_strdup (yytext);
- }
- ;
-
-initializer
- : assignment_expression
- | '{' initializer_list '}'
- | '{' initializer_list ',' '}'
- ;
-
-initializer_list
- : initializer
- | initializer_list ',' initializer
- ;
-
-/* A.2.3 Statements. */
-
-statement
- : labeled_statement
- | compound_statement
- | expression_statement
- | selection_statement
- | iteration_statement
- | jump_statement
- ;
-
-labeled_statement
- : identifier_or_typedef_name ':' statement
- | CASE constant_expression ':' statement
- | DEFAULT ':' statement
- ;
-
-compound_statement
- : '{' '}'
- | '{' block_item_list '}'
- ;
-
-block_item_list
- : block_item
- | block_item_list block_item
- ;
-
-block_item
- : declaration
- | statement
- ;
-
-expression_statement
- : ';'
- | expression ';'
- ;
-
-selection_statement
- : IF '(' expression ')' statement
- | IF '(' expression ')' statement ELSE statement
- | SWITCH '(' expression ')' statement
- ;
-
-iteration_statement
- : WHILE '(' expression ')' statement
- | DO statement WHILE '(' expression ')' ';'
- | FOR '(' ';' ';' ')' statement
- | FOR '(' expression ';' ';' ')' statement
- | FOR '(' ';' expression ';' ')' statement
- | FOR '(' expression ';' expression ';' ')' statement
- | FOR '(' ';' ';' expression ')' statement
- | FOR '(' expression ';' ';' expression ')' statement
- | FOR '(' ';' expression ';' expression ')' statement
- | FOR '(' expression ';' expression ';' expression ')' statement
- ;
-
-jump_statement
- : GOTO identifier_or_typedef_name ';'
- | CONTINUE ';'
- | BREAK ';'
- | RETURN ';'
- | RETURN expression ';'
- ;
-
-/* A.2.4 External definitions. */
-
-translation_unit
- : external_declaration
- | translation_unit external_declaration
- ;
-
-external_declaration
- : function_definition
- | declaration
- | macro
- ;
-
-function_definition
- : declaration_specifiers declarator declaration_list compound_statement
- | declaration_specifiers declarator compound_statement
- ;
-
-declaration_list
- : declaration
- | declaration_list declaration
- ;
-
-/* Macros */
-
-function_macro
- : FUNCTION_MACRO
- {
- $$ = g_strdup (yytext + strlen ("#define "));
- }
- ;
-
-object_macro
- : OBJECT_MACRO
- {
- $$ = g_strdup (yytext + strlen ("#define "));
- }
- ;
-
-function_macro_define
- : function_macro '(' identifier_list ')'
- ;
-
-object_macro_define
- : object_macro constant_expression
- {
- if ($2->const_int_set || $2->const_string != NULL) {
- $2->ident = $1;
- gi_source_scanner_add_symbol (scanner, $2);
- gi_source_symbol_unref ($2);
- }
- }
- ;
-
-macro
- : function_macro_define
- | object_macro_define
- | error
- ;
-
-%%
-static void
-yyerror (GISourceScanner *scanner, const char *s)
-{
- /* ignore errors while doing a macro scan as not all object macros
- * have valid expressions */
- if (!scanner->macro_scan)
- {
- fprintf(stderr, "%s:%d: %s\n",
- scanner->current_filename, lineno, s);
- }
-}
-
-gboolean
-gi_source_scanner_parse_file (GISourceScanner *scanner, FILE *file)
-{
- g_return_val_if_fail (file != NULL, FALSE);
-
- const_table = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify)gi_source_symbol_unref);
-
- lineno = 1;
- yyin = file;
- yyparse (scanner);
-
- g_hash_table_destroy (const_table);
- const_table = NULL;
-
- yyin = NULL;
-
- return TRUE;
-}
-
-gboolean
-gi_source_scanner_lex_filename (GISourceScanner *scanner, const gchar *filename)
-{
- yyin = fopen (filename, "r");
-
- while (yylex (scanner) != YYEOF)
- ;
-
- fclose (yyin);
-
- return TRUE;
-}