#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
#include "grammar.h"
+#include "token.h"
+
+struct function_definition *function_definition_new(void)
+{
+ struct function_definition *fd;
+
+ fd = malloc(sizeof(*fd));
+
+ if(fd) {
+ memset(fd, 0, sizeof(*fd));
+ }
+
+ return(fd);
+}
struct type_qualifier *type_qualifier_new(struct token *tok)
{
return(tq);
}
+int type_qualifier_to_string(struct type_qualifier *tq, char *dst, size_t n)
+{
+ int ret_val;
+
+ ret_val = snprintf(dst, sizeof(dst), "%s", tq->token ? token_value(tq->token) : "(null)");
+
+ return(ret_val);
+}
+
struct storage_class_specifier *storage_class_specifier_new(struct token *tok)
{
struct storage_class_specifier *sp;
return(ed);
}
+
+struct declaration_specifiers *declaration_specifiers_new(void)
+{
+ struct declaration_specifiers *ds;
+
+ ds = malloc(sizeof(*ds));
+
+ if(ds) {
+ memset(ds, 0, sizeof(*ds));
+ }
+
+ return(ds);
+}
+
+int storage_class_specifier_to_string(struct storage_class_specifier *scspec, char *dst, size_t n)
+{
+ int ret_val;
+
+ ret_val = snprintf(dst, n, "%s", scspec->token ? token_value(scspec->token) : "(null)");
+
+ return(ret_val);
+}
+
+int type_specifier_to_string(struct type_specifier *tspec, char *dst, size_t n)
+{
+ char datastr[512];
+ int ret_val;
+
+ static const char *tspec_typestr[] = {
+ "TYPE_SPECIFIER_INVALID",
+ "TYPE_SPECIFIER_PRIMITIVE",
+ "TYPE_SPECIFIER_STRUCT",
+ "TYPE_SPECIFIER_UNION",
+ "TYPE_SPECIFIER_ENUM",
+ "TYPE_SPECIFIER_TYPEDEF"
+ };
+
+ switch(tspec->type) {
+ case TYPE_SPECIFIER_PRIMITIVE:
+ snprintf(datastr, sizeof(datastr), "%s",
+ tspec->data.token ? token_value(tspec->data.token) : "(null)");
+ break;
+
+ case TYPE_SPECIFIER_STRUCT:
+ case TYPE_SPECIFIER_UNION:
+ case TYPE_SPECIFIER_ENUM:
+ case TYPE_SPECIFIER_TYPEDEF:
+ snprintf(datastr, sizeof(datastr), "(not implemented)");
+ break;
+
+ default:
+ snprintf(datastr, sizeof(datastr), "(inv)");
+ break;
+ }
+
+ ret_val = snprintf(dst, n,
+ "type_specifier {\n"
+ "\ttype = %s\n"
+ "\tdata = %s\n"
+ "}\n",
+ tspec_typestr[tspec->type],
+ datastr);
+
+ return(ret_val);
+}
+
+void declaration_specifiers_debug(struct declaration_specifiers *declspec)
+{
+ static const char *declspec_typestr[] = {
+ "DECL_SPEC_INVALID",
+ "DECL_SPEC_STORAGE_CLASS",
+ "DECL_SPEC_TYPE_SPEC",
+ "DECL_SPEC_TYPE_QUALIFIER"
+ };
+
+ char datastr[512];
+
+ switch(declspec->type) {
+ case DECL_SPEC_STORAGE_CLASS:
+ storage_class_specifier_to_string(declspec->data.scspec, datastr, sizeof(datastr));
+ break;
+
+ case DECL_SPEC_TYPE_SPEC:
+ type_specifier_to_string(declspec->data.tspec, datastr, sizeof(datastr));
+ break;
+
+ case DECL_SPEC_TYPE_QUALIFIER:
+ type_qualifier_to_string(declspec->data.tqual, datastr, sizeof(datastr));
+ break;
+
+ default:
+ snprintf(datastr, sizeof(datastr), "(invalid)");
+ break;
+ }
+
+ printf("decl_spec %p {\n"
+ "\ttype = %s [%s],\n"
+ "\tdata = %p [%s],\n"
+ "\tnext = %p\n"
+ "}",
+ declspec,
+ declspec_typestr[declspec->type],
+ datastr,
+ declspec->next);
+
+ if(declspec->next) {
+ declaration_specifiers_debug(declspec->next);
+ }
+
+ return;
+}
struct type_specifier {
enum type_specifier_type type;
- struct token *token;
- struct struct_specifier *ss;
- struct union_specifier *us;
- struct enum_specifier *es;
- struct typedef_name *tn;
+ union {
+ struct token *token;
+ struct struct_specifier *ss;
+ struct union_specifier *us;
+ struct enum_specifier *es;
+ struct typedef_name *tn;
+ } data;
};
-struct function_definition {
+enum declaration_specifier_type {
+ DECL_SPEC_INVALID = 0,
+ DECL_SPEC_STORAGE_CLASS,
+ DECL_SPEC_TYPE_SPEC,
+ DECL_SPEC_TYPE_QUALIFIER
+};
+
+struct declaration_specifiers {
+ enum declaration_specifier_type type;
+
+ union {
+ struct storage_class_specifier *scspec;
+ struct type_specifier *tspec;
+ struct type_qualifier *tqual;
+ } data;
+
+ struct declaration_specifiers *next;
+};
+
+struct declarator {
+
+};
+struct declaration_list {
+
+};
+
+struct compound_statement {
+
+};
+
+struct function_definition {
+ struct declaration_specifiers *decl_specs;
+ struct declarator *decl;
+ struct declaration_list *decl_list;
+ struct compound_statement *stmts;
};
struct declaration {
struct external_declaration *decl;
};
+struct function_definition *function_definition_new(void);
+
struct type_qualifier *type_qualifier_new(struct token*);
+int type_qualifier_to_string(struct type_qualifier*, char*, size_t);
+
struct storage_class_specifier *storage_class_specifier_new(struct token*);
struct type_specifier *type_specifier_new(void);
struct translation_unit *translation_unit_new(struct external_declaration*);
struct external_declaration *external_declaration_new(void);
+struct declaration_specifiers* declaration_specifiers_new(void);
+void declaration_specifiers_debug(struct declaration_specifiers*);
+
#endif /* GRAMMAR_H */
#include "token.h"
#include "lex.h"
#include "grammar.h"
+#include "parser.h"
struct type_qualifier *parse_type_qualifier(void)
{
case TOKEN_SIGNED:
case TOKEN_UNSIGNED:
ret_val->type = TYPE_SPECIFIER_PRIMITIVE;
- ret_val->token = tok;
+ ret_val->data.token = tok;
break;
case TOKEN_STRUCT:
ret_val->type = TYPE_SPECIFIER_STRUCT;
lex_setpos(pos);
- ret_val->ss = parse_struct_specifier();
+ ret_val->data.ss = parse_struct_specifier();
break;
case TOKEN_UNION:
ret_val->type = TYPE_SPECIFIER_UNION;
lex_setpos(pos);
- ret_val->us = parse_union_specifier();
+ ret_val->data.us = parse_union_specifier();
break;
case TOKEN_ENUM:
ret_val->type = TYPE_SPECIFIER_ENUM;
lex_setpos(pos);
- ret_val->es = parse_enum_specifier();
+ ret_val->data.es = parse_enum_specifier();
break;
default:
ret_val->type = TYPE_SPECIFIER_TYPEDEF;
lex_setpos(pos);
- ret_val->tn = parse_typedef_name();
+ ret_val->data.tn = parse_typedef_name();
break;
}
switch(ret_val->type) {
case TYPE_SPECIFIER_STRUCT:
- if(!ret_val->ss) {
+ if(!ret_val->data.ss) {
/* syntax error */
+#if 0
fprintf(stderr,
"%s:%d:%d [E] Expected struct-specifier\n",
tok->file, tok->line, tok->column);
+#endif
ret_val->type = TYPE_SPECIFIER_INVALID;
}
break;
case TYPE_SPECIFIER_UNION:
- if(!ret_val->us) {
+ if(!ret_val->data.us) {
/* syntax error */
+#if 0
fprintf(stderr,
"%s:%d:%d [E] Expected union-specifier\n",
tok->file, tok->line, tok->column);
+#endif
ret_val->type = TYPE_SPECIFIER_INVALID;
}
break;
case TYPE_SPECIFIER_ENUM:
- if(!ret_val->es) {
+ if(!ret_val->data.es) {
/* syntax error */
+#if 0
fprintf(stderr,
"%s:%d:%d [E] Expected enum-specifier\n",
tok->file, tok->line, tok->column);
+#endif
ret_val->type = TYPE_SPECIFIER_INVALID;
}
break;
case TYPE_SPECIFIER_TYPEDEF:
- if(!ret_val->tn) {
+ if(!ret_val->data.tn) {
/* syntax error */
+#if 0
fprintf(stderr,
"%s:%d:%d [E] Expected typedef-name\n",
tok->file, tok->line, tok->column);
+#endif
ret_val->type = TYPE_SPECIFIER_INVALID;
}
break;
default:
if(ret_val->type != TYPE_SPECIFIER_PRIMITIVE) {
/* syntax error */
+#if 0
fprintf(stderr,
"%s:%d:%d [E] Expected type-specifier\n",
tok->file, tok->line, tok->column);
+#endif
ret_val->type = TYPE_SPECIFIER_INVALID;
}
return(ret_val);
}
+struct declaration_specifiers *parse_declaration_specifiers(void)
+{
+ struct declaration_specifiers *ds;
+ int pos;
+
+ pos = lex_getpos();
+ ds = declaration_specifiers_new();
+
+ ds->data.scspec = parse_storage_class_specifier();
+
+ if(ds->data.scspec) {
+ ds->type = DECL_SPEC_STORAGE_CLASS;
+ goto parse_next;
+ }
+
+ ds->data.tspec = parse_type_specifier();
+
+ if(ds->data.tspec) {
+ ds->type = DECL_SPEC_TYPE_SPEC;
+ goto parse_next;
+ }
+
+ ds->data.tqual = parse_type_qualifier();
+
+ if(ds->data.tqual) {
+ ds->type = DECL_SPEC_TYPE_QUALIFIER;
+ }
+
+parse_next:
+ if(ds->type != DECL_SPEC_INVALID) {
+ ds->next = parse_declaration_specifiers();
+ } else {
+ free(ds);
+ ds = NULL;
+ }
+
+ return(ds);
+}
+
struct function_definition *parse_function_definition(void)
+{
+ struct function_definition *fdef;
+ int pos;
+
+ /*
+ * function-definition:
+ * declaration-specifiers_opt declarator declaration-list_opt compound-statement
+ */
+
+ pos = lex_getpos();
+ fdef = function_definition_new();
+
+ if(fdef) {
+ fdef->decl_specs = parse_declaration_specifiers();
+ fdef->decl = parse_declarator();
+
+ if(!fdef->decl) {
+ free(fdef);
+ fdef = NULL;
+ goto gtfo;
+ }
+
+ fdef->decl_list = parse_declaration_list();
+ fdef->stmts = parse_compound_statement();
+
+ if(!fdef->stmts) {
+ free(fdef);
+ fdef = NULL;
+ }
+ }
+
+ if(!fdef) {
+ lex_setpos(pos);
+ }
+gtfo:
+ return(fdef);
+}
+
+struct declaration_list *parse_declaration_list(void)
+{
+ return(NULL);
+}
+
+struct compound_statement *parse_compound_statement(void)
+{
+ return(NULL);
+}
+
+struct declarator *parse_declarator(void)
{
return(NULL);
}