]> git.corax.cc Git - ccc/commitdiff
parser: Implement parsing of unary expressions
authorMatthias Kruk <m@m10k.eu>
Sat, 11 Jul 2020 07:47:16 +0000 (16:47 +0900)
committerMatthias Kruk <m@m10k.eu>
Sat, 11 Jul 2020 07:47:16 +0000 (16:47 +0900)
src/parser.c
src/parser.h

index 6e6a93b5f9b0a8305fb6e72d1a689f4671517892..1743595525413e94440ac197e5fcbc2302900fb5 100644 (file)
@@ -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);
+}
index 4a0e8063f6d51b3784daff553c700f9c55a968bf..f1d51ef4827bac37c9346a89fefb2279769e4ebc 100644 (file)
@@ -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);