#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
#include "token.h"
#include "lex.h"
struct token *token;
};
-const char *_type_qualifiers[] = {
- "const",
- "volatile",
- "restrict",
- NULL
+struct storage_class_specifier {
+ struct token *token;
};
-#if 0
-struct translation_unit {
- struct translation_unit *tunit;
- struct external_declaration *edecl;
+enum type_specifier_type {
+ TYPE_SPECIFIER_INVALID,
+ TYPE_SPECIFIER_PRIMITIVE,
+ TYPE_SPECIFIER_STRUCT,
+ TYPE_SPECIFIER_UNION,
+ TYPE_SPECIFIER_ENUM,
+ TYPE_SPECIFIER_TYPEDEF
};
-struct external_declaration {
- external_declaration_type type;
+struct struct_specifier {
+ struct token *token;
};
-struct function_definition {
- struct external_declaration parent;
+struct union_specifier {
+ struct token *token;
};
-struct declaration {
- struct external_declaration parent;
+struct enum_specifier {
+ struct token *token;
};
-struct translation_unit *parse_translation_unit(void)
-{
- struct translation_unit *tu;
- struct token *tok;
+struct typedef_name {
+ /* add a reference to the typedef? */
+ struct token *token;
+};
- tu = translation_unit_new();
+struct type_specifier {
+ enum type_specifier_type type;
+ struct token *token;
- if(tu) {
- tu->edecx = parse_external_declaration(void);
+ struct struct_specifier *ss;
+ struct union_specifier *us;
+ struct enum_specifier *es;
+ struct typedef_name *tn;
+};
- if(lex_peek()) {
- tu->tunit = parse_translation_unit();
- }
- }
+struct function_definition {
- return(tu);
-}
+};
-struct external_declaration *parse_external_declaration(void)
-{
- struct external_declaration *ed;
+struct declaration {
- ed = (struct external_declaration*)parse_function_definition();
+};
- if(!ed) {
- ed = (struct external_declaration*)parse_declaration();
- }
+struct external_declaration {
+ struct function_definition *fdef;
+ struct declaration *decl;
+};
- return(ed);
-}
-#endif
+struct translation_unit {
+ struct translation_unit *unit;
+ struct external_declaration *decl;
+};
struct type_qualifier *type_qualifier_new(struct token *tok)
{
return(tq);
}
+struct storage_class_specifier *storage_class_specifier_new(struct token *tok)
+{
+ struct storage_class_specifier *sp;
+
+ sp = malloc(sizeof(*sp));
+
+ if(sp) {
+ memset(sp, 0, sizeof(*sp));
+ sp->token = tok;
+ }
+
+ return(sp);
+}
+
struct type_qualifier *parse_type_qualifier(void)
{
struct type_qualifier *ret_val;
return(ret_val);
}
+
+struct storage_class_specifier *parse_storage_class_specifier(void)
+{
+ struct storage_class_specifier *ret_val;
+ struct token *tok;
+ int pos;
+
+ ret_val = NULL;
+ pos = lex_getpos();
+ tok = lex_gettoken();
+
+ if(tok) {
+ switch(tok->type) {
+ case TOKEN_AUTO:
+ case TOKEN_REGISTER:
+ case TOKEN_STATIC:
+ case TOKEN_EXTERN:
+ case TOKEN_TYPEDEF:
+ ret_val = storage_class_specifier_new(tok);
+ break;
+
+ default:
+ lex_setpos(pos);
+ break;
+ }
+ }
+
+ return(ret_val);
+}
+
+struct type_specifier *type_specifier_new(void)
+{
+ struct type_specifier *ts;
+
+ ts = malloc(sizeof(*ts));
+
+ if(ts) {
+ memset(ts, 0, sizeof(*ts));
+ }
+
+ return(ts);
+}
+
+struct translation_unit *translation_unit_new(struct external_declaration *edecl)
+{
+ struct translation_unit *tu;
+
+ tu = malloc(sizeof(*tu));
+
+ if(tu) {
+ memset(tu, 0, sizeof(*tu));
+ tu->decl = edecl;
+ }
+
+ return(tu);
+}
+
+struct struct_specifier *parse_struct_specifier(void)
+{
+ return(NULL);
+}
+
+struct union_specifier *parse_union_specifier(void)
+{
+ return(NULL);
+}
+
+struct enum_specifier *parse_enum_specifier(void)
+{
+ return(NULL);
+}
+
+struct typedef_name *parse_typedef_name(void)
+{
+ return(NULL);
+}
+
+struct type_specifier *parse_type_specifier(void)
+{
+ struct type_specifier *ret_val;
+ struct token *tok;
+ int pos;
+
+ ret_val = type_specifier_new();
+
+ if(ret_val) {
+ pos = lex_getpos();
+ tok = lex_gettoken();
+
+ if(tok) {
+ switch(tok->type) {
+ case TOKEN_VOID:
+ case TOKEN_CHAR:
+ case TOKEN_SHORT:
+ case TOKEN_INT:
+ case TOKEN_LONG:
+ case TOKEN_FLOAT:
+ case TOKEN_DOUBLE:
+ case TOKEN_SIGNED:
+ case TOKEN_UNSIGNED:
+ ret_val->type = TYPE_SPECIFIER_PRIMITIVE;
+ ret_val->token = tok;
+ break;
+
+ case TOKEN_STRUCT:
+ ret_val->type = TYPE_SPECIFIER_STRUCT;
+ lex_setpos(pos);
+ ret_val->ss = parse_struct_specifier();
+ break;
+
+ case TOKEN_UNION:
+ ret_val->type = TYPE_SPECIFIER_UNION;
+ lex_setpos(pos);
+ ret_val->us = parse_union_specifier();
+ break;
+
+ case TOKEN_ENUM:
+ ret_val->type = TYPE_SPECIFIER_ENUM;
+ lex_setpos(pos);
+ ret_val->es = parse_enum_specifier();
+ break;
+
+ default:
+ ret_val->type = TYPE_SPECIFIER_TYPEDEF;
+ lex_setpos(pos);
+ ret_val->tn = parse_typedef_name();
+ break;
+ }
+
+ switch(ret_val->type) {
+ case TYPE_SPECIFIER_STRUCT:
+ if(!ret_val->ss) {
+ /* syntax error */
+ fprintf(stderr, "%s:%d:%d [E] Expected struct-specifier\n",
+ tok->file, tok->line, tok->column);
+ ret_val->type = TYPE_SPECIFIER_INVALID;
+ }
+ break;
+
+ case TYPE_SPECIFIER_UNION:
+ if(!ret_val->us) {
+ /* syntax error */
+ fprintf(stderr, "%s:%d:%d [E] Expected union-specifier\n",
+ tok->file, tok->line, tok->column);
+ ret_val->type = TYPE_SPECIFIER_INVALID;
+ }
+ break;
+
+ case TYPE_SPECIFIER_ENUM:
+ if(!ret_val->es) {
+ /* syntax error */
+ fprintf(stderr, "%s:%d:%d [E] Expected enum-specifier\n",
+ tok->file, tok->line, tok->column);
+ ret_val->type = TYPE_SPECIFIER_INVALID;
+ }
+ break;
+
+ case TYPE_SPECIFIER_TYPEDEF:
+ if(!ret_val->tn) {
+ /* syntax error */
+ fprintf(stderr, "%s:%d:%d [E] Expected typedef-name\n",
+ tok->file, tok->line, tok->column);
+ ret_val->type = TYPE_SPECIFIER_INVALID;
+ }
+ break;
+
+ default:
+ if(ret_val->type != TYPE_SPECIFIER_PRIMITIVE) {
+ /* syntax error */
+ fprintf(stderr, "%s:%d:%d [E] Expected type-specifier\n",
+ tok->file, tok->line, tok->column);
+ ret_val->type = TYPE_SPECIFIER_INVALID;
+ }
+
+ break;
+ }
+ }
+
+ if(ret_val->type == TYPE_SPECIFIER_INVALID) {
+ free(ret_val);
+ ret_val = NULL;
+ }
+ }
+
+ return(ret_val);
+}
+
+struct external_declaration *external_declaration_new(void)
+{
+ struct external_declaration *ed;
+
+ ed = malloc(sizeof(*ed));
+
+ if(ed) {
+ memset(ed, 0, sizeof(*ed));
+ }
+
+ return(ed);
+}
+
+struct function_definition *parse_function_definition(void)
+{
+ return(NULL);
+}
+
+struct declaration *parse_declaration(void)
+{
+ return(NULL);
+}
+
+struct external_declaration *parse_external_declaration(void)
+{
+ struct external_declaration *ret_val;
+
+ ret_val = external_declaration_new();
+
+ if(ret_val) {
+ ret_val->fdef = parse_function_definition();
+
+ if(!ret_val->fdef) {
+ ret_val->decl = parse_declaration();
+ }
+ }
+
+ return(ret_val);
+}
+
+struct translation_unit *parse_translation_unit(struct translation_unit *unit)
+{
+ struct translation_unit *ret_val;
+ struct token *tok;
+ int pos;
+
+ ret_val = NULL;
+ pos = lex_getpos();
+ tok = lex_gettoken();
+
+ if(tok) {
+ struct external_declaration *ed;
+
+ ed = parse_external_declaration();
+
+ if(ed) {
+ ret_val = translation_unit_new(ed);
+
+ if(ret_val) {
+ if(lex_peek()) {
+ /* need to next this external declaration */
+ ret_val = parse_translation_unit(ret_val);
+ }
+ }
+ } else {
+ /* is this necessary? */
+ lex_setpos(pos);
+ }
+ }
+
+ return(ret_val);
+}