From e9d8459e65f896a8ca91368e93744ed988b7f956 Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Sat, 11 Jul 2020 16:47:16 +0900 Subject: [PATCH] parser: Implement parsing of unary expressions --- src/parser.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++----- src/parser.h | 4 +- 2 files changed, 105 insertions(+), 12 deletions(-) diff --git a/src/parser.c b/src/parser.c index 6e6a93b..1743595 100644 --- a/src/parser.c +++ b/src/parser.c @@ -62,12 +62,7 @@ struct storage_class_specifier *parse_storage_class_specifier(void) return(ret_val); } -struct struct_specifier *parse_struct_specifier(void) -{ - return(NULL); -} - -struct union_specifier *parse_union_specifier(void) +struct struct_union_specifier *parse_struct_union_specifier(void) { return(NULL); } @@ -112,13 +107,13 @@ struct type_specifier *parse_type_specifier(void) case TOKEN_STRUCT: ret_val->type = TYPE_SPECIFIER_STRUCT; lex_setpos(pos); - ret_val->data.ss = parse_struct_specifier(); + ret_val->data.su = parse_struct_union_specifier(); break; case TOKEN_UNION: ret_val->type = TYPE_SPECIFIER_UNION; lex_setpos(pos); - ret_val->data.us = parse_union_specifier(); + ret_val->data.su = parse_struct_union_specifier(); break; case TOKEN_ENUM: @@ -136,7 +131,7 @@ struct type_specifier *parse_type_specifier(void) switch(ret_val->type) { case TYPE_SPECIFIER_STRUCT: - if(!ret_val->data.ss) { + if(!ret_val->data.su) { /* syntax error */ #if 0 fprintf(stderr, @@ -148,7 +143,7 @@ struct type_specifier *parse_type_specifier(void) break; case TYPE_SPECIFIER_UNION: - if(!ret_val->data.us) { + if(!ret_val->data.su) { /* syntax error */ #if 0 fprintf(stderr, @@ -657,6 +652,99 @@ struct assignment_expression *parse_assignment_expression(void) struct unary_expression *parse_unary_expression(void) { + struct unary_expression *expr; + int pos; + + expr = unary_expression_new(); + + if(!expr) { + return(NULL); + } + + if((expr->data.postfix = parse_postfix_expression())) { + expr->type = UNARY_EXPR_POSTFIX; + return(expr); + } + + pos = lex_getpos(); + + expr->data.prefix.prefix = lex_gettoken(); + expr->data.prefix.uexpr = parse_unary_expression(); + + if(expr->data.prefix.prefix && expr->data.prefix.uexpr && + (expr->data.prefix.prefix->type == TOKEN_INC || expr->data.prefix.prefix->type == TOKEN_DEC)) { + expr->type = UNARY_EXPR_PREFIX; + return(expr); + } + + expr->data.prefix.prefix = NULL; + + if(expr->data.prefix.uexpr) { + unary_expression_free(expr->data.prefix.uexpr); + expr->data.prefix.uexpr = NULL; + } + + lex_setpos(pos); + + expr->data.cast.op = lex_gettoken(); + expr->data.cast.castexpr = parse_cast_expression(); + + if(expr->data.cast.op && expr->data.cast.castexpr && (expr->data.cast.op->type == TOKEN_AND || + expr->data.cast.op->type == TOKEN_MUL || + expr->data.cast.op->type == TOKEN_ADD || + expr->data.cast.op->type == TOKEN_SUB || + expr->data.cast.op->type == TOKEN_COMPLEMENT || + expr->data.cast.op->type == TOKEN_NOT)) { + expr->type = UNARY_EXPR_CAST; + return(expr); + } + + if(expr->data.cast.castexpr) { + cast_expression_free(expr->data.cast.castexpr); + expr->data.cast.castexpr = NULL; + } + + expr->data.cast.op = NULL; + lex_setpos(pos); + + expr->data.sizeof_unary.op = lex_gettoken(); + expr->data.sizeof_unary.uexpr = parse_unary_expression(); + + if(expr->data.sizeof_unary.op && expr->data.sizeof_unary.uexpr && + token_cmp(expr->data.sizeof_unary.op, "sizeof") == 0) { + expr->type = UNARY_EXPR_SIZEOF_UNARY; + return(expr); + } + + if(expr->data.sizeof_unary.uexpr) { + unary_expression_free(expr->data.sizeof_unary.uexpr); + expr->data.sizeof_unary.uexpr = NULL; + } + expr->data.sizeof_unary.op = NULL; + + lex_setpos(pos); + + expr->data.sizeof_type.op = lex_gettoken(); + expr->data.sizeof_type.lparen = lex_gettoken(); + expr->data.sizeof_type.typename = parse_type_name(); + expr->data.sizeof_type.rparen = lex_gettoken(); + + if(expr->data.sizeof_type.op && expr->data.sizeof_type.lparen && + expr->data.sizeof_type.typename && expr->data.sizeof_type.rparen && + (token_cmp(expr->data.sizeof_type.op, "sizeof") == 0 && + expr->data.sizeof_type.lparen->type == TOKEN_LPAREN && + expr->data.sizeof_type.rparen->type == TOKEN_RPAREN)) { + expr->type = UNARY_EXPR_SIZEOF_TYPE; + return(expr); + } + + if(expr->data.sizeof_type.typename) { + type_name_free(expr->data.sizeof_type.typename); + } + + lex_setpos(pos); + unary_expression_free(expr); + return(NULL); } @@ -1062,3 +1150,8 @@ struct multiplicative_expression *parse_multiplicative_expression(void) return(NULL); } + +struct postfix_expression *parse_postfix_expression(void) +{ + return(NULL); +} diff --git a/src/parser.h b/src/parser.h index 4a0e806..f1d51ef 100644 --- a/src/parser.h +++ b/src/parser.h @@ -22,6 +22,7 @@ struct shift_expression *parse_shift_expression(void); struct additive_expression *parse_additive_expression(void); struct multiplicative_expression *parse_multiplicative_expression(void); struct cast_expression *parse_cast_expression(void); +struct postfix_expression *parse_postfix_expression(void); struct unary_expression *parse_unary_expression(void); struct conditional_expression *parse_conditional_expression(void); @@ -30,8 +31,7 @@ struct expression *parse_expression(void); struct primary_expression *parse_primary_expression(void); struct type_qualifier *parse_type_qualifier(void); struct storage_class_specifier *parse_storage_class_specifier(void); -struct struct_specifier *parse_struct_specifier(void); /* TODO */ -struct union_specifier *parse_union_specifier(void); /* TODO */ +struct struct_union_specifier *parse_struct_union_specifier(void); struct enum_specifier *parse_enum_specifier(void); /* TODO */ struct typedef_name *parse_typedef_name(void); /* TODO */ struct type_specifier *parse_type_specifier(void); -- 2.47.3