From: Matthias Kruk Date: Sun, 19 Jul 2020 09:40:30 +0000 (+0900) Subject: parser: Add syntax_node and rule types, and start rewrite of the parser to have a... X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=d741d8f0f416e503e2e64a7edbd7e7888c5ebafe;p=ccc parser: Add syntax_node and rule types, and start rewrite of the parser to have a cleaner separation between data and code --- diff --git a/src/Makefile b/src/Makefile index 1d163b2..4c497cf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJECTS = str.o token.o list.o lex.o main.o parser.o grammar.o +OBJECTS = str.o token.o list.o lex.o main.o parser.o grammar.o assoc_array.o OUTPUT = c3 PHONY = clean diff --git a/src/grammar.c b/src/grammar.c index 7870e71..45ab477 100644 --- a/src/grammar.c +++ b/src/grammar.c @@ -4,6 +4,706 @@ #include "grammar.h" #include "token.h" +struct rule _translation_unit_production_A[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_EXTERNAL_DECLARATION, + .name = "external-declaration" + }, { + 0 + } +}; + +struct rule _translation_unit_production_B[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_TRANSLATION_UNIT, + .name = "translation-unit" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_EXTERNAL_DECLARATION, + .name = "external-declaration" + }, { + 0 + } +}; + +struct rule **_translation_unit_productions = { + _translation_unit_production_A, + _translation_unit_production_B, + NULL +}; + +struct rule _external_declaration_production_A[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_FUNCTION_DEFINITION, + .name = "function-definition" + }, { + 0 + } +}; + +struct rule _external_declaration_production_B[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION, + .name = "declaration" + }, { + 0 + } +}; + +struct rule **_external_declaration_productions = { + _external_declaration_production_A, + _external_declaration_production_B, + NULL +}; + +struct rule _function_definition_production_A[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS, + .flags = RULE_FLAG_OPTIONAL, + .name = "declaration-specifiers" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATOR, + .name = "declarator" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_LIST, + .flags = RULE_FLAG_OPTIONAL, + .name = "declaration-list" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_COMPOUND_STATEMENT, + .name = "compound-statement" + }, { + 0 + } +}; + +struct rule **_function_definition_productions = { + _function_definition_production_A, + NULL +}; + +struct rule _declaration_production_A[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS, + .name = "declaration-specifiers" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_INIT_DECLARATOR_LIST, + .flags = RULE_FLAG_OPTIONAL, + .name = "init-declarator-list" + }, { + 0 + } +}; + +struct rule **_declaration_productions = { + _declaration_productions_A, + NULL +}; + +struct rule _declaration_list_production_A[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION, + .name = "declaration" + }, { + 0 + } +}; + +struct rule _declaration_list_production_B[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_LIST, + .name = "declaration-list" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION, + .name = "declaration" + }, { + 0 + } +}; + +struct rule **_declaration_list_productions = { + _declaration_list_production_A, + _declaration_list_production_B, + NULL +}; + +struct rule _declaration_specifiers_production_A[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_STORAGE_CLASS_SPECIFIER, + .name = "storage-class-specifier" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS, + .flags = RULE_FLAG_OPTIONAL, + .name = "declaration-specifiers" + }, { + 0 + } +}; + +struct rule _declaration_specifiers_production_B[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_TYPE_SPECIFIER, + .name = "type-specifier" + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS, + .flags = RULE_FLAG_OPTIONAL, + .name = "declaration-specifiers" + }, { + 0 + } +}; + +struct rule _declaration_specifiers_production_C[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER, + .name = "type-qualifier", + }, { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS, + .flags = RULE_FLAG_OPTIONAL, + .name = "declaration-specifiers" + }, { + 0 + } +}; + +struct rule **_declaration_specifiers_productions = { + _declaration_specifiers_production_A, + _declaration_specifiers_production_B, + _declaration_specifiers_production_C, + NULL +}; + +struct rule _storage_class_specifier_production_A[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_AUTO, + .name = "terminal" + }, { + 0 + } +}; + +struct rule _storage_class_specifier_production_B[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_REGISTER, + .name = "terminal" + }, { + 0 + } +}; + +struct rule _storage_class_specifier_production_C[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_STATIC, + .name = "terminal" + }, { + 0 + } +}; + +struct rule _storage_class_specifier_production_D[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_EXTERN, + .name = "terminal" + }, { + 0 + } +}; + +struct rule _storage_class_specifier_production_E[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_TYPEDEF, + .name = "terminal" + }, { + 0 + } +}; + +struct rule **_storage_class_specifier_productions = { + _storage_class_specifier_production_A, + _storage_class_specifier_production_B, + _storage_class_specifier_production_C, + _storage_class_specifier_production_D, + _storage_class_specifier_production_E, + NULL +}; + +struct rule _type_specifier_production_A[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_VOID, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_B[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_CHAR, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_C[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_SHORT, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_D[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_INT, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_E[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_LONG, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_F[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_FLOAT, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_G[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_DOUBLE, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_H[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_SIGNED, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_I[] = { + { + .type = RULE_TERMINAL, + .terminal = TOKEN_UNSIGNED, + .name = "type" + }, { + 0 + } +}; + +struct rule _type_specifier_production_J[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_STRUCT_OR_UNION_SPECIFIER, + .name = "struct-or-union-specifier" + }, { + 0 + } +}; + +struct rule _type_specifier_production_K[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_ENUM_SPECIFIER, + .name = "enum-specifier" + }, { + 0 + } +}; + +struct rule _type_specifier_production_L[] = { + { + .type = RULE_NONTERMINAL, + .nonterminal = SYNTAX_NODE_TYPEDEF_NAME, + .name = "typedef-name" + }, { + 0 + } +}; + +struct rule **_type_specifier_productions = { + _type_specifier_production_A, + _type_specifier_production_B, + _type_specifier_production_C, + _type_specifier_production_D, + _type_specifier_production_E, + _type_specifier_production_F, + _type_specifier_production_G, + _type_specifier_production_H, + _type_specifier_production_I, + _type_specifier_production_J, + _type_specifier_production_K, + _type_specifier_production_L, + NULL +}; + +struct syntax_node_descriptor _node_descriptors[] = { + /* order needs to be in sync with syntax_node_type_t */ + { + .type = SYNTAX_NODE_INVALID, + .productions = NULL, + .parse = NULL + }, { + .type = SYNTAX_NODE_TRANSLATION_UNIT, + .productions = _translation_unit_productions, + .parse = translation_unit_parse + }, { + .type = SYNTAX_NODE_EXTERNAL_DECLARATION, + .productions = _external_declaration_productions, + .parse = external_declaration_parse + }, { + .type = SYNTAX_NODE_FUNCTION_DEFINITION, + .productions = _function_definition_productions, + .parse = function_definition_parse + }, { + .type = SYNTAX_NODE_DECLARATION, + .productions = _declaration_productions, + .parse = declaration_parse + }, { + .type = SYNTAX_NODE_DECLARATION_LIST, + .productions = _declaration_list_productions, + .parse = declaration_list_parse + }, { + .type = SYNTAX_NODE_DECLARATION_SPECIFIERS, + .productions = _declaration_specifiers_productions, + .parse = declaration_specifiers_parse + }, { + .type = SYNTAX_NODE_STORAGE_CLASS_SPECIFIER, + .productions = _storage_class_specifier_productions, + .parse = storage_class_specifier_parse + }, { + .type = SYNTAX_NODE_TYPE_SPECIFIER, + .productions = _type_specifier_productions, + .parse = type_specifier_parse + }, { + .type = SYNTAX_NODE_TYPE_QUALIFIER, + .productions = _type_qualifier_productions, + .parse = type_qualifier_parse + }, { + .type = SYNTAX_NODE_STRUCT_OR_UNION_SPECIFIER, + .productions = _struct_or_union_specifier_productions, + .parse = struct_or_union_specifier_parse + }, { + .type = SYNTAX_NODE_STRUCT_OR_UNION, + .productions = _struct_or_union_productions, + .parse = struct_or_union_parse + }, { + .type = SYNTAX_NODE_STRUCT_DECLARATION_LIST, + .productions = _struct_declaration_list_productions, + .parse = struct_declaration_list_parse + }, { + .type = SYNTAX_NODE_INIT_DECLARATOR_LIST, + .productions = _init_declarator_list_productions, + .parse = init_declarator_list_parse + }, { + .type = SYNTAX_NODE_INIT_DECLARATOR, + .productions = _init_declarator_productions, + .parse = init_declarator_parse + }, { + .type = SYNTAX_NODE_STRUCT_DECLARATION, + .productions = _struct_declaration_productions, + .parse = struct_declaration_parse + }, { + .type = SYNTAX_NODE_SPECIFIER_QUALIFIER_LIST, + .productions = _specifier_qualifier_list_productions, + .parse = specifier_qualifier_list_parse + }, { + .type = SYNTAX_NODE_STRUCT_DECLARATOR_LIST, + .productions = _struct_declarator_list_productions, + .parse = struct_declarator_list_parse + }, { + .type = SYNTAX_NODE_STRUCT_DECLARATOR, + .productions = _struct_declarator_productions, + .parse = struct_declarator_parse + }, { + .type = SYNTAX_NODE_ENUM_SPECIFIER, + .productions = _enum_specifier_productions, + .parse = enum_specifier_parse + }, { + .type = SYNTAX_NODE_ENUMERATOR_LIST, + .productions = _enumerator_list_productions, + .parse = enumerator_list_parse + }, { + .type = SYNTAX_NODE_ENUMERATOR, + .productions = _enumerator_productions, + .parse = enumerator_parse + }, { + .type = SYNTAX_NODE_DECLARATOR, + .productions = _declarator_productions, + .parse = declarator_parse + }, { + .type = SYNTAX_NODE_DIRECT_DECLARATOR, + .productions = _direct_declarator_productions, + .parse = direct_declarator_parse + }, { + .type = SYNTAX_NODE_POINTER, + .productions = _pointer_productions, + .parse = pointer_parse + }, { + .type = SYNTAX_NODE_TYPE_QUALIFIER_LIST, + .productions = _type_qualifier_list_productions, + .parse = type_qualifier_list_parse + }, { + .type = SYNTAX_NODE_PARAMETER_TYPE_LIST, + .productions = _parameter_type_list_productions, + .parse = parameter_type_list_parse + }, { + .type = SYNTAX_NODE_PARAMETER_LIST, + .productions = _parameter_list_productions, + .parse = parameter_list_parse + }, { + .type = SYNTAX_NODE_PARAMETER_DECLARATION, + .productions = _parameter_declaration_productions, + .parse = parameter_declaration_parse + }, { + .type = SYNTAX_NODE_IDENTIFIER_LIST, + .productions = _identifier_list_productions, + .parse = identifier_list_parse + }, { + .type = SYNTAX_NODE_INITIALIZER, + .productions = _initializer_productions, + .parse = initializer_parse + }, { + .type = SYNTAX_NODE_INITIALIZER_LIST, + .productions = _initializer_list_productions, + .parse = initializer_list_parse + }, { + .type = SYNTAX_NODE_TYPE_NAME, + .productions = _type_name_productions, + .parse = type_name_parse + }, { + .type = SYNTAX_NODE_ABSTRACT_DECLARATOR, + .productions = _abstract_declarator_productions, + .parse = abstract_declarator_parse + }, { + .type = SYNTAX_NODE_DIRECT_ABSTRACT_DECLARATOR, + .productions = _direct_abstract_declarator_productions, + .parse = direct_abstract_declarator_parse + }, { + .type = SYNTAX_NODE_TYPEDEF_NAME, + .productions = _typedef_name_productions, + .parse = typedef_name_parse + }, { + .type = SYNTAX_NODE_STATEMENT, + .productions = _statement_productions, + .parse = statement_parse + }, { + .type = SYNTAX_NODE_LABELED_STATEMENT, + .productions = _labeled_statement_productions, + .parse = labeled_statement_parse + }, { + .type = SYNTAX_NODE_EXPRESSION_STATEMENT, + .productions = _expression_statement_productions, + .parse = expression_statement_parse + }, { + .type = SYNTAX_NODE_COMPOUND_STATEMENT, + .productions = _compound_statement_productions, + .parse = compound_statement_parse + }, { + .type = SYNTAX_NODE_STATEMENT_LIST, + .productions = _statement_list_productions, + .parse = statement_list_parse + }, { + .type = SYNTAX_NODE_SELECTION_STATEMENT, + .productions = _selection_statement_productions, + .parse = selection_statement_parse + }, { + .type = SYNTAX_NODE_IF_STATEMENT, + .productions = _if_statement_productions, + .parse = if_statement_parse + }, { + .type = SYNTAX_NODE_IF_ELSE_STATEMENT, + .productions = _if_else_statement_productions, + .parse = if_else_statement_parse + }, { + .type = SYNTAX_NODE_SWITCH_STATEMENT, + .productions = _switch_statement_productions, + .parse = switch_statement_parse + }, { + .type = SYNTAX_NODE_ITERATION_STATEMENT, + .productions = _iteration_statement_productions, + .parse = iteration_statement_parse + }, { + .type = SYNTAX_NODE_WHILE_STATEMENT, + .productions = _while_statement_productions, + .parse = while_statement_parse + }, { + .type = SYNTAX_NODE_DO_WHILE_STATEMENT, + .productions = _do_while_statement_productions, + .parse = do_while_statement_parse + }, { + .type = SYNTAX_NODE_FOR_STATEMENT, + .productions = _for_statement_productions, + .parse = for_statement_parse + }, { + .type = SYNTAX_NODE_JUMP_STATEMENT, + .productions = _jump_statement_productions, + .parse = jump_statement_parse + }, { + .type = SYNTAX_NODE_GOTO_STATEMENT, + .productions = _goto_statement_productions, + .parse = goto_statement_parse + }, { + .type = SYNTAX_NODE_CONTINUE_STATEMENT, + .productions = _continue_statement_productions, + .parse = continue_statement_parse + }, { + .type = SYNTAX_NODE_BREAK_STATEMENT, + .productions = _break_statement_productions, + .parse = break_statement_parse + }, { + .type = SYNTAX_NODE_RETURN_STATEMENT, + .productions = _return_statement_productions, + .parse = return_statement_parse + }, { + .type = SYNTAX_NODE_EXPRESSION, + .productions = _expression_productions, + .parse = expression_parse + }, { + .type = SYNTAX_NODE_ASSIGNMENT_EXPRESSION, + .productions = _assignement_expression_productions, + .parse = assignement_expression_parse + }, { + .type = SYNTAX_NODE_ASSIGNMENT_OPERATOR, + .productions = _assignment_operator_productions, + .parse = assignment_operator_parse + }, { + .type = SYNTAX_NODE_CONDITIONAL_EXPRESSION, + .productions = _conditional_expression_productions, + .parse = conditional_expression_parse + }, { + .type = SYNTAX_NODE_CONSTANT_EXPRESSION, + .productions = _constant_expression_productions, + .parse = constant_expression_parse + }, { + .type = SYNTAX_NODE_LOGICAL_OR_EXPRESSION, + .productions = _logical_or_expression_productions, + .parse = logical_or_expression_parse + }, { + .type = SYNTAX_NODE_LOGICAL_AND_EXPRESSION, + .productions = _logical_and_expression_productions, + .parse = logical_and_expression_parse + }, { + .type = SYNTAX_NODE_INCLUSIVE_OR_EXPRESSION, + .productions = _inclusive_or_expression_productions, + .parse = inclusive_or_expression_parse + }, { + .type = SYNTAX_NODE_EXCLUSIVE_OR_EXPRESSION, + .productions = _exclusive_or_expression_productions, + .parse = exclusive_or_expression_parse + }, { + .type = SYNTAX_NODE_AND_EXPRESSION, + .productions = _and_expression_productions, + .parse = and_expression_parse + }, { + .type = SYNTAX_NODE_EQUALITY_EXPRESSION, + .productions = _equality_expression_productions, + .parse = equality_expression_parse + }, { + .type = SYNTAX_NODE_RELATIONAL_EXPRESSION, + .productions = _relational_expression_productions, + .parse = relational_expression_parse + }, { + .type = SYNTAX_NODE_SHIFT_EXPRESSION, + .productions = _shift_expression_productions, + .parse = shift_expression_parse + }, { + .type = SYNTAX_NODE_ADDITIVE_EXPRESSION, + .productions = _additive_expression_productions, + .parse = additive_expression_parse + }, { + .type = SYNTAX_NODE_MULTIPLICATIVE_EXRESSION, + .productions = _multiplicative_expression_productions, + .parse = multiplicative_expression_parse + }, { + .type = SYNTAX_NODE_CAST_EXPRESSION, + .productions = _cast_expression_productions, + .parse = cast_expression_parse + }, { + .type = SYNTAX_NODE_UNARY_EXPRESSION, + .productions = _unary_expression_productions, + .parse = unary_expression_parse + }, { + .type = SYNTAX_NODE_UNARY_OPERATOR, + .productions = _unary_operator_productions, + .parse = unary_operator_parse + }, { + .type = SYNTAX_NODE_POSTFIX_EXPRESSION, + .productions = _postfix_expression_productions, + .parse = postfix_expression_parse + }, { + .type = SYNTAX_NODE_PRIMARY_EXPRESSION, + .productions = _primary_expression_productions, + .parse = primary_expression_parse + }, { + .type = SYNTAX_NODE_ARGUMENT_EXPRESSION_LIST, + .productions = _argument_expression_list_productions, + .parse = argument_expression_list_parse + }, { + .type = SYNTAX_NODE_CONSTANT, + .productions = _constant_productions, + .parse = constant_parse + } +}; + +struct syntax_node* syntax_node_parse(syntax_node_type_t type) +{ + if(type > 0 && type < SYNTAX_NODE_MAX) { + return(_node_descriptors[type].parse()); + } + + return(NULL); +} + struct function_definition *function_definition_new(void) { struct function_definition *fd; diff --git a/src/grammar.h b/src/grammar.h index 4c27c39..aa7fea9 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -1,8 +1,121 @@ #ifndef GRAMMAR_H #define GRAMMAR_H +#include "token.h" + struct token; +typedef enum { + SYNTAX_NODE_INVALID = 0, + SYNTAX_NODE_TRANSLATION_UNIT, + SYNTAX_NODE_EXTERNAL_DECLARATION, + SYNTAX_NODE_FUNCTION_DEFINITION, + SYNTAX_NODE_DECLARATION, + SYNTAX_NODE_DECLARATION_LIST, + SYNTAX_NODE_DECLARATION_SPECIFIERS, + SYNTAX_NODE_STORAGE_CLASS_SPECIFIER, + SYNTAX_NODE_TYPE_SPECIFIER, + SYNTAX_NODE_TYPE_QUALIFIER, + SYNTAX_NODE_STRUCT_OR_UNION_SPECIFIER, + SYNTAX_NODE_STRUCT_OR_UNION, + SYNTAX_NODE_STRUCT_DECLARATION_LIST, + SYNTAX_NODE_INIT_DECLARATOR_LIST, + SYNTAX_NODE_INIT_DECLARATOR, + SYNTAX_NODE_STRUCT_DECLARATION, + SYNTAX_NODE_SPECIFIER_QUALIFIER_LIST, + SYNTAX_NODE_STRUCT_DECLARATOR_LIST, + SYNTAX_NODE_STRUCT_DECLARATOR, + SYNTAX_NODE_ENUM_SPECIFIER, + SYNTAX_NODE_ENUMERATOR_LIST, + SYNTAX_NODE_ENUMERATOR, + SYNTAX_NODE_DECLARATOR, + SYNTAX_NODE_DIRECT_DECLARATOR, + SYNTAX_NODE_POINTER, + SYNTAX_NODE_TYPE_QUALIFIER_LIST, + SYNTAX_NODE_PARAMETER_TYPE_LIST, + SYNTAX_NODE_PARAMETER_LIST, + SYNTAX_NODE_PARAMETER_DECLARATION, + SYNTAX_NODE_IDENTIFIER_LIST, + SYNTAX_NODE_INITIALIZER, + SYNTAX_NODE_INITIALIZER_LIST, + SYNTAX_NODE_TYPE_NAME, + SYNTAX_NODE_ABSTRACT_DECLARATOR, + SYNTAX_NODE_DIRECT_ABSTRACT_DECLARATOR, + SYNTAX_NODE_TYPEDEF_NAME, + SYNTAX_NODE_STATEMENT, + SYNTAX_NODE_LABELED_STATEMENT, + SYNTAX_NODE_EXPRESSION_STATEMENT, + SYNTAX_NODE_COMPOUND_STATEMENT, + SYNTAX_NODE_STATEMENT_LIST, + SYNTAX_NODE_SELECTION_STATEMENT, + SYNTAX_NODE_IF_STATEMENT, + SYNTAX_NODE_IF_ELSE_STATEMENT, + SYNTAX_NODE_SWITCH_STATEMENT, + SYNTAX_NODE_ITERATION_STATEMENT, + SYNTAX_NODE_WHILE_STATEMENT, + SYNTAX_NODE_DO_WHILE_STATEMENT, + SYNTAX_NODE_FOR_STATEMENT, + SYNTAX_NODE_JUMP_STATEMENT, + SYNTAX_NODE_GOTO_STATEMENT, + SYNTAX_NODE_CONTINUE_STATEMENT, + SYNTAX_NODE_BREAK_STATEMENT, + SYNTAX_NODE_RETURN_STATEMENT, + SYNTAX_NODE_EXPRESSION, + SYNTAX_NODE_ASSIGNMENT_EXPRESSION, + SYNTAX_NODE_ASSIGNMENT_OPERATOR, + SYNTAX_NODE_CONDITIONAL_EXPRESSION, + SYNTAX_NODE_CONSTANT_EXPRESSION, + SYNTAX_NODE_LOGICAL_OR_EXPRESSION, + SYNTAX_NODE_LOGICAL_AND_EXPRESSION, + SYNTAX_NODE_INCLUSIVE_OR_EXPRESSION, + SYNTAX_NODE_EXCLUSIVE_OR_EXPRESSION, + SYNTAX_NODE_AND_EXPRESSION, + SYNTAX_NODE_EQUALITY_EXPRESSION, + SYNTAX_NODE_RELATIONAL_EXPRESSION, + SYNTAX_NODE_SHIFT_EXPRESSION, + SYNTAX_NODE_ADDITIVE_EXPRESSION, + SYNTAX_NODE_MULTIPLICATIVE_EXRESSION, + SYNTAX_NODE_CAST_EXPRESSION, + SYNTAX_NODE_UNARY_EXPRESSION, + SYNTAX_NODE_UNARY_OPERATOR, + SYNTAX_NODE_POSTFIX_EXPRESSION, + SYNTAX_NODE_PRIMARY_EXPRESSION, + SYNTAX_NODE_ARGUMENT_EXPRESSION_LIST, + SYNTAX_NODE_CONSTANT, + SYNTAX_NODE_MAX +} syntax_node_type_t; + +struct syntax_node_descriptor { + syntax_node_type_t type; + + struct rule **productions; + struct syntax_node* (*parse)(void); +}; + +struct syntax_node { + syntax_node_type_t type; + + int (*debug)(struct syntax_node*); + int (*free)(struct syntax_node*); +}; + +struct syntax_node *syntax_node_parse(syntax_node_type_t); + +enum rule_type { + RULE_TERMINAL, + RULE_NONTERMINAL +}; + +#define RULE_FLAG_OPTIONAL (1 << 0) + +struct rule { + enum rule_type type; + unsigned flags; + token_type_t terminal; + syntax_node_type_t nonterminal; + const char *name; +}; + struct integer_constant { /* * 0[0-9] \ diff --git a/src/main.c b/src/main.c index 7d5c4fa..997f4ee 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,9 @@ #include +#include #include "lex.h" #include "parser.h" #include "str.h" +#include "assoc_array.h" int main(int argc, char *argv[]) { @@ -9,7 +11,9 @@ int main(int argc, char *argv[]) struct string *s; struct token *tok; struct primary_expression *pexpr; + struct assignment_expression *aexpr; int pos; + struct assoc_array *aa; pos = lex_getpos(); @@ -20,6 +24,23 @@ int main(int argc, char *argv[]) lex_setpos(pos); + aa = assoc_array_new(); + assert(aa); + + assert(assoc_array_set(aa, "hoge", "__hoge__") == 0); + assert(assoc_array_set(aa, "foo", "__foo__") == 0); + + char *ptr; + + assert(assoc_array_get(aa, "hoge", (void**)&ptr) == 0); + printf("aa[\"hoge\"] = \"%s\"\n", ptr); + assert(assoc_array_get(aa, "foo", (void**)&ptr) == 0); + printf("aa[\"foo\"] = \"%s\"\n", ptr); + + aexpr = parse_assignment_expression(); + + printf("aexpr = %p\n", aexpr); + #if 0 c = parse_constant(); diff --git a/src/parser.c b/src/parser.c index 12dda22..065f498 100644 --- a/src/parser.c +++ b/src/parser.c @@ -767,51 +767,49 @@ struct primary_expression *parse_primary_expression(void) struct assignment_expression *parse_assignment_expression(void) { struct assignment_expression *ae; + int pos; + pos = lex_getpos(); ae = assignment_expression_new(); - if(!ae) { - return(NULL); - } - - if((ae->data.cexpr = parse_conditional_expression())) { - ae->type = ASSIGNMENT_EXPR_CONDITIONAL; - } else { - int pos; + if(ae) { + if((ae->data.cexpr = parse_conditional_expression())) { + ae->type = ASSIGNMENT_EXPR_CONDITIONAL; + } else { - pos = lex_getpos(); + if(!(ae->data.aexpr.uexpr = parse_unary_expression())) { + goto gtfo; + } - ae->data.aexpr.uexpr = parse_unary_expression(); - ae->data.aexpr.op = lex_gettoken(); - ae->data.aexpr.aexpr = parse_assignment_expression(); - - if(ae->data.aexpr.uexpr && ae->data.aexpr.op && ae->data.aexpr.aexpr && - (ae->data.aexpr.op->type == TOKEN_ASSIGN || - ae->data.aexpr.op->type == TOKEN_ASSIGN_ADD || - ae->data.aexpr.op->type == TOKEN_ASSIGN_AND || - ae->data.aexpr.op->type == TOKEN_ASSIGN_MOD || - ae->data.aexpr.op->type == TOKEN_ASSIGN_MUL || - ae->data.aexpr.op->type == TOKEN_ASSIGN_OR || - ae->data.aexpr.op->type == TOKEN_ASSIGN_SHL || - ae->data.aexpr.op->type == TOKEN_ASSIGN_SHR || - ae->data.aexpr.op->type == TOKEN_ASSIGN_SUB || - ae->data.aexpr.op->type == TOKEN_ASSIGN_XOR)) { - ae->type = ASSIGNMENT_EXPR_ASSIGNMENT; - } else { - if(ae->data.aexpr.uexpr) { - free(ae->data.aexpr.uexpr); + if(!(ae->data.aexpr.op = lex_gettoken()) || + (ae->data.aexpr.op->type != TOKEN_ASSIGN && + ae->data.aexpr.op->type != TOKEN_ASSIGN_ADD && + ae->data.aexpr.op->type != TOKEN_ASSIGN_AND && + ae->data.aexpr.op->type != TOKEN_ASSIGN_MOD && + ae->data.aexpr.op->type != TOKEN_ASSIGN_MUL && + ae->data.aexpr.op->type != TOKEN_ASSIGN_OR && + ae->data.aexpr.op->type != TOKEN_ASSIGN_SHL && + ae->data.aexpr.op->type != TOKEN_ASSIGN_SHR && + ae->data.aexpr.op->type != TOKEN_ASSIGN_SUB && + ae->data.aexpr.op->type != TOKEN_ASSIGN_XOR)) { + goto gtfo; } - if(ae->data.aexpr.aexpr) { - free(ae->data.aexpr.aexpr); + if(!(ae->data.aexpr.aexpr = parse_assignment_expression())) { + goto gtfo; } - lex_setpos(pos); - free(ae); - ae = NULL; + ae->type = ASSIGNMENT_EXPR_ASSIGNMENT; } } +gtfo: + if(ae && ae->type == ASSIGNMENT_EXPR_INVALID) { + lex_setpos(pos); + assignment_expression_free(ae); + ae = NULL; + } + return(ae); }