]> git.corax.cc Git - ccc/commitdiff
parser: Implement parsing of direct-abstract-declarators, parameter-type-lists, param...
authorMatthias Kruk <m@m10k.eu>
Sun, 12 Jul 2020 10:01:35 +0000 (19:01 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 12 Jul 2020 10:01:35 +0000 (19:01 +0900)
src/grammar.c
src/grammar.h
src/parser.c
src/parser.h

index d092852a99df05647af070ba8a24e2334e8d3f9d..70590c6049702aceb11c01b370e69241770d3559 100644 (file)
@@ -54,6 +54,14 @@ struct storage_class_specifier *storage_class_specifier_new(struct token *tok)
         return(sp);
 }
 
+void storage_class_specifier_free(struct storage_class_specifier *spec)
+{
+       memset(spec, 0, sizeof(*spec));
+       free(spec);
+
+       return;
+}
+
 struct type_specifier *type_specifier_new(void)
 {
         struct type_specifier *ts;
@@ -107,6 +115,40 @@ struct declaration_specifiers *declaration_specifiers_new(void)
        return(ds);
 }
 
+void declaration_specifiers_free(struct declaration_specifiers *specs)
+{
+       switch(specs->type) {
+       case DECL_SPEC_STORAGE_CLASS:
+               if(specs->data.scspec) {
+                       storage_class_specifier_free(specs->data.scspec);
+               }
+
+               break;
+
+       case DECL_SPEC_TYPE_SPEC:
+               if(specs->data.tspec) {
+                       type_specifier_free(specs->data.tspec);
+               }
+
+               break;
+
+       case DECL_SPEC_TYPE_QUALIFIER:
+               if(specs->data.tqual) {
+                       type_qualifier_free(specs->data.tqual);
+               }
+
+               break;
+
+       default:
+               break;
+       }
+
+       memset(specs, 0, sizeof(*specs));
+       free(specs);
+
+       return;
+}
+
 int storage_class_specifier_to_string(struct storage_class_specifier *scspec, char *dst, size_t n)
 {
        int ret_val;
@@ -1397,7 +1439,43 @@ struct direct_abstract_declarator *direct_abstract_declarator_new(void)
 
 void direct_abstract_declarator_free(struct direct_abstract_declarator *decl)
 {
-       fprintf(stderr, "FIXME: %s() not implemented\n", __func__);
+       switch(decl->type) {
+       case DIRECT_ABSTRACT_DECL_ABS:
+               if(decl->data.abs.decl) {
+                       abstract_declarator_free(decl->data.abs.decl);
+               }
+
+               break;
+
+       case DIRECT_ABSTRACT_DECL_CNST:
+               if(decl->data.cnst.next) {
+                       direct_abstract_declarator_free(decl->data.cnst.next);
+               }
+
+               if(decl->data.cnst.cexpr) {
+                       constant_expression_free(decl->data.cnst.cexpr);
+               }
+
+               break;
+
+       case DIRECT_ABSTRACT_DECL_PARAM:
+               if(decl->data.param.next) {
+                       direct_abstract_declarator_free(decl->data.param.next);
+               }
+
+               if(decl->data.param.params) {
+                       parameter_type_list_free(decl->data.param.params);
+               }
+
+               break;
+
+       default:
+               break;
+       }
+
+       memset(decl, 0, sizeof(*decl));
+       free(decl);
+
        return;
 }
 
@@ -1445,6 +1523,14 @@ struct pointer *pointer_new(void)
 
 void pointer_free(struct pointer *ptr)
 {
+       if(ptr->ptr) {
+               pointer_free(ptr->ptr);
+       }
+
+       if(ptr->tqual) {
+               type_qualifier_list_free(ptr->tqual);
+       }
+
        memset(ptr, 0, sizeof(*ptr));
        free(ptr);
 }
@@ -1514,6 +1600,14 @@ struct declarator *declarator_new(void)
 
 void declarator_free(struct declarator *decl)
 {
+       if(decl->ptr) {
+               pointer_free(decl->ptr);
+       }
+
+       if(decl->ddecl) {
+               direct_declarator_free(decl->ddecl);
+       }
+
        memset(decl, 0, sizeof(*decl));
        free(decl);
 
@@ -1577,3 +1671,189 @@ void enumerator_free(struct enumerator *en)
 
        return;
 }
+
+struct type_qualifier_list *type_qualifier_list_new(void)
+{
+       struct type_qualifier_list *list;
+
+       list = malloc(sizeof(*list));
+
+       if(list) {
+               memset(list, 0, sizeof(*list));
+       }
+
+       return(list);
+}
+
+void type_qualifier_list_free(struct type_qualifier_list *list)
+{
+       if(list->tqual) {
+               type_qualifier_free(list->tqual);
+       }
+
+       if(list->next) {
+               type_qualifier_list_free(list->next);
+       }
+
+       memset(list, 0, sizeof(*list));
+       free(list);
+
+       return;
+}
+
+struct parameter_type_list *parameter_type_list_new(void)
+{
+       struct parameter_type_list *list;
+
+       list = malloc(sizeof(*list));
+
+       if(list) {
+               memset(list, 0, sizeof(*list));
+       }
+
+       return(list);
+}
+
+void parameter_type_list_free(struct parameter_type_list *list)
+{
+       if(list->params) {
+               parameter_list_free(list->params);
+       }
+
+       memset(list, 0, sizeof(*list));
+       free(list);
+
+       return;
+}
+
+struct parameter_list *parameter_list_new(void)
+{
+       struct parameter_list *list;
+
+       list = malloc(sizeof(*list));
+
+       if(list) {
+               memset(list, 0, sizeof(*list));
+       }
+
+       return(list);
+}
+
+void parameter_list_free(struct parameter_list *list)
+{
+       if(list->decl) {
+               parameter_declaration_free(list->decl);
+       }
+
+       if(list->next) {
+               parameter_list_free(list->next);
+       }
+
+       memset(list, 0, sizeof(*list));
+       free(list);
+
+       return;
+}
+
+struct parameter_declaration *parameter_declaration_new(void)
+{
+       struct parameter_declaration *decl;
+
+       decl = malloc(sizeof(*decl));
+
+       if(decl) {
+               memset(decl, 0, sizeof(*decl));
+       }
+
+       return(decl);
+}
+
+void parameter_declaration_free(struct parameter_declaration *decl)
+{
+       if(decl->specs) {
+               declaration_specifiers_free(decl->specs);
+       }
+
+       if(decl->decl) {
+               declarator_free(decl->decl);
+       }
+
+       if(decl->adecl) {
+               abstract_declarator_free(decl->adecl);
+       }
+
+       memset(decl, 0, sizeof(*decl));
+       free(decl);
+
+       return;
+}
+
+struct direct_declarator *direct_declarator_new(void)
+{
+       struct direct_declarator *decl;
+
+       decl = malloc(sizeof(*decl));
+
+       if(decl) {
+               memset(decl, 0, sizeof(*decl));
+       }
+
+       return(decl);
+}
+
+void direct_declarator_free(struct direct_declarator *decl)
+{
+       if(decl->identifier) {
+               identifier_free(decl->identifier);
+       }
+
+       if(decl->decl) {
+               declarator_free(decl->decl);
+       }
+
+       if(decl->cexpr) {
+               constant_expression_free(decl->cexpr);
+       }
+
+       if(decl->params) {
+               parameter_type_list_free(decl->params);
+       }
+
+       if(decl->ids) {
+               identifier_list_free(decl->ids);
+       }
+
+       memset(decl, 0, sizeof(*decl));
+       free(decl);
+
+       return;
+}
+
+struct identifier_list *identifier_list_new(void)
+{
+       struct identifier_list *list;
+
+       list = malloc(sizeof(*list));
+
+       if(list) {
+               memset(list, 0, sizeof(*list));
+       }
+
+       return(list);
+}
+
+void identifier_list_free(struct identifier_list *list)
+{
+       if(list->identifier) {
+               identifier_free(list->identifier);
+       }
+
+       if(list->next) {
+               identifier_list_free(list->next);
+       }
+
+       memset(list, 0, sizeof(*list));
+       free(list);
+
+       return;
+}
index dbb7723b3cbb39766342aa48e29d7d0ed031c768..1ba60c171d2d47d5d7bc1b731fadd0c8f90a81e8 100644 (file)
@@ -89,11 +89,60 @@ enum unary_expression_type {
 };
 
 struct pointer {
+       struct token *op;
+       struct type_qualifier_list *tqual;
+       struct pointer *ptr;
+};
+
+enum direct_abstract_declarator_type {
+       DIRECT_ABSTRACT_DECL_INVALID,
+       DIRECT_ABSTRACT_DECL_ABS,
+       DIRECT_ABSTRACT_DECL_CNST,
+       DIRECT_ABSTRACT_DECL_PARAM
+};
 
+struct parameter_declaration {
+       struct declaration_specifiers *specs;
+       struct declarator *decl;
+       struct abstract_declarator *adecl;
+};
+
+struct parameter_list {
+       struct parameter_declaration *decl;
+       struct token *comma;
+       struct parameter_list *next;
+};
+
+struct parameter_type_list {
+       struct parameter_list *params;
+       struct token *comma;
+       struct token *dots;
 };
 
 struct direct_abstract_declarator {
+       enum direct_abstract_declarator_type type;
 
+       union {
+               struct {
+                       struct token *lparen;
+                       struct abstract_declarator *decl;
+                       struct token *rparen;
+               } abs;
+
+               struct {
+                       struct direct_abstract_declarator *next;
+                       struct token *lbracket;
+                       struct constant_expression *cexpr;
+                       struct token *rbracket;
+               } cnst;
+
+               struct {
+                       struct direct_abstract_declarator *next;
+                       struct token *lparen;
+                       struct parameter_type_list *params;
+                       struct token *rparen;
+               } param;
+       } data;
 };
 
 struct abstract_declarator {
@@ -304,6 +353,11 @@ struct type_qualifier {
         struct token *token;
 };
 
+struct type_qualifier_list {
+       struct type_qualifier *tqual;
+       struct type_qualifier_list *next;
+};
+
 struct storage_class_specifier {
         struct token *token;
 };
@@ -402,8 +456,26 @@ struct declaration_specifiers {
        struct declaration_specifiers *next;
 };
 
-struct declarator {
+struct identifier_list {
+       struct identifier *identifier;
+       struct token *comma;
+       struct identifier_list *next;
+};
 
+struct direct_declarator {
+       struct identifier *identifier;
+       struct declarator *decl;
+       struct direct_declarator *ddecl;
+       struct constant_expression *cexpr;
+       struct parameter_type_list *params;
+       struct identifier_list *ids;
+       struct token *ltok;
+       struct token *rtok;
+};
+
+struct declarator {
+       struct pointer *ptr;
+       struct direct_declarator *ddecl;
 };
 
 struct declaration_list {
@@ -461,6 +533,7 @@ void type_qualifier_free(struct type_qualifier*);
 int type_qualifier_to_string(struct type_qualifier*, char*, size_t);
 
 struct storage_class_specifier *storage_class_specifier_new(struct token*);
+void storage_class_specifier_free(struct storage_class_specifier*);
 struct translation_unit *translation_unit_new(struct external_declaration*);
 struct external_declaration *external_declaration_new(void);
 
@@ -566,6 +639,9 @@ void struct_declaration_free(struct struct_declaration*);
 struct struct_declaration_list *struct_declaration_list_new(void);
 void struct_declaration_list_free(struct struct_declaration_list*);
 
+struct direct_declarator *direct_declarator_new(void);
+void direct_declarator_free(struct direct_declarator*);
+
 struct declarator *declarator_new(void);
 void declarator_free(struct declarator*);
 
@@ -578,4 +654,19 @@ void enumerator_list_free(struct enumerator_list*);
 struct expression *expression_new(void);
 void expression_free(struct expression*);
 
+struct type_qualifier_list *type_qualifier_list_new(void);
+void type_qualifier_list_free(struct type_qualifier_list*);
+
+struct parameter_type_list *parameter_type_list_new(void);
+void parameter_type_list_free(struct parameter_type_list*);
+
+struct parameter_list *parameter_list_new(void);
+void parameter_list_free(struct parameter_list*);
+
+struct parameter_declaration *parameter_declaration_new(void);
+void parameter_declaration_free(struct parameter_declaration*);
+
+struct identifier_list *identifier_list_new(void);
+void identifier_list_free(struct identifier_list*);
+
 #endif /* GRAMMAR_H */
index 0859d4a2271c1ee7cc032f54a99e4d9092f3f51a..c7e82bea51af162b8d95037aa7d059c6f28c718b 100644 (file)
@@ -295,12 +295,132 @@ struct compound_statement *parse_compound_statement(void)
        return(NULL);
 }
 
-struct declarator *parse_declarator(void)
+struct direct_declarator *parse_direct_declarator(void)
 {
-       fprintf(stderr, "FIXME: %s() is not implemented\n", __func__);
+       struct direct_declarator *decl;
+       int pos;
+
+       decl = direct_declarator_new();
+
+       if(!decl) {
+               return(NULL);
+       }
+
+       if((decl->identifier = parse_identifier())) {
+               return(decl);
+       }
+
+       pos = lex_getpos();
+
+       decl->ltok = lex_gettoken();
+       decl->decl = parse_declarator();
+       decl->rtok = lex_gettoken();
+
+       if(decl->ltok && decl->decl && decl->rtok &&
+          decl->ltok->type == TOKEN_LPAREN && decl->rtok->type == TOKEN_RPAREN) {
+               return(decl);
+       } else {
+               decl->ltok = NULL;
+               decl->rtok = NULL;
+
+               if(decl->decl) {
+                       declarator_free(decl->decl);
+                       decl->decl = NULL;
+               }
+
+               lex_setpos(pos);
+       }
+
+       decl->ddecl = parse_direct_declarator();
+       decl->ltok = lex_gettoken();
+       decl->cexpr = parse_constant_expression();
+       decl->rtok = lex_gettoken();
+
+       if(decl->ddecl && decl->ltok && decl->rtok && decl->ltok->type == TOKEN_LBRACKET &&
+          decl->rtok->type == TOKEN_RBRACKET) {
+               return(decl);
+       } else {
+               if(decl->ddecl) {
+                       direct_declarator_free(decl->ddecl);
+                       decl->ddecl = NULL;
+               }
+
+               if(decl->cexpr) {
+                       constant_expression_free(decl->cexpr);
+                       decl->cexpr = NULL;
+               }
+
+               decl->ltok = NULL;
+               decl->rtok = NULL;
+
+               lex_setpos(pos);
+       }
+
+       decl->ddecl = parse_direct_declarator();
+       decl->ltok = lex_gettoken();
+       decl->params = parse_parameter_type_list();
+       decl->rtok = lex_gettoken();
+
+       if(decl->ddecl && decl->ltok && decl->params && decl->rtok &&
+          decl->ltok->type == TOKEN_LPAREN && decl->rtok->type == TOKEN_RPAREN) {
+               return(decl);
+       } else {
+               if(decl->ddecl) {
+                       direct_declarator_free(decl->ddecl);
+                       decl->ddecl = NULL;
+               }
+
+               if(decl->params) {
+                       parameter_type_list_free(decl->params);
+                       decl->params = NULL;
+               }
+
+               decl->ltok = NULL;
+               decl->rtok = NULL;
+
+               lex_setpos(pos);
+       }
+
+       decl->ddecl = parse_direct_declarator();
+       decl->ltok = lex_gettoken();
+       decl->ids = parse_identifier_list();
+       decl->rtok = lex_gettoken();
+
+       if(decl->ddecl && decl->ltok && decl->rtok &&
+          decl->ltok->type == TOKEN_LPAREN &&
+          decl->rtok->type == TOKEN_RPAREN) {
+               return(decl);
+       }
+
+       direct_declarator_free(decl);
+       lex_setpos(pos);
+
        return(NULL);
 }
 
+struct declarator *parse_declarator(void)
+{
+       struct declarator *decl;
+       int pos;
+
+       decl = declarator_new();
+       pos = lex_getpos();
+
+       if(decl) {
+               decl->ptr = parse_pointer();
+               decl->ddecl = parse_direct_declarator();
+
+               if(!decl->ddecl) {
+                       lex_setpos(pos);
+
+                       declarator_free(decl);
+                       decl = NULL;
+               }
+       }
+
+       return(decl);
+}
+
 struct declaration *parse_declaration(void)
 {
        fprintf(stderr, "FIXME: %s() is not implemented\n", __func__);
@@ -911,6 +1031,37 @@ struct abstract_declarator *parse_abstract_declarator(void)
        return(decl);
 }
 
+struct pointer *parse_pointer(void)
+{
+       struct pointer *ptr;
+       int pos;
+
+       ptr = pointer_new();
+
+       /*
+        * pointer:
+        *     * type-qualifier-list_opt
+        *     * type-qualifier-list_opt pointer
+        */
+
+       if(ptr) {
+               pos = lex_getpos();
+
+               ptr->op = lex_gettoken();
+               ptr->tqual = parse_type_qualifier_list();
+               ptr->ptr = parse_pointer();
+
+               if(!ptr->op || ptr->op->type != TOKEN_MUL) {
+                       pointer_free(ptr);
+                       lex_setpos(pos);
+
+                       ptr = NULL;
+               }
+       }
+
+       return(ptr);
+}
+
 struct logical_or_expression *parse_logical_or_expression(void)
 {
        struct logical_or_expression *expr;
@@ -1399,3 +1550,257 @@ struct specifier_qualifier_list *parse_specifier_qualifier_list(void)
 
        return(sql);
 }
+
+struct type_qualifier_list *parse_type_qualifier_list(void)
+{
+       struct type_qualifier_list *list;
+       int pos;
+
+       list = type_qualifier_list_new();
+
+       if(!list) {
+               return(NULL);
+       }
+
+       if((list->tqual = parse_type_qualifier())) {
+               return(list);
+       }
+
+       pos = lex_getpos();
+
+       list->next = parse_type_qualifier_list();
+       list->tqual = parse_type_qualifier();
+
+       if(list->next && list->tqual) {
+               return(list);
+       }
+
+       type_qualifier_list_free(list);
+       lex_setpos(pos);
+
+       return(NULL);
+}
+
+struct direct_abstract_declarator *parse_direct_abstract_declarator(void)
+{
+       struct direct_abstract_declarator *decl;
+       int pos;
+
+       decl = direct_abstract_declarator_new();
+
+       if(!decl) {
+               return(NULL);
+       }
+
+       pos = lex_getpos();
+
+       decl->data.abs.lparen = lex_gettoken();
+       decl->data.abs.decl = parse_abstract_declarator();
+       decl->data.abs.rparen = lex_gettoken();
+
+       if(decl->data.abs.lparen && decl->data.abs.decl && decl->data.abs.rparen &&
+          decl->data.abs.lparen->type == TOKEN_LPAREN && decl->data.abs.rparen->type == TOKEN_RPAREN) {
+               decl->type = DIRECT_ABSTRACT_DECL_ABS;
+               return(decl);
+       }
+
+       if(decl->data.abs.decl) {
+               abstract_declarator_free(decl->data.abs.decl);
+               decl->data.abs.decl = NULL;
+       }
+
+       decl->data.abs.lparen = NULL;
+       decl->data.abs.rparen = NULL;
+
+       lex_setpos(pos);
+
+       decl->data.cnst.next = parse_direct_abstract_declarator();
+       decl->data.cnst.lbracket = lex_gettoken();
+       decl->data.cnst.cexpr = parse_constant_expression();
+       decl->data.cnst.rbracket = lex_gettoken();
+
+       if(decl->data.cnst.lbracket && decl->data.cnst.rbracket &&
+          decl->data.cnst.lbracket->type == TOKEN_LBRACKET &&
+          decl->data.cnst.rbracket->type == TOKEN_RBRACKET) {
+               decl->type = DIRECT_ABSTRACT_DECL_CNST;
+               return(decl);
+       }
+
+       if(decl->data.cnst.next) {
+               direct_abstract_declarator_free(decl->data.cnst.next);
+               decl->data.cnst.next = NULL;
+       }
+
+       if(decl->data.cnst.cexpr) {
+               constant_expression_free(decl->data.cnst.cexpr);
+               decl->data.cnst.cexpr = NULL;
+       }
+
+       decl->data.cnst.lbracket = NULL;
+       decl->data.cnst.rbracket = NULL;
+
+       lex_setpos(pos);
+
+       decl->data.param.next = parse_direct_abstract_declarator();
+       decl->data.param.lparen = lex_gettoken();
+       decl->data.param.params = parse_parameter_type_list();
+       decl->data.param.rparen = lex_gettoken();
+
+       decl->type = DIRECT_ABSTRACT_DECL_PARAM;
+
+       if(decl->data.param.lparen && decl->data.param.rparen &&
+          decl->data.param.lparen->type == TOKEN_LPAREN &&
+          decl->data.param.rparen->type == TOKEN_RPAREN) {
+               return(decl);
+       }
+
+       direct_abstract_declarator_free(decl);
+       lex_setpos(pos);
+
+       return(NULL);
+}
+
+struct constant_expression *parse_constant_expression(void)
+{
+       struct constant_expression *expr;
+
+       expr = constant_expression_new();
+
+       if(expr) {
+               expr->cexpr = parse_conditional_expression();
+
+               if(!expr->cexpr) {
+                       constant_expression_free(expr);
+                       expr = NULL;
+               }
+       }
+
+       return(expr);
+}
+
+struct parameter_type_list *parse_parameter_type_list(void)
+{
+       struct parameter_type_list *list;
+
+       list = parameter_type_list_new();
+
+       if(!list) {
+               return(NULL);
+       }
+
+       list->params = parse_parameter_list();
+
+       if(list->params) {
+               int pos;
+
+               pos = lex_getpos();
+
+               list->comma = lex_gettoken();
+               list->dots = lex_gettoken();
+
+               if(!(list->comma && list->dots &&
+                    list->comma->type == TOKEN_COMMA &&
+                    list->dots->type == TOKEN_DOTS)) {
+                       list->comma = NULL;
+                       list->dots = NULL;
+
+                       lex_setpos(pos);
+               }
+
+               return(list);
+       }
+
+       parameter_type_list_free(list);
+
+       return(NULL);
+}
+
+struct parameter_list *parse_parameter_list(void)
+{
+       struct parameter_list *list;
+       int pos;
+
+       list = parameter_list_new();
+
+       if(!list) {
+               return(NULL);
+       }
+
+       if((list->decl = parse_parameter_declaration())) {
+               /* FIXME: should we be matching the second case first? */
+               return(list);
+       }
+
+       pos = lex_getpos();
+
+       list->next = parse_parameter_list();
+       list->comma = lex_gettoken();
+       list->decl = parse_parameter_declaration();
+
+       if(list->next && list->comma && list->decl && list->comma->type == TOKEN_COMMA) {
+               return(list);
+       }
+
+       parameter_list_free(list);
+       lex_setpos(pos);
+
+       return(NULL);
+}
+
+struct parameter_declaration *parse_parameter_declaration(void)
+{
+       struct parameter_declaration *decl;
+
+       decl = parameter_declaration_new();
+
+       if(!decl) {
+               return(NULL);
+       }
+
+       decl->specs = parse_declaration_specifiers();
+
+       if(decl->specs) {
+               decl->decl = parse_declarator();
+
+               if(!decl->decl) {
+                       decl->adecl = parse_abstract_declarator();
+               }
+
+               return(decl);
+       }
+
+       parameter_declaration_free(decl);
+
+       return(NULL);
+}
+
+struct identifier_list *parse_identifier_list(void)
+{
+       struct identifier_list *list;
+       int pos;
+
+       list = identifier_list_new();
+
+       if(!list) {
+               return(NULL);
+       }
+
+       if((list->identifier = parse_identifier())) {
+               return(list);
+       }
+
+       pos = lex_getpos();
+
+       list->next = parse_identifier_list();
+       list->comma = lex_gettoken();
+       list->identifier = parse_identifier();
+
+       if(list->next && list->comma && list->identifier && list->comma->type == TOKEN_COMMA) {
+               return(list);
+       }
+
+       identifier_list_free(list);
+       lex_setpos(pos);
+
+       return(NULL);
+}
index fc09c0923d846898fa442711a5c3d576e112a59e..93660e506f7058840cfff04af99cf4cc09c1a326 100644 (file)
@@ -10,7 +10,9 @@ struct enumeration_constant *parse_enumeration_constant(void);
 struct constant *parse_constant(void);
 struct string *parse_string(void);
 struct type_name *parse_type_name(void);
+struct pointer *parse_pointer(void);
 
+struct specifier_qualifier_list *parse_specifier_qualifier_list(void);
 struct abstract_declarator *parse_abstract_declarator(void);
 struct assignment_expression *parse_assignment_expression(void);
 struct logical_or_expression *parse_logical_or_expression(void);
@@ -42,9 +44,16 @@ struct declaration_list *parse_declaration_list(void);
 struct declaration_specifiers *parse_declaration_specifiers(void);
 struct function_definition *parse_function_definition(void);
 struct compound_statement *parse_compound_statement(void);
+struct direct_abstract_declarator *parse_direct_abstract_declarator(void);
+struct type_qualifier_list *parse_type_qualifier_list(void);
 struct declarator *parse_declarator(void);
 struct declaration *parse_declaration(void);
 struct external_declaration *parse_external_declaration(void);
 struct translation_unit *parse_translation_unit(struct translation_unit*);
+struct constant_expression *parse_constant_expression(void);
+struct parameter_type_list *parse_parameter_type_list(void);
+struct parameter_list *parse_parameter_list(void);
+struct parameter_declaration *parse_parameter_declaration(void);
+struct identifier_list *parse_identifier_list(void);
 
 #endif /* PARSER_H */