#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,
}
};
-struct rule _translation_unit_production_B[] = {
+static struct rule _translation_unit_production_B[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_TRANSLATION_UNIT,
}
};
-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,
}
};
-struct rule _external_declaration_production_B[] = {
+static struct rule _external_declaration_production_B[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_DECLARATION,
}
};
-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,
}
};
-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,
}
};
-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,
}
};
-struct rule _declaration_list_production_B[] = {
+static struct rule _declaration_list_production_B[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_DECLARATION_LIST,
}
};
-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,
}
};
-struct rule _declaration_specifiers_production_B[] = {
+static struct rule _declaration_specifiers_production_B[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_TYPE_SPECIFIER,
}
};
-struct rule _declaration_specifiers_production_C[] = {
+static struct rule _declaration_specifiers_production_C[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_TYPE_QUALIFIER,
}
};
-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,
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,
}
};
-struct rule _type_specifier_production_K[] = {
+static struct rule _type_specifier_production_K[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_ENUM_SPECIFIER,
}
};
-struct rule _type_specifier_production_L[] = {
+static struct rule _type_specifier_production_L[] = {
{
.type = RULE_NONTERMINAL,
.nonterminal = SYNTAX_NODE_TYPEDEF_NAME,
}
};
-struct rule **_type_specifier_productions = {
+static struct rule *_type_specifier_productions[] = {
_type_specifier_production_A,
_type_specifier_production_B,
_type_specifier_production_C,
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,
.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);
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;
+}