]> git.corax.cc Git - ccc/commitdiff
grammar: Add production rules for grammatical structures on pages 295, 296 of "The...
authorMatthias Kruk <m@m10k.eu>
Sun, 19 Jul 2020 15:20:45 +0000 (00:20 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 19 Jul 2020 15:20:45 +0000 (00:20 +0900)
src/grammar.c
src/grammar.h
src/parser.h

index 45ab47749324925875cf5f7e01289b75fc7ef6bb..e0eb8523dc8da8058ea3fe5de3874fb9152ed53b 100644 (file)
@@ -1,10 +1,14 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <errno.h>
 #include "grammar.h"
 #include "token.h"
+#include "parser.h"
+#include "lex.h"
+#include "assoc_array.h"
 
-struct rule _translation_unit_production_A[] = {
+static struct rule _translation_unit_production_A[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_EXTERNAL_DECLARATION,
@@ -14,7 +18,7 @@ struct rule _translation_unit_production_A[] = {
        }
 };
 
-struct rule _translation_unit_production_B[] = {
+static struct rule _translation_unit_production_B[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_TRANSLATION_UNIT,
@@ -28,13 +32,13 @@ struct rule _translation_unit_production_B[] = {
        }
 };
 
-struct rule **_translation_unit_productions = {
+static struct rule *_translation_unit_productions[] = {
        _translation_unit_production_A,
        _translation_unit_production_B,
        NULL
 };
 
-struct rule _external_declaration_production_A[] = {
+static struct rule _external_declaration_production_A[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_FUNCTION_DEFINITION,
@@ -44,7 +48,7 @@ struct rule _external_declaration_production_A[] = {
        }
 };
 
-struct rule _external_declaration_production_B[] = {
+static struct rule _external_declaration_production_B[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_DECLARATION,
@@ -54,13 +58,13 @@ struct rule _external_declaration_production_B[] = {
        }
 };
 
-struct rule **_external_declaration_productions = {
+static struct rule *_external_declaration_productions[] = {
        _external_declaration_production_A,
        _external_declaration_production_B,
        NULL
 };
 
-struct rule _function_definition_production_A[] = {
+static struct rule _function_definition_production_A[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS,
@@ -84,12 +88,12 @@ struct rule _function_definition_production_A[] = {
        }
 };
 
-struct rule **_function_definition_productions = {
+static struct rule *_function_definition_productions[] = {
        _function_definition_production_A,
        NULL
 };
 
-struct rule _declaration_production_A[] = {
+static struct rule _declaration_production_A[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_DECLARATION_SPECIFIERS,
@@ -104,12 +108,12 @@ struct rule _declaration_production_A[] = {
        }
 };
 
-struct rule **_declaration_productions = {
-       _declaration_productions_A,
+static struct rule *_declaration_productions[] = {
+       _declaration_production_A,
        NULL
 };
 
-struct rule _declaration_list_production_A[] = {
+static struct rule _declaration_list_production_A[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_DECLARATION,
@@ -119,7 +123,7 @@ struct rule _declaration_list_production_A[] = {
        }
 };
 
-struct rule _declaration_list_production_B[] = {
+static struct rule _declaration_list_production_B[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_DECLARATION_LIST,
@@ -133,13 +137,13 @@ struct rule _declaration_list_production_B[] = {
        }
 };
 
-struct rule **_declaration_list_productions = {
+static struct rule *_declaration_list_productions[] = {
        _declaration_list_production_A,
        _declaration_list_production_B,
        NULL
 };
 
-struct rule _declaration_specifiers_production_A[] = {
+static struct rule _declaration_specifiers_production_A[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_STORAGE_CLASS_SPECIFIER,
@@ -154,7 +158,7 @@ struct rule _declaration_specifiers_production_A[] = {
        }
 };
 
-struct rule _declaration_specifiers_production_B[] = {
+static struct rule _declaration_specifiers_production_B[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_TYPE_SPECIFIER,
@@ -169,7 +173,7 @@ struct rule _declaration_specifiers_production_B[] = {
        }
 };
 
-struct rule _declaration_specifiers_production_C[] = {
+static struct rule _declaration_specifiers_production_C[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER,
@@ -184,64 +188,64 @@ struct rule _declaration_specifiers_production_C[] = {
        }
 };
 
-struct rule **_declaration_specifiers_productions = {
+static 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[] = {
+static struct rule _storage_class_specifier_production_A[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_AUTO,
-               .name = "terminal"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _storage_class_specifier_production_B[] = {
+static struct rule _storage_class_specifier_production_B[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_REGISTER,
-               .name = "terminal"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _storage_class_specifier_production_C[] = {
+static struct rule _storage_class_specifier_production_C[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_STATIC,
-               .name = "terminal"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _storage_class_specifier_production_D[] = {
+static struct rule _storage_class_specifier_production_D[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_EXTERN,
-               .name = "terminal"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _storage_class_specifier_production_E[] = {
+static struct rule _storage_class_specifier_production_E[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_TYPEDEF,
-               .name = "terminal"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule **_storage_class_specifier_productions = {
+static struct rule *_storage_class_specifier_productions[] = {
        _storage_class_specifier_production_A,
        _storage_class_specifier_production_B,
        _storage_class_specifier_production_C,
@@ -250,97 +254,97 @@ struct rule **_storage_class_specifier_productions = {
        NULL
 };
 
-struct rule _type_specifier_production_A[] = {
+static struct rule _type_specifier_production_A[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_VOID,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_B[] = {
+static struct rule _type_specifier_production_B[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_CHAR,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_C[] = {
+static struct rule _type_specifier_production_C[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_SHORT,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_D[] = {
+static struct rule _type_specifier_production_D[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_INT,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_E[] = {
+static struct rule _type_specifier_production_E[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_LONG,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_F[] = {
+static struct rule _type_specifier_production_F[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_FLOAT,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_G[] = {
+static struct rule _type_specifier_production_G[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_DOUBLE,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_H[] = {
+static struct rule _type_specifier_production_H[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_SIGNED,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_I[] = {
+static struct rule _type_specifier_production_I[] = {
        {
                .type = RULE_TERMINAL,
                .terminal = TOKEN_UNSIGNED,
-               .name = "type"
+               .name = "token"
        }, {
                0
        }
 };
 
-struct rule _type_specifier_production_J[] = {
+static struct rule _type_specifier_production_J[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_STRUCT_OR_UNION_SPECIFIER,
@@ -350,7 +354,7 @@ struct rule _type_specifier_production_J[] = {
        }
 };
 
-struct rule _type_specifier_production_K[] = {
+static struct rule _type_specifier_production_K[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_ENUM_SPECIFIER,
@@ -360,7 +364,7 @@ struct rule _type_specifier_production_K[] = {
        }
 };
 
-struct rule _type_specifier_production_L[] = {
+static struct rule _type_specifier_production_L[] = {
        {
                .type = RULE_NONTERMINAL,
                .nonterminal = SYNTAX_NODE_TYPEDEF_NAME,
@@ -370,7 +374,7 @@ struct rule _type_specifier_production_L[] = {
        }
 };
 
-struct rule **_type_specifier_productions = {
+static struct rule *_type_specifier_productions[] = {
        _type_specifier_production_A,
        _type_specifier_production_B,
        _type_specifier_production_C,
@@ -386,7 +390,641 @@ struct rule **_type_specifier_productions = {
        NULL
 };
 
-struct syntax_node_descriptor _node_descriptors[] = {
+static struct rule _type_qualifier_production_A[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_CONST,
+               .name = "token"
+       }, {
+               0
+       }
+};
+
+static struct rule _type_qualifier_production_B[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_VOLATILE,
+               .name = "token"
+       }, {
+               0
+       }
+};
+
+static struct rule *_type_qualifier_productions[] = {
+       _type_qualifier_production_A,
+       _type_qualifier_production_B,
+       NULL
+};
+
+static struct rule _struct_or_union_specifier_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_OR_UNION,
+               .name = "struct-or-union"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "identifier"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_LBRACE,
+               .name = "lbrace"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATION_LIST,
+               .name = "struct-declaration-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_RBRACE,
+               .name = "rbrace"
+       }, {
+               0
+       }
+};
+
+static struct rule _struct_or_union_specifier_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_OR_UNION,
+               .name = "struct-or-union"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .name = "identifier"
+       }, {
+               0
+       }
+};
+
+static struct rule *_struct_or_union_specifier_productions[] = {
+       _struct_or_union_specifier_production_A,
+       _struct_or_union_specifier_production_B,
+       NULL
+};
+
+static struct rule _struct_or_union_production_A[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_STRUCT,
+               .name = "token"
+       }, {
+               0
+       }
+};
+
+static struct rule _struct_or_union_production_B[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_UNION,
+               .name = "token"
+       }, {
+               0
+       }
+};
+
+static struct rule *_struct_or_union_productions[] = {
+       _struct_or_union_production_A,
+       _struct_or_union_production_B,
+       NULL
+};
+
+static struct rule _struct_declaration_list_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATION,
+               .name = "struct-declaration"
+       }, {
+               0
+       }
+};
+
+static struct rule _struct_declaration_list_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATION_LIST,
+               .name = "struct-declaration-list"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATION,
+               .name = "struct-declaration"
+       }, {
+               0
+       }
+};
+
+static struct rule *_struct_declaration_list_productions[] = {
+       _struct_declaration_list_production_A,
+       _struct_declaration_list_production_B,
+       NULL
+};
+
+static struct rule _init_declarator_list_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_INIT_DECLARATOR,
+               .name = "init-declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule _init_declarator_list_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_INIT_DECLARATOR_LIST,
+               .name = "init-declarator-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_COMMA,
+               .name = "comma"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_INIT_DECLARATOR,
+               .name = "init-declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule *_init_declarator_list_productions[] = {
+       _init_declarator_list_production_A,
+       _init_declarator_list_production_B,
+       NULL
+};
+
+static struct rule _init_declarator_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DECLARATOR,
+               .name = "declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule _init_declarator_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DECLARATOR,
+               .name = "declarator"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_EQ,
+               .name = "eq"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_INITIALIZER,
+               .name = "initializer"
+       }, {
+               0
+       }
+};
+
+static struct rule *_init_declarator_productions[] = {
+       _init_declarator_production_A,
+       _init_declarator_production_B,
+       NULL
+};
+
+static struct rule _struct_declaration_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_SPECIFIER_QUALIFIER_LIST,
+               .name = "specifier-qualifier-list"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATOR_LIST,
+               .name = "struct-declarator-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_SEMICOLON,
+               .name = "semicolon"
+       }, {
+               0
+       }
+};
+
+static struct rule *_struct_declaration_productions[] = {
+       _struct_declaration_production_A,
+       NULL
+};
+
+static struct rule _specifier_qualifier_list_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_SPECIFIER,
+               .name = "type-specifier"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_SPECIFIER_QUALIFIER_LIST,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "specifier-qualifier-list"
+       }, {
+               0
+       }
+};
+
+static struct rule _specifier_qualifier_list_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER,
+               .name = "type-qualifier"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_SPECIFIER_QUALIFIER_LIST,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "specifier-qualifier-list"
+       }, {
+               0
+       }
+};
+
+static struct rule *_specifier_qualifier_list_productions[] = {
+       _specifier_qualifier_list_production_A,
+       _specifier_qualifier_list_production_B,
+       NULL
+};
+
+static struct rule _struct_declarator_list_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATOR,
+               .name = "struct-declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule _struct_declarator_list_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATOR_LIST,
+               .name = "struct-declarator-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_COMMA,
+               .name = "comma"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_STRUCT_DECLARATOR,
+               .name = "struct-declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule *_struct_declarator_list_productions[] = {
+       _struct_declarator_list_production_A,
+       _struct_declarator_list_production_B,
+       NULL
+};
+
+static struct rule _struct_declarator_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DECLARATOR,
+               .name = "declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule _struct_declarator_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DECLARATOR,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "declarator"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_COLON,
+               .name = "colon"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_CONSTANT_EXPRESSION,
+               .name = "constant-expression"
+       }, {
+               0
+       }
+};
+
+static struct rule *_struct_declarator_productions[] = {
+       _struct_declarator_production_A,
+       _struct_declarator_production_B,
+       NULL
+};
+
+static struct rule _enum_specifier_production_A[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_ENUM,
+               .name = "token"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "identifier"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_LBRACE,
+               .name = "lbrace"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_ENUMERATOR_LIST,
+               .name = "enumerator-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_RBRACE,
+               .name = "rbrace"
+       }, {
+               0
+       }
+};
+
+static struct rule _enum_specifier_production_B[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_ENUM,
+               .name = "token"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .name = "identifier"
+       }, {
+               0
+       }
+};
+
+static struct rule *_enum_specifier_productions[] = {
+       _enum_specifier_production_A,
+       _enum_specifier_production_B,
+       NULL
+};
+
+static struct rule _enumerator_list_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .name = "identifier"
+       }, {
+               0
+       }
+};
+
+static struct rule _enumerator_list_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_ENUMERATOR_LIST,
+               .name = "enumerator-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_COMMA,
+               .name = "comma"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_ENUMERATOR,
+               .name = "enumerator"
+       }, {
+               0
+       }
+};
+
+static struct rule *_enumerator_list_productions[] = {
+       _enumerator_list_production_A,
+       _enumerator_list_production_B,
+       NULL
+};
+
+static struct rule _enumerator_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .name = "identifier"
+       }, {
+               0
+       }
+};
+
+static struct rule _enumerator_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .name = "identifier"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_EQ,
+               .name = "eq"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_CONSTANT_EXPRESSION
+       }, {
+               0
+       }
+};
+
+static struct rule *_enumerator_productions[] = {
+       _enumerator_production_A,
+       _enumerator_production_B,
+       NULL
+};
+
+static struct rule _declarator_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_POINTER,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "pointer"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DIRECT_DECLARATOR,
+               .name = "direct-declarator"
+       }, {
+               0
+       }
+};
+
+static struct rule *_declarator_productions[] = {
+       _declarator_production_A,
+       NULL
+};
+
+static struct rule _direct_declarator_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER,
+               .name = "identifier"
+       }, {
+               0
+       }
+};
+
+static struct rule _direct_declarator_production_B[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_LPAREN,
+               .name = "lparen"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DECLARATOR,
+               .name = "declarator"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_RPAREN,
+               .name = "rparen"
+       }, {
+               0
+       }
+};
+
+static struct rule _direct_declarator_production_C[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DIRECT_DECLARATOR,
+               .name = "direct-declarator"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_LBRACKET,
+               .name = "lbracket"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_CONSTANT_EXPRESSION,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "constant-expression"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_RBRACKET,
+               .name = "rbracket"
+       }, {
+               0
+       }
+};
+
+static struct rule _direct_declarator_production_D[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DIRECT_DECLARATOR,
+               .name = "direct-declarator"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_LPAREN,
+               .name = "lparen"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_PARAMETER_TYPE_LIST,
+               .name = "parameter-type-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_RPAREN,
+               .name = "rparen"
+       }, {
+               0
+       }
+};
+
+static struct rule _direct_declarator_production_E[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_DIRECT_DECLARATOR,
+               .name = "direct-declarator"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_LPAREN,
+               .name = "lparen"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_IDENTIFIER_LIST,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "identifier-list"
+       }, {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_RPAREN,
+               .name = "rparen"
+       }, {
+               0
+       }
+};
+
+static struct rule *_direct_declarator_productions[] = {
+       _direct_declarator_production_A,
+       _direct_declarator_production_B,
+       _direct_declarator_production_C,
+       _direct_declarator_production_D,
+       _direct_declarator_production_E,
+       NULL
+};
+
+static struct rule _pointer_production_A[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_MUL,
+               .name = "token"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER_LIST,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "type-qualifier-list"
+       }, {
+               0
+       }
+};
+
+static struct rule _pointer_production_B[] = {
+       {
+               .type = RULE_TERMINAL,
+               .terminal = TOKEN_MUL,
+               .name = "token"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER_LIST,
+               .flags = RULE_FLAG_OPTIONAL,
+               .name = "type-qualifier-list"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_POINTER,
+               .name = "pointer"
+       }, {
+               0
+       }
+};
+
+static struct rule *_pointer_productions[] = {
+       _pointer_production_A,
+       _pointer_production_B,
+       NULL
+};
+
+static struct rule _type_qualifier_list_production_A[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER,
+               .name = "type-qualifier"
+       }, {
+               0
+       }
+};
+
+static struct rule _type_qualifier_list_production_B[] = {
+       {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER_LIST,
+               .name = "type-qualifier-list"
+       }, {
+               .type = RULE_NONTERMINAL,
+               .nonterminal = SYNTAX_NODE_TYPE_QUALIFIER,
+               .name = "type-qualifier"
+       }, {
+               0
+       }
+};
+
+static struct rule *_type_qualifier_list_productions[] = {
+       _type_qualifier_list_production_A,
+       _type_qualifier_list_production_B,
+       NULL
+};
+
+static struct syntax_node_descriptor _node_descriptors[] = {
        /* order needs to be in sync with syntax_node_type_t */
        {
                .type = SYNTAX_NODE_INVALID,
@@ -394,311 +1032,318 @@ struct syntax_node_descriptor _node_descriptors[] = {
                .parse = NULL
        }, {
                .type = SYNTAX_NODE_TRANSLATION_UNIT,
-               .productions = _translation_unit_productions,
-               .parse = translation_unit_parse
+               .productions = _translation_unit_productions
        }, {
                .type = SYNTAX_NODE_EXTERNAL_DECLARATION,
-               .productions = _external_declaration_productions,
-               .parse = external_declaration_parse
+               .productions = _external_declaration_productions
        }, {
                .type = SYNTAX_NODE_FUNCTION_DEFINITION,
-               .productions = _function_definition_productions,
-               .parse = function_definition_parse
+               .productions = _function_definition_productions
        }, {
                .type = SYNTAX_NODE_DECLARATION,
-               .productions = _declaration_productions,
-               .parse = declaration_parse
+               .productions = _declaration_productions
        }, {
                .type = SYNTAX_NODE_DECLARATION_LIST,
-               .productions = _declaration_list_productions,
-               .parse = declaration_list_parse
+               .productions = _declaration_list_productions
        }, {
                .type = SYNTAX_NODE_DECLARATION_SPECIFIERS,
-               .productions = _declaration_specifiers_productions,
-               .parse = declaration_specifiers_parse
+               .productions = _declaration_specifiers_productions
        }, {
                .type = SYNTAX_NODE_STORAGE_CLASS_SPECIFIER,
-               .productions = _storage_class_specifier_productions,
-               .parse = storage_class_specifier_parse
+               .productions = _storage_class_specifier_productions
        }, {
                .type = SYNTAX_NODE_TYPE_SPECIFIER,
-               .productions = _type_specifier_productions,
-               .parse = type_specifier_parse
+               .productions = _type_specifier_productions
        }, {
                .type = SYNTAX_NODE_TYPE_QUALIFIER,
-               .productions = _type_qualifier_productions,
-               .parse = type_qualifier_parse
+               .productions = _type_qualifier_productions
        }, {
                .type = SYNTAX_NODE_STRUCT_OR_UNION_SPECIFIER,
-               .productions = _struct_or_union_specifier_productions,
-               .parse = struct_or_union_specifier_parse
+               .productions = _struct_or_union_specifier_productions
        }, {
                .type = SYNTAX_NODE_STRUCT_OR_UNION,
-               .productions = _struct_or_union_productions,
-               .parse = struct_or_union_parse
+               .productions = _struct_or_union_productions
        }, {
                .type = SYNTAX_NODE_STRUCT_DECLARATION_LIST,
-               .productions = _struct_declaration_list_productions,
-               .parse = struct_declaration_list_parse
+               .productions = _struct_declaration_list_productions
        }, {
                .type = SYNTAX_NODE_INIT_DECLARATOR_LIST,
-               .productions = _init_declarator_list_productions,
-               .parse = init_declarator_list_parse
+               .productions = _init_declarator_list_productions
        }, {
                .type = SYNTAX_NODE_INIT_DECLARATOR,
-               .productions = _init_declarator_productions,
-               .parse = init_declarator_parse
+               .productions = _init_declarator_productions
        }, {
                .type = SYNTAX_NODE_STRUCT_DECLARATION,
-               .productions = _struct_declaration_productions,
-               .parse = struct_declaration_parse
+               .productions = _struct_declaration_productions
        }, {
                .type = SYNTAX_NODE_SPECIFIER_QUALIFIER_LIST,
-               .productions = _specifier_qualifier_list_productions,
-               .parse = specifier_qualifier_list_parse
+               .productions = _specifier_qualifier_list_productions
        }, {
                .type = SYNTAX_NODE_STRUCT_DECLARATOR_LIST,
-               .productions = _struct_declarator_list_productions,
-               .parse = struct_declarator_list_parse
+               .productions = _struct_declarator_list_productions
        }, {
                .type = SYNTAX_NODE_STRUCT_DECLARATOR,
-               .productions = _struct_declarator_productions,
-               .parse = struct_declarator_parse
+               .productions = _struct_declarator_productions
        }, {
                .type = SYNTAX_NODE_ENUM_SPECIFIER,
-               .productions = _enum_specifier_productions,
-               .parse = enum_specifier_parse
+               .productions = _enum_specifier_productions
        }, {
                .type = SYNTAX_NODE_ENUMERATOR_LIST,
-               .productions = _enumerator_list_productions,
-               .parse = enumerator_list_parse
+               .productions = _enumerator_list_productions
        }, {
                .type = SYNTAX_NODE_ENUMERATOR,
-               .productions = _enumerator_productions,
-               .parse = enumerator_parse
+               .productions = _enumerator_productions
        }, {
                .type = SYNTAX_NODE_DECLARATOR,
-               .productions = _declarator_productions,
-               .parse = declarator_parse
+               .productions = _declarator_productions
        }, {
                .type = SYNTAX_NODE_DIRECT_DECLARATOR,
-               .productions = _direct_declarator_productions,
-               .parse = direct_declarator_parse
+               .productions = _direct_declarator_productions
        }, {
                .type = SYNTAX_NODE_POINTER,
-               .productions = _pointer_productions,
-               .parse = pointer_parse
+               .productions = _pointer_productions
        }, {
                .type = SYNTAX_NODE_TYPE_QUALIFIER_LIST,
-               .productions = _type_qualifier_list_productions,
-               .parse = type_qualifier_list_parse
+               .productions = _type_qualifier_list_productions
        }, {
                .type = SYNTAX_NODE_PARAMETER_TYPE_LIST,
-               .productions = _parameter_type_list_productions,
-               .parse = parameter_type_list_parse
+               .productions = _parameter_type_list_productions
        }, {
                .type = SYNTAX_NODE_PARAMETER_LIST,
-               .productions = _parameter_list_productions,
-               .parse = parameter_list_parse
+               .productions = _parameter_list_productions
        }, {
                .type = SYNTAX_NODE_PARAMETER_DECLARATION,
-               .productions = _parameter_declaration_productions,
-               .parse = parameter_declaration_parse
+               .productions = _parameter_declaration_productions
+       }, {
+               .type = SYNTAX_NODE_IDENTIFIER,
+               .parse = identifier_parse
        }, {
                .type = SYNTAX_NODE_IDENTIFIER_LIST,
-               .productions = _identifier_list_productions,
-               .parse = identifier_list_parse
+               .productions = _identifier_list_productions
        }, {
                .type = SYNTAX_NODE_INITIALIZER,
-               .productions = _initializer_productions,
-               .parse = initializer_parse
+               .productions = _initializer_productions
        }, {
                .type = SYNTAX_NODE_INITIALIZER_LIST,
-               .productions = _initializer_list_productions,
-               .parse = initializer_list_parse
+               .productions = _initializer_list_productions
        }, {
                .type = SYNTAX_NODE_TYPE_NAME,
-               .productions = _type_name_productions,
-               .parse = type_name_parse
+               .productions = _type_name_productions
        }, {
                .type = SYNTAX_NODE_ABSTRACT_DECLARATOR,
-               .productions = _abstract_declarator_productions,
-               .parse = abstract_declarator_parse
+               .productions = _abstract_declarator_productions
        }, {
                .type = SYNTAX_NODE_DIRECT_ABSTRACT_DECLARATOR,
-               .productions = _direct_abstract_declarator_productions,
-               .parse = direct_abstract_declarator_parse
+               .productions = _direct_abstract_declarator_productions
        }, {
                .type = SYNTAX_NODE_TYPEDEF_NAME,
-               .productions = _typedef_name_productions,
-               .parse = typedef_name_parse
+               .productions = _typedef_name_productions
        }, {
                .type = SYNTAX_NODE_STATEMENT,
-               .productions = _statement_productions,
-               .parse = statement_parse
+               .productions = _statement_productions
        }, {
                .type = SYNTAX_NODE_LABELED_STATEMENT,
-               .productions = _labeled_statement_productions,
-               .parse = labeled_statement_parse
+               .productions = _labeled_statement_productions
        }, {
                .type = SYNTAX_NODE_EXPRESSION_STATEMENT,
-               .productions = _expression_statement_productions,
-               .parse = expression_statement_parse
+               .productions = _expression_statement_productions
        }, {
                .type = SYNTAX_NODE_COMPOUND_STATEMENT,
-               .productions = _compound_statement_productions,
-               .parse = compound_statement_parse
+               .productions = _compound_statement_productions
        }, {
                .type = SYNTAX_NODE_STATEMENT_LIST,
-               .productions = _statement_list_productions,
-               .parse = statement_list_parse
+               .productions = _statement_list_productions
        }, {
                .type = SYNTAX_NODE_SELECTION_STATEMENT,
-               .productions = _selection_statement_productions,
-               .parse = selection_statement_parse
+               .productions = _selection_statement_productions
        }, {
                .type = SYNTAX_NODE_IF_STATEMENT,
-               .productions = _if_statement_productions,
-               .parse = if_statement_parse
+               .productions = _if_statement_productions
        }, {
                .type = SYNTAX_NODE_IF_ELSE_STATEMENT,
-               .productions = _if_else_statement_productions,
-               .parse = if_else_statement_parse
+               .productions = _if_else_statement_productions
        }, {
                .type = SYNTAX_NODE_SWITCH_STATEMENT,
-               .productions = _switch_statement_productions,
-               .parse = switch_statement_parse
+               .productions = _switch_statement_productions
        }, {
                .type = SYNTAX_NODE_ITERATION_STATEMENT,
-               .productions = _iteration_statement_productions,
-               .parse = iteration_statement_parse
+               .productions = _iteration_statement_productions
        }, {
                .type = SYNTAX_NODE_WHILE_STATEMENT,
-               .productions = _while_statement_productions,
-               .parse = while_statement_parse
+               .productions = _while_statement_productions
        }, {
                .type = SYNTAX_NODE_DO_WHILE_STATEMENT,
-               .productions = _do_while_statement_productions,
-               .parse = do_while_statement_parse
+               .productions = _do_while_statement_productions
        }, {
                .type = SYNTAX_NODE_FOR_STATEMENT,
-               .productions = _for_statement_productions,
-               .parse = for_statement_parse
+               .productions = _for_statement_productions
        }, {
                .type = SYNTAX_NODE_JUMP_STATEMENT,
-               .productions = _jump_statement_productions,
-               .parse = jump_statement_parse
+               .productions = _jump_statement_productions
        }, {
                .type = SYNTAX_NODE_GOTO_STATEMENT,
-               .productions = _goto_statement_productions,
-               .parse = goto_statement_parse
+               .productions = _goto_statement_productions
        }, {
                .type = SYNTAX_NODE_CONTINUE_STATEMENT,
-               .productions = _continue_statement_productions,
-               .parse = continue_statement_parse
+               .productions = _continue_statement_productions
        }, {
                .type = SYNTAX_NODE_BREAK_STATEMENT,
-               .productions = _break_statement_productions,
-               .parse = break_statement_parse
+               .productions = _break_statement_productions
        }, {
                .type = SYNTAX_NODE_RETURN_STATEMENT,
-               .productions = _return_statement_productions,
-               .parse = return_statement_parse
+               .productions = _return_statement_productions
        }, {
                .type = SYNTAX_NODE_EXPRESSION,
-               .productions = _expression_productions,
-               .parse = expression_parse
+               .productions = _expression_productions
        }, {
                .type = SYNTAX_NODE_ASSIGNMENT_EXPRESSION,
-               .productions = _assignement_expression_productions,
-               .parse = assignement_expression_parse
+               .productions = _assignement_expression_productions
        }, {
                .type = SYNTAX_NODE_ASSIGNMENT_OPERATOR,
-               .productions = _assignment_operator_productions,
-               .parse = assignment_operator_parse
+               .productions = _assignment_operator_productions
        }, {
                .type = SYNTAX_NODE_CONDITIONAL_EXPRESSION,
-               .productions = _conditional_expression_productions,
-               .parse = conditional_expression_parse
+               .productions = _conditional_expression_productions
        }, {
                .type = SYNTAX_NODE_CONSTANT_EXPRESSION,
-               .productions = _constant_expression_productions,
-               .parse = constant_expression_parse
+               .productions = _constant_expression_productions
        }, {
                .type = SYNTAX_NODE_LOGICAL_OR_EXPRESSION,
-               .productions = _logical_or_expression_productions,
-               .parse = logical_or_expression_parse
+               .productions = _logical_or_expression_productions
        }, {
                .type = SYNTAX_NODE_LOGICAL_AND_EXPRESSION,
-               .productions = _logical_and_expression_productions,
-               .parse = logical_and_expression_parse
+               .productions = _logical_and_expression_productions
        }, {
                .type = SYNTAX_NODE_INCLUSIVE_OR_EXPRESSION,
-               .productions = _inclusive_or_expression_productions,
-               .parse = inclusive_or_expression_parse
+               .productions = _inclusive_or_expression_productions
        }, {
                .type = SYNTAX_NODE_EXCLUSIVE_OR_EXPRESSION,
-               .productions = _exclusive_or_expression_productions,
-               .parse = exclusive_or_expression_parse
+               .productions = _exclusive_or_expression_productions
        }, {
                .type = SYNTAX_NODE_AND_EXPRESSION,
-               .productions = _and_expression_productions,
-               .parse = and_expression_parse
+               .productions = _and_expression_productions
        }, {
                .type = SYNTAX_NODE_EQUALITY_EXPRESSION,
-               .productions = _equality_expression_productions,
-               .parse = equality_expression_parse
+               .productions = _equality_expression_productions
        }, {
                .type = SYNTAX_NODE_RELATIONAL_EXPRESSION,
-               .productions = _relational_expression_productions,
-               .parse = relational_expression_parse
+               .productions = _relational_expression_productions
        }, {
                .type = SYNTAX_NODE_SHIFT_EXPRESSION,
-               .productions = _shift_expression_productions,
-               .parse = shift_expression_parse
+               .productions = _shift_expression_productions
        }, {
                .type = SYNTAX_NODE_ADDITIVE_EXPRESSION,
-               .productions = _additive_expression_productions,
-               .parse = additive_expression_parse
+               .productions = _additive_expression_productions
        }, {
                .type = SYNTAX_NODE_MULTIPLICATIVE_EXRESSION,
-               .productions = _multiplicative_expression_productions,
-               .parse = multiplicative_expression_parse
+               .productions = _multiplicative_expression_productions
        }, {
                .type = SYNTAX_NODE_CAST_EXPRESSION,
-               .productions = _cast_expression_productions,
-               .parse = cast_expression_parse
+               .productions = _cast_expression_productions
        }, {
                .type = SYNTAX_NODE_UNARY_EXPRESSION,
-               .productions = _unary_expression_productions,
-               .parse = unary_expression_parse
+               .productions = _unary_expression_productions
        }, {
                .type = SYNTAX_NODE_UNARY_OPERATOR,
-               .productions = _unary_operator_productions,
-               .parse = unary_operator_parse
+               .productions = _unary_operator_productions
        }, {
                .type = SYNTAX_NODE_POSTFIX_EXPRESSION,
-               .productions = _postfix_expression_productions,
-               .parse = postfix_expression_parse
+               .productions = _postfix_expression_productions
        }, {
                .type = SYNTAX_NODE_PRIMARY_EXPRESSION,
-               .productions = _primary_expression_productions,
-               .parse = primary_expression_parse
+               .productions = _primary_expression_productions
        }, {
                .type = SYNTAX_NODE_ARGUMENT_EXPRESSION_LIST,
-               .productions = _argument_expression_list_productions,
-               .parse = argument_expression_list_parse
+               .productions = _argument_expression_list_productions
        }, {
                .type = SYNTAX_NODE_CONSTANT,
-               .productions = _constant_productions,
-               .parse = constant_parse
+               .productions = _constant_productions
        }
 };
 
-struct syntax_node* syntax_node_parse(syntax_node_type_t type)
+struct syntax_node *syntax_node_parse_production(syntax_node_type_t type, int prod)
+{
+       struct syntax_node *node;
+       struct rule *rule;
+       int match;
+       int origin;
+
+       node = syntax_node_new();
+
+       if(!node) {
+               return(NULL);
+       }
+
+       origin = lex_getpos();
+
+       for(rule = _node_descriptors[type].productions[prod], match = 1;
+           rule && match;
+           rule++) {
+               int pos;
+
+               pos = lex_getpos();
+
+               if(rule->type == RULE_TERMINAL) {
+                       struct token *tok;
+                       int pos;
+
+                       pos = lex_getpos();
+                       tok = lex_gettoken();
+
+                       if(tok && tok->type == rule->terminal) {
+                               syntax_node_set_property(node, rule->name, tok);
+                               continue;
+                       }
+
+                       match = 0;
+               } else {
+                       struct syntax_node *nt;
+
+                       nt = syntax_node_parse(rule->nonterminal);
+
+                       if(nt || rule->flags & RULE_FLAG_OPTIONAL) {
+                               /* will be NULL if optional and missing */
+                               syntax_node_set_child(node, rule->name, nt);
+                               continue;
+                       }
+
+                       match = 0;
+               }
+       }
+
+       if(!match) {
+               lex_setpos(origin);
+               syntax_node_free(node);
+               node = NULL;
+       }
+
+       return(node);
+}
+
+struct syntax_node *syntax_node_parse_generic(syntax_node_type_t type)
+{
+       struct syntax_node *ret_val;
+       int prod;
+
+       for(prod = 0; _node_descriptors[type].productions[prod]; prod++) {
+               ret_val = syntax_node_parse_production(type, prod);
+
+               if(ret_val) {
+                       break;
+               }
+       }
+
+       return(ret_val);
+}
+
+struct syntax_node *syntax_node_parse(syntax_node_type_t type)
 {
        if(type > 0 && type < SYNTAX_NODE_MAX) {
-               return(_node_descriptors[type].parse());
+               if(_node_descriptors[type].parse) {
+                       return(_node_descriptors[type].parse());
+               }
+
+               return(syntax_node_parse_generic(type));
        }
 
        return(NULL);
@@ -3300,3 +3945,53 @@ void jump_statement_debug(struct jump_statement *stmt)
 
        return;
 }
+
+static int _syntax_node_debug(struct syntax_node *node)
+{
+       return(-ENOSYS);
+}
+
+struct syntax_node *syntax_node_new(void)
+{
+       struct syntax_node *node;
+
+       node = malloc(sizeof(*node));
+
+       if(node) {
+               node->children = assoc_array_new();
+               node->properties = assoc_array_new();
+
+               if(node->children && node->properties) {
+                       node->debug = _syntax_node_debug;
+               } else {
+                       if(node->children) {
+                               assoc_array_free(node->children);
+                       }
+
+                       if(node->properties) {
+                               assoc_array_free(node->properties);
+                       }
+
+                       free(node);
+                       node = NULL;
+               }
+       }
+
+       return(node);
+}
+
+void syntax_node_free(struct syntax_node *node)
+{
+       if(node->children) {
+               /* assoc_array_foreach(node->children, syntax_node_free); */
+               assoc_array_free(node->children);
+       }
+
+       if(node->properties) {
+               assoc_array_free(node->properties);
+       }
+
+       memset(node, 0, sizeof(*node));
+       free(node);
+       return;
+}
index aa7fea950195a830a9b38ce2b87ec4a75f200e31..272cedf960a50f4f37db4ae727e2b631deaf5833 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef GRAMMAR_H
 #define GRAMMAR_H
 
+#include "assoc_array.h"
 #include "token.h"
 
 struct token;
@@ -35,6 +36,7 @@ typedef enum {
        SYNTAX_NODE_PARAMETER_TYPE_LIST,
        SYNTAX_NODE_PARAMETER_LIST,
        SYNTAX_NODE_PARAMETER_DECLARATION,
+       SYNTAX_NODE_IDENTIFIER,
        SYNTAX_NODE_IDENTIFIER_LIST,
        SYNTAX_NODE_INITIALIZER,
        SYNTAX_NODE_INITIALIZER_LIST,
@@ -94,6 +96,8 @@ struct syntax_node_descriptor {
 
 struct syntax_node {
        syntax_node_type_t type;
+       struct assoc_array *children;
+       struct assoc_array *properties;
 
        int (*debug)(struct syntax_node*);
        int (*free)(struct syntax_node*);
@@ -1014,4 +1018,13 @@ void initializer_list_free(struct initializer_list*);
 
 void jump_statement_debug(struct jump_statement*);
 
+struct syntax_node *syntax_node_new(void);
+void syntax_node_free(struct syntax_node*);
+int syntax_node_set_property(struct syntax_node*, const char*, void*);
+int syntax_node_get_property(struct syntax_node*, const char*, void**);
+int syntax_node_set_child(struct syntax_node*, const char*, struct syntax_node*);
+int syntax_node_get_child(struct syntax_node*, const char*, struct syntax_node**);
+syntax_node_type_t syntax_node_get_type(struct syntax_node*);
+void syntax_node_set_type(struct syntax_node*, const syntax_node_type_t);
+
 #endif /* GRAMMAR_H */
index 2a863a6a082f89994818def6d830ebb5334f9840..1f9f22891a9ed96417d2df6f3ff69e6c9adb9eef 100644 (file)
@@ -65,5 +65,4 @@ struct iteration_statement *parse_iteration_statement(void);
 struct jump_statement *parse_jump_statement(void);
 struct statement_list *parse_statement_list(void);
 
-
 #endif /* PARSER_H */