return;
}
+
+struct primary_expression *primary_expression_new(void)
+{
+ struct primary_expression *pexp;
+
+ pexp = malloc(sizeof(*pexp));
+
+ if(pexp) {
+ memset(pexp, 0, sizeof(*pexp));
+ }
+
+ return(pexp);
+}
+
+struct integer_constant *integer_constant_new(void)
+{
+ struct integer_constant *iconst;
+
+ iconst = malloc(sizeof(*iconst));
+
+ if(iconst) {
+ memset(iconst, 0, sizeof(*iconst));
+ }
+
+ return(iconst);
+}
+
+struct character_constant *character_constant_new(void)
+{
+ struct character_constant *cconst;
+
+ cconst = malloc(sizeof(*cconst));
+
+ if(cconst) {
+ memset(cconst, 0, sizeof(*cconst));
+ }
+
+ return(cconst);
+}
+
+struct floating_constant *floating_constant_new(void)
+{
+ struct floating_constant *fconst;
+
+ fconst = malloc(sizeof(*fconst));
+
+ if(fconst) {
+ memset(fconst, 0, sizeof(*fconst));
+ }
+
+ return(fconst);
+}
+
+struct enumeration_constant *enumeration_constant_new(void)
+{
+ struct enumeration_constant *econst;
+
+ econst = malloc(sizeof(*econst));
+
+ if(econst) {
+ memset(econst, 0, sizeof(*econst));
+ }
+
+ return(econst);
+}
+
+struct constant *constant_new(void)
+{
+ struct constant *c;
+
+ c = malloc(sizeof(*c));
+
+ if(c) {
+ memset(c, 0, sizeof(*c));
+ }
+
+ return(c);
+}
+
+struct argument_expression_list* argument_expression_list_new(void)
+{
+ struct argument_expression_list *aelist;
+
+ aelist = malloc(sizeof(*aelist));
+
+ if(aelist) {
+ memset(aelist, 0, sizeof(*aelist));
+ }
+
+ return(aelist);
+}
+
+void constant_debug(struct constant *cnst)
+{
+ static const char *_const_type_str[] = {
+ "INVALID",
+ "integer",
+ "character",
+ "floating",
+ "enumeration"
+ };
+ char data[128];
+
+ switch(cnst->type) {
+ case CONST_TYPE_INVALID:
+ data[0] = 0;
+ break;
+
+ case CONST_TYPE_INTEGER:
+ snprintf(data, sizeof(data), "%s%s",
+ cnst->data.iconst->token ? token_value(cnst->data.iconst->token) : "",
+ cnst->data.iconst->suffix ? token_value(cnst->data.iconst->suffix) : "");
+ break;
+
+ case CONST_TYPE_CHARACTER:
+ snprintf(data, sizeof(data), "%s%s",
+ cnst->data.cconst->prefix ? token_value(cnst->data.cconst->prefix) : "",
+ cnst->data.cconst->token ? token_value(cnst->data.cconst->token) : "");
+ break;
+
+ case CONST_TYPE_FLOATING:
+ snprintf(data, sizeof(data), "%s%s",
+ cnst->data.fconst->token ? token_value(cnst->data.fconst->token) : "",
+ cnst->data.fconst->suffix ? token_value(cnst->data.fconst->suffix) : "");
+ break;
+
+ case CONST_TYPE_ENUMERATION:
+ snprintf(data, sizeof(data), "%s",
+ cnst->data.econst->token ? token_value(cnst->data.econst->token) : "");
+ break;
+ }
+
+ printf("CONSTANT { %s, %s }\n", _const_type_str[cnst->type], data);
+ return;
+}
struct token;
+struct integer_constant {
+ /*
+ * 0[0-9] \
+ * 0[xX][0-9a-fA-F] | ([uUlL]|ll|LL|ul|uL|ull|uLL|Ul|UL|Ull|ULL|lu|Lu|llu|LLu|lU|LU|llU|LLU)
+ * [1-9][0-9]* /
+ */
+ struct token *token;
+ struct token *suffix;
+};
+
+struct character_constant {
+ /* L'x' */
+ struct token *prefix;
+ struct token *token;
+};
+
+struct floating_constant {
+ /* [0-9]*.[0-9]*([eE][0-9]*)[fFlL] */
+ struct token *token;
+ struct token *suffix;
+};
+
+struct enumeration_constant {
+ struct token *token;
+};
+
+struct argument_expression_list {
+ struct assigment_expression *aexpr;
+ struct argument_expression_list *next;
+};
+
+enum primary_expression_type {
+ PEXPR_INVALID = 0,
+ PEXPR_IDENTIFIER,
+ PEXPR_CONSTANT,
+ PEXPR_STRING,
+ PEXPR_EXPR
+};
+
+struct primary_expression {
+ enum primary_expression_type type;
+
+ union {
+ struct identifier *identifier;
+ struct constant *constant;
+ struct string *string;
+ struct {
+ struct token *oparen;
+ struct expression *expr;
+ struct token *cparen;
+ } expr;
+ } data;
+};
+
+enum constant_type {
+ CONST_TYPE_INVALID = 0,
+ CONST_TYPE_INTEGER,
+ CONST_TYPE_CHARACTER,
+ CONST_TYPE_FLOATING,
+ CONST_TYPE_ENUMERATION
+};
+
+struct constant {
+ enum constant_type type;
+
+ union {
+ struct integer_constant *iconst;
+ struct character_constant *cconst;
+ struct floating_constant *fconst;
+ struct enumeration_constant *econst;
+ } data;
+};
+
+struct identifier {
+ struct token *token;
+};
+
struct type_qualifier {
struct token *token;
};
TYPE_SPECIFIER_TYPEDEF
};
-struct struct_specifier {
- struct token *token;
+enum sq_list_type {
+ SQ_LIST_TYPE_INVALID,
+ SQ_LIST_TYPE_SPECIFIER_LIST,
+ SQ_LIST_TYPE_QUALIFIER_LIST
+};
+
+struct specifier_qualifier_list {
+ enum sq_list_type type;
+
+ union {
+ struct type_specifier *tspec;
+ struct type_qualifier *tqual;
+ } data;
+
+ struct specifier_qualifier_list *next;
+};
+
+struct struct_declarator_list {
+ struct struct_declarator *sdecl;
+ struct struct_declarator_list *next;
+};
+
+struct struct_declaration {
+ struct specifier_qualifier_list *sqlist;
+ struct struct_declarator_list *sdecl;
};
-struct union_specifier {
+struct struct_declaration_list {
+ struct struct_declaration *decl;
+ struct struct_declaration_list *next;
+};
+
+struct struct_union_specifier {
struct token *token;
+ struct identifier *identifier;
+ struct struct_declaration_list *sdecl;
+};
+
+struct enumerator {
+ struct identifier *identifier;
+ struct token *eq;
+ struct constant_expression *cexpr;
+};
+
+struct enumerator_list {
+ struct enumerator *en;
+ struct enumerator_list *next;
};
struct enum_specifier {
struct token *token;
+ struct identifier *identifier;
+ struct enumerator_list *enum_list;
};
struct typedef_name {
struct external_declaration *decl;
};
+struct primary_expression *primary_expression_new(void);
+struct integer_constant *integer_constant_new(void);
+struct character_constant *character_constant_new(void);
+struct floating_constant *floating_constant_new(void);
+struct enumeration_constant *enumeration_constant_new(void);
+struct argument_expression_list *argument_expression_list_new(void);
+
struct function_definition *function_definition_new(void);
struct type_qualifier *type_qualifier_new(struct token*);
struct declaration_specifiers* declaration_specifiers_new(void);
void declaration_specifiers_debug(struct declaration_specifiers*);
+struct constant *constant_new(void);
+struct integer_constant *integer_constant_new(void);
+struct character_constant *character_constant_new(void);
+struct floating_constant *floating_constant_new(void);
+struct enumeration_constant *enueration_constant_new(void);
+
+void constant_debug(struct constant*);
+
#endif /* GRAMMAR_H */
return(ret_val);
}
+
+struct constant *parse_constant(void)
+{
+ struct constant *c;
+
+ c = constant_new();
+
+ if(!c) {
+ goto gtfo;
+ }
+
+ if((c->data.iconst = parse_integer_constant())) {
+ c->type = CONST_TYPE_INTEGER;
+ goto gtfo;
+ }
+
+ if((c->data.cconst = parse_character_constant())) {
+ c->type = CONST_TYPE_CHARACTER;
+ goto gtfo;
+ }
+
+ if((c->data.fconst = parse_floating_constant())) {
+ c->type = CONST_TYPE_FLOATING;
+ goto gtfo;
+ }
+
+ if((c->data.econst = parse_enumeration_constant())) {
+ c->type = CONST_TYPE_ENUMERATION;
+ goto gtfo;
+ }
+
+ /* couldn't parse any of the constant types */
+ free(c);
+ c = NULL;
+
+gtfo:
+ return(c);
+}
+
+struct integer_constant *parse_integer_constant(void)
+{
+ struct integer_constant *ic;
+ int pos;
+
+ ic = integer_constant_new();
+ pos = lex_getpos();
+
+ if(!ic) {
+ return(NULL);
+ }
+
+ ic->token = lex_gettoken();
+
+ if(!ic->token || ic->token->type != TOKEN_NUMBER) {
+ lex_setpos(pos);
+ free(ic);
+ return(NULL);
+ }
+
+ /* we have a valid integer constant - check if there is a suffix */
+
+ pos = lex_getpos();
+ ic->suffix = lex_gettoken();
+
+ if(ic->suffix &&
+ token_cmp(ic->suffix, "U") != 0 &&
+ token_cmp(ic->suffix, "L") != 0 &&
+ token_cmp(ic->suffix, "UL") != 0 &&
+ token_cmp(ic->suffix, "LL") != 0 &&
+ token_cmp(ic->suffix, "ULL") != 0) {
+ /*
+ * We have a token, but it's neither U, L, UL, LL, nor ULL,
+ * so we return what we had without the suffix
+ */
+ ic->suffix = NULL;
+ lex_setpos(pos);
+ }
+
+ return(ic);
+}
+
+struct character_constant *parse_character_constant(void)
+{
+ struct character_constant *cc;
+ int pos;
+
+ cc = character_constant_new();
+
+ if(!cc) {
+ return(NULL);
+ }
+
+ pos = lex_getpos();
+ cc->prefix = lex_gettoken();
+
+ if(!cc->prefix || cc->prefix->type != TOKEN_IDENTIFIER ||
+ token_cmp(cc->prefix, "L") != 0) {
+ lex_setpos(pos);
+ cc->prefix = NULL;
+ }
+
+ cc->token = lex_gettoken();
+
+ if(!cc->token || cc->token->type != TOKEN_CHAR_LITERAL) {
+ lex_setpos(pos);
+ free(cc);
+ cc = NULL;
+ }
+
+ return(cc);
+}
+
+struct floating_constant *parse_floating_constant(void)
+{
+ struct floating_constant *fc;
+ int pos;
+
+ fc = floating_constant_new();
+
+ if(!fc) {
+ return(NULL);
+ }
+
+ pos = lex_getpos();
+ fc->token = lex_gettoken();
+
+ if(!fc->token || fc->token->type != TOKEN_FLOAT_LITERAL) {
+ lex_setpos(pos);
+ free(fc);
+ fc = NULL;
+ } else {
+ pos = lex_getpos();
+ fc->suffix = lex_gettoken();
+
+ if(fc->suffix &&
+ token_cmp(fc->suffix, "f") != 0 &&
+ token_cmp(fc->suffix, "l") != 0 &&
+ token_cmp(fc->suffix, "F") != 0 &&
+ token_cmp(fc->suffix, "L") != 0) {
+ lex_setpos(pos);
+ fc->suffix = NULL;
+ }
+ }
+
+ return(fc);
+}
+
+struct enumeration_constant *parse_enumeration_constant(void)
+{
+ return(NULL);
+}