]> git.corax.cc Git - ccc/commitdiff
parser: Add syntax_node and rule types, and start rewrite of the parser to have a...
authorMatthias Kruk <m@m10k.eu>
Sun, 19 Jul 2020 09:40:30 +0000 (18:40 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 19 Jul 2020 09:40:30 +0000 (18:40 +0900)
src/Makefile
src/grammar.c
src/grammar.h
src/main.c
src/parser.c

index 1d163b2baf74e096360a8ab39362dc21aeb2fbed..4c497cffea87d9229ea696259676dd47687e12ce 100644 (file)
@@ -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
 
index 7870e71879dc58b18b3aaa8398c6a58539bad542..45ab47749324925875cf5f7e01289b75fc7ef6bb 100644 (file)
@@ -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;
index 4c27c39ad92b2389fda33e0d5d6887d072899b6e..aa7fea950195a830a9b38ce2b87ec4a75f200e31 100644 (file)
@@ -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]           \
index 7d5c4fa51cf4b924d3a689651e620a949572e9fb..997f4eeafebd0c11b7b7dd430326dc0435eeee57 100644 (file)
@@ -1,7 +1,9 @@
 #include <stdio.h>
+#include <assert.h>
 #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();
 
index 12dda224dc287dd4ea0529932008f699aed37932..065f4983d3daf670021b1c8a887a8334976890ac 100644 (file)
@@ -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);
 }