typedef struct expression_list_element_t expression_list_element_t;
typedef struct comma_expression_t comma_expression_t;
typedef struct statement_expression_t statement_expression_t;
-typedef struct member_designator_t member_designator_t;
+typedef struct designator_t designator_t;
typedef struct offsetof_expression_t offsetof_expression_t;
typedef struct va_arg_expression_t va_arg_expression_t;
typedef struct builtin_symbol_expression_t builtin_symbol_expression_t;
+typedef struct initializer_t initializer_t;
typedef struct declaration_t declaration_t;
typedef struct statement_t statement_t;
void ast_set_output(FILE *out);
void print_expression(const expression_t *expression);
+void print_initializer(const initializer_t *initializer);
void print_ast(const translation_unit_t *unit);
void *allocate_ast(size_t size);
expression_t *size_expression;
};
-struct member_designator_t {
- symbol_t *symbol;
- expression_t *array_access;
- member_designator_t *next;
+struct designator_t {
+ symbol_t *symbol;
+ expression_t *array_access;
+ designator_t *next;
};
struct offsetof_expression_t {
- expression_t expression;
- type_t *type;
- member_designator_t *member_designators;
+ expression_t expression;
+ type_t *type;
+ designator_t *designator;
};
struct va_arg_expression_t {
STORAGE_CLASS_ENUM_ENTRY
} storage_class_t;
+typedef enum {
+ INITIALIZER_VALUE,
+ INITIALIZER_LIST,
+} initializer_type_t;
+
+struct initializer_t {
+ initializer_type_t type;
+ designator_t *designator;
+ union {
+ initializer_t *list;
+ expression_t *value;
+ } v;
+ initializer_t *next;
+};
+
struct declaration_t {
storage_class_t storage_class;
type_t *type;
symbol_t *symbol;
statement_t *statement;
- expression_t *initializer;
+ initializer_t *initializer;
source_position_t source_position;
context_t context;
;
}
+static designator_t *parse_designation(void)
+{
+ if(token.type != '[' && token.type != '.')
+ return NULL;
+
+ designator_t *result = NULL;
+ designator_t *last = NULL;
+
+ while(1) {
+ designator_t *designator;
+ switch(token.type) {
+ case '[':
+ designator = allocate_ast_zero(sizeof(designator[0]));
+ next_token();
+ designator->array_access = parse_constant_expression();
+ expect(']');
+ break;
+ case '.':
+ designator = allocate_ast_zero(sizeof(designator[0]));
+ next_token();
+ if(token.type != T_IDENTIFIER) {
+ parse_error_expected("problem while parsing designator",
+ T_IDENTIFIER, 0);
+ return NULL;
+ }
+ designator->symbol = token.v.symbol;
+ next_token();
+ break;
+ default:
+ expect('=');
+ return result;
+ }
+
+ assert(designator != NULL);
+ if(last != NULL) {
+ last->next = designator;
+ } else {
+ result = designator;
+ }
+ last = designator;
+ }
+}
+
+static initializer_t *parse_initializer_list(void);
+
+static initializer_t *parse_initializer(void)
+{
+ designator_t *designator = parse_designation();
+
+ initializer_t *result;
+ if(token.type == '{') {
+ result = parse_initializer_list();
+ } else {
+ result = allocate_ast_zero(sizeof(result[0]));
+ result->type = INITIALIZER_VALUE;
+ result->v.value = parse_assignment_expression();
+ }
+ result->designator = designator;
+
+ return result;
+}
+
+static initializer_t *parse_initializer_list(void)
+{
+ eat('{');
+
+ initializer_t *result = allocate_ast_zero(sizeof(result[0]));
+ result->type = INITIALIZER_LIST;
+
+ initializer_t *last = NULL;
+ while(1) {
+ initializer_t *initializer = parse_initializer();
+ if(last != NULL) {
+ last->next = initializer;
+ } else {
+ result->v.list = initializer;
+ }
+ last = initializer;
+
+ if(token.type == '}')
+ break;
+
+ if(token.type != ',') {
+ parse_error_expected("problem while parsing initializer list",
+ ',', '}', 0);
+ eat_block();
+ return result;
+ }
+ eat(',');
+
+ if(token.type == '}')
+ break;
+ }
+
+ expect('}');
+
+ return result;
+}
+
static compound_type_t *find_compound_type(compound_type_t *types,
const symbol_t *symbol)
{
if(token.type == '=') {
next_token();
- entry->initializer = parse_constant_expression();
+ entry->initializer = parse_initializer();
}
record_declaration(entry);
error();
}
-static void parse_designation(void)
-{
- if(token.type != '[' && token.type != '.')
- return;
-
- while(1) {
- switch(token.type) {
- case '[':
- next_token();
- parse_constant_expression();
- expect_void(']');
- break;
- case '.':
- next_token();
- expect_void(T_IDENTIFIER);
- break;
- default:
- expect_void('=');
- return;
- }
- }
-}
-
-static void parse_initializer_list(void);
-
-static void parse_initializer(void)
-{
- parse_designation();
-
- if(token.type == '{') {
- parse_initializer_list();
- } else {
- parse_assignment_expression();
- }
-}
-
-static void parse_initializer_list(void)
-{
- eat('{');
-
- while(1) {
- parse_initializer();
- if(token.type == '}')
- break;
-
- if(token.type != ',') {
- parse_error_expected("problem while parsing initializer list",
- ',', '}', 0);
- eat_block();
- return;
- }
- eat(',');
-
- if(token.type == '}')
- break;
- }
-
- expect_void('}');
-}
-
static void parse_init_declarators(const declaration_specifiers_t *specifiers)
{
while(true) {
parser_error_multiple_definition(declaration, ndeclaration);
}
- parse_initializer();
+ ndeclaration->initializer = parse_initializer();
} else if(token.type == '{') {
if(declaration->type->type != TYPE_METHOD) {
parser_print_error_prefix();
return (expression_t*) expression;
}
-static member_designator_t *parse_member_designators(void)
+static designator_t *parse_designator(void)
{
- member_designator_t *result = allocate_ast_zero(sizeof(result[0]));
+ designator_t *result = allocate_ast_zero(sizeof(result[0]));
if(token.type != T_IDENTIFIER) {
parse_error_expected("problem while parsing member designator",
result->symbol = token.v.symbol;
next_token();
- member_designator_t *last_designator = result;
+ designator_t *last_designator = result;
while(true) {
if(token.type == '.') {
next_token();
eat_brace();
return NULL;
}
- member_designator_t *designator
- = allocate_ast_zero(sizeof(result[0]));
- designator->symbol = token.v.symbol;
+ designator_t *designator = allocate_ast_zero(sizeof(result[0]));
+ designator->symbol = token.v.symbol;
next_token();
last_designator->next = designator;
}
if(token.type == '[') {
next_token();
- member_designator_t *designator
- = allocate_ast_zero(sizeof(result[0]));
+ designator_t *designator = allocate_ast_zero(sizeof(result[0]));
designator->array_access = parse_expression();
if(designator->array_access == NULL) {
eat_brace();
expect('(');
expression->type = parse_typename();
expect(',');
- expression->member_designators = parse_member_designators();
+ expression->designator = parse_designator();
expect(')');
return (expression_t*) expression;