X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=inline;f=parser.c;h=278c524526c39eea108a77a4206d93f8dac595b6;hb=d1d999b6563a06706be2500a02217986c54ec13f;hp=66d44c2055a795e701fcd3e03ac33fe37bf2478e;hpb=557d5a86be9428156b887e4494e574de2d9400ac;p=cparser diff --git a/parser.c b/parser.c index 66d44c2..278c524 100644 --- a/parser.c +++ b/parser.c @@ -14,6 +14,7 @@ #include "adt/array.h" //#define PRINT_TOKENS +//#define ABORT_ON_ERROR #define MAX_LOOKAHEAD 2 struct environment_entry_t { @@ -87,7 +88,7 @@ static inline const token_t *la(int num) { assert(num > 0 && num <= MAX_LOOKAHEAD); - int pos = (num-1) % MAX_LOOKAHEAD; + int pos = (lookahead_bufpos+num-1) % MAX_LOOKAHEAD; return & lookahead_buffer[pos]; } @@ -104,6 +105,9 @@ void parser_print_error_prefix_pos(const source_position_t source_position) fputc(':', stderr); fprintf(stderr, "%d", source_position.linenr); fputs(": error: ", stderr); +#ifdef ABORT_ON_ERROR + abort(); +#endif } void parser_print_error_prefix(void) @@ -351,35 +355,48 @@ static type_t *parse_union_specifier(void) return (type_t*) union_type; } -static void parse_enum_type_entries(void) +static enum_entry_t *parse_enum_type_entries(void) { eat('{'); if(token.type == '}') { next_token(); parse_error("empty enum not allowed"); - return; + return NULL; } + enum_entry_t *result = NULL; + enum_entry_t *last_entry = NULL; do { + enum_entry_t *entry = allocate_ast_zero(sizeof(entry[0])); if(token.type != T_IDENTIFIER) { parse_error_expected("problem while parsing enum entry", T_IDENTIFIER, 0); eat_until('}'); - return; + return result; } + entry->symbol = token.v.symbol; next_token(); if(token.type == '=') { - parse_constant_expression(); + next_token(); + entry->value = parse_constant_expression(); } + if(last_entry != NULL) { + last_entry->next = entry; + } else { + result = entry; + } + last_entry = entry; + if(token.type != ',') break; next_token(); } while(token.type != '}'); - expect_void('}'); + expect('}'); + return result; } static type_t *parse_enum_specifier(void) @@ -394,10 +411,10 @@ static type_t *parse_enum_specifier(void) enum_type->symbol = token.v.symbol; next_token(); if(token.type == '{') { - parse_enum_type_entries(); + enum_type->entries = parse_enum_type_entries(); } } else if(token.type == '{') { - parse_enum_type_entries(); + enum_type->entries = parse_enum_type_entries(); } else { parse_error_expected("problem while parsing enum type specifiers", T_IDENTIFIER, '{'); @@ -406,6 +423,72 @@ static type_t *parse_enum_specifier(void) return (type_t*) enum_type; } +static +const char *parse_string_literals(void) +{ + assert(token.type == T_STRING_LITERAL); + const char *result = token.v.string; + + next_token(); + + while(token.type == T_STRING_LITERAL) { + result = concat_strings(result, token.v.string); + next_token(); + } + + return result; +} + +static +void parse_attributes(void) +{ + while(1) { + switch(token.type) { + case T___attribute__: + next_token(); + + expect_void('('); + int depth = 1; + while(depth > 0) { + switch(token.type) { + case T_EOF: + parse_error("EOF while parsing attribute"); + break; + case '(': + next_token(); + depth++; + break; + case ')': + next_token(); + depth--; + break; + default: + next_token(); + } + } + break; + case T_asm: + next_token(); + expect_void('('); + if(token.type != T_STRING_LITERAL) { + parse_error_expected("while parsing assembler attribute", + T_STRING_LITERAL); + eat_until(')'); + break; + } else { + parse_string_literals(); + } + expect_void(')'); + break; + default: + goto attributes_finished; + } + } + +attributes_finished: + ; +} + typedef enum { SPECIFIER_SIGNED = 1 << 0, SPECIFIER_UNSIGNED = 1 << 1, @@ -589,6 +672,11 @@ void parse_declaration_specifiers(declaration_specifiers_t *specifiers) next_token(); break; + case T___attribute__: + /* TODO */ + parse_attributes(); + break; + case T_IDENTIFIER: declaration = token.v.symbol->declaration; if(declaration == NULL || @@ -860,7 +948,7 @@ void parse_parameters(method_type_t *type) return; } - declaration_t *declaration; + declaration_t *declaration; method_parameter_type_t *parameter_type; method_parameter_type_t *last_parameter_type = NULL; @@ -896,34 +984,6 @@ void parse_parameters(method_type_t *type) } } -static -void parse_attributes(void) -{ - while(token.type == T___attribute__) { - next_token(); - - expect_void('('); - int depth = 1; - while(depth > 0) { - switch(token.type) { - case T_EOF: - parse_error("EOF while parsing attribute"); - break; - case '(': - next_token(); - depth++; - break; - case ')': - next_token(); - depth--; - break; - default: - next_token(); - } - } - } -} - typedef struct declarator_part declarator_part; struct declarator_part { parsed_pointer_t *pointers; @@ -941,6 +1001,9 @@ declarator_part *parse_inner_declarator(declaration_t *declaration, part->pointers = parse_pointers(); + /* TODO: find out if this is correct */ + parse_attributes(); + switch(token.type) { case T_IDENTIFIER: if(declaration == NULL) { @@ -1226,9 +1289,7 @@ expression_t *parse_string_const(void) string_literal_t *cnst = allocate_ast_zero(sizeof(cnst[0])); cnst->expression.type = EXPR_STRING_LITERAL; - cnst->value = token.v.string; - - next_token(); + cnst->value = parse_string_literals(); return (expression_t*) cnst; } @@ -1259,11 +1320,44 @@ expression_t *parse_reference(void) return (expression_t*) ref; } +static +expression_t *parse_cast(void) +{ + unary_expression_t *cast = allocate_ast_zero(sizeof(cast[0])); + + cast->expression.type = EXPR_UNARY; + cast->type = UNEXPR_CAST; + cast->expression.source_position = token.source_position; + + type_t *type = parse_typename(); + + expect(')'); + expression_t *value = parse_sub_expression(20); + + cast->expression.datatype = type; + cast->value = value; + + return (expression_t*) cast; +} + static expression_t *parse_brace_expression(void) { eat('('); + declaration_t *declaration; + switch(token.type) { + TYPE_QUALIFIERS + TYPE_SPECIFIERS + return parse_cast(); + case T_IDENTIFIER: + declaration = token.v.symbol->declaration; + if(declaration != NULL && + (declaration->storage_class & STORAGE_CLASS_TYPEDEF)) { + return parse_cast(); + } + } + expression_t *result = parse_expression(); expect(')'); @@ -1898,7 +1992,7 @@ statement_t *parse_compound_statement(void) statement_t *last_statement = NULL; - while(token.type != '}') { + while(token.type != '}' && token.type != T_EOF) { statement_t *statement = parse_statement(); if(last_statement != NULL) {