From 6c4c881adf19cd06b778924d5bcee62d022d3865 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Thu, 13 Mar 2008 15:59:46 +0000 Subject: [PATCH] Now parsing structs and unions --- src/parser.c | 104 +++++++++++++++++++++++++- src/sets/specifier_qualifier_list.set | 2 + src/sets/struct_declaration.set | 1 + src/tokenset.c | 10 +++ src/tokenset.h | 1 + 5 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/sets/specifier_qualifier_list.set create mode 100644 src/sets/struct_declaration.set diff --git a/src/parser.c b/src/parser.c index 1b5ef31..53d8ddd 100644 --- a/src/parser.c +++ b/src/parser.c @@ -41,6 +41,11 @@ static int _declaration_specifiers(C99 * c99); static int _storage_class_specifier(C99 * c99); static int _type_specifier(C99 * c99); static int _struct_or_union_specifier(C99 * c99); +static int _struct_or_union(C99 * c99); +static int _struct_declaration_list(C99 * c99); +static int _struct_declaration(C99 * c99); +static int _struct_declarator_list(C99 * c99); +static int _struct_declarator(C99 * c99); static int _enum_specifier(C99 * c99); static int _enumerator_list(C99 * c99); static int _enumerator(C99 * c99); @@ -285,14 +290,107 @@ static int _type_specifier(C99 * c99) /* struct-or-union-specifier */ static int _struct_or_union_specifier(C99 * c99) + /* struct-or-union [ identifier ] "{" struct-declaration-list "}" + * | struct-or-union identifier */ +{ + int ret; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__); +#endif + ret = _struct_or_union(c99); + if(token_get_code(c99->token) == C99_CODE_IDENTIFIER) + { + ret |= _identifier(c99); + if(token_get_code(c99->token) != C99_CODE_OPERATOR_LBRACE) + return ret; + } + ret |= _parse_check(c99, C99_CODE_OPERATOR_LBRACE); + ret |= _struct_declaration_list(c99); + if(token_get_code(c99->token) == C99_CODE_COMMA) + ret |= c99_scan(c99); + ret |= _parse_check(c99, C99_CODE_OPERATOR_RBRACE); + return ret; +} + + +/* struct-or-union */ +static int _struct_or_union(C99 * c99) + /* "struct" | "union" */ { - /* FIXME implement */ #ifdef DEBUG fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, token_get_string(c99->token)); #endif - c99_scan(c99); - return 0; + return c99_scan(c99); +} + + +/* struct-declaration-list */ +static int _struct_declaration_list(C99 * c99) + /* struct-declaration { struct-declaration } */ +{ + int ret; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__); +#endif + ret = _struct_declaration(c99); + while(token_in_set(c99->token, c99set_struct_declaration)) + ret |= _struct_declaration(c99); + return ret; +} + + +/* struct-declaration */ +static int _struct_declaration(C99 * c99) + /* specifier-qualifier-list struct-declarator-list ";" */ +{ + int ret; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__); +#endif + ret = _specifier_qualifier_list(c99); + ret |= _struct_declarator_list(c99); + return ret; +} + + +/* struct-declarator-list */ +static int _struct_declarator_list(C99 * c99) + /* struct-declarator { "," struct-declarator } */ +{ + int ret; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__); +#endif + ret = _struct_declarator(c99); + while(token_get_code(c99->token) == C99_CODE_COMMA) + ret |= _struct_declarator(c99); + return ret; +} + + +/* struct-declarator */ +static int _struct_declarator(C99 * c99) + /* declarator + * [ declarator ] : constant-expr */ +{ + int ret; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__); +#endif + if(token_get_code(c99->token) == C99_CODE_OPERATOR_COLON) + { + ret |= c99_scan(c99); + ret |= _constant_expr(c99); + } + else + ret = _declarator(c99); + return ret; } diff --git a/src/sets/specifier_qualifier_list.set b/src/sets/specifier_qualifier_list.set new file mode 100644 index 0000000..d022958 --- /dev/null +++ b/src/sets/specifier_qualifier_list.set @@ -0,0 +1,2 @@ +#include "type_specifier.set" +#include "type_qualifier.set" diff --git a/src/sets/struct_declaration.set b/src/sets/struct_declaration.set new file mode 100644 index 0000000..dd6070e --- /dev/null +++ b/src/sets/struct_declaration.set @@ -0,0 +1 @@ +#include "specifier_qualifier_list.set" diff --git a/src/tokenset.c b/src/tokenset.c index bb28c18..e4465b0 100644 --- a/src/tokenset.c +++ b/src/tokenset.c @@ -322,6 +322,16 @@ static TokenCode _c99set_storage_class_specifier[] = TokenSet c99set_storage_class_specifier = _c99set_storage_class_specifier; +/* struct-declaration */ +static TokenCode _c99set_struct_declaration[] = +{ +#include "sets/struct_declaration.set" + C99_CODE_NULL +}; + +TokenSet c99set_struct_declaration = _c99set_struct_declaration; + + /* struct-or-union-specifier */ static TokenCode _c99set_struct_or_union_specifier[] = { diff --git a/src/tokenset.h b/src/tokenset.h index ca51e92..e7f87b4 100644 --- a/src/tokenset.h +++ b/src/tokenset.h @@ -53,6 +53,7 @@ extern TokenSet c99set_punctuator; extern TokenSet c99set_selection_statement; extern TokenSet c99set_statement; extern TokenSet c99set_storage_class_specifier; +extern TokenSet c99set_struct_declaration; extern TokenSet c99set_struct_or_union_specifier; extern TokenSet c99set_type_qualifier; extern TokenSet c99set_type_qualifier_list;