From f4ae1b8601ca8067d4e588fca9e8d2c3ee77b38a Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 19 Jul 2024 14:34:50 -0400 Subject: [PATCH] Add position fields to AST nodes (not populated yet) - #27 --- assets/parser.c.erb | 21 +++++++++++++++++---- assets/parser.d.erb | 25 +++++++++++++++++++------ assets/parser.h.erb | 2 ++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/assets/parser.c.erb b/assets/parser.c.erb index 4915b1a..ec05d77 100644 --- a/assets/parser.c.erb +++ b/assets/parser.c.erb @@ -681,6 +681,14 @@ typedef struct <% end %> } state_value_t; +/** Common AST node structure. */ +typedef struct +{ + <%= @grammar.prefix %>position_t position; + <%= @grammar.prefix %>position_t end_position; + void * fields[]; +} ASTNode; + /** Parser shift table. */ static const shift_t parser_shift_table[] = { <% @parser.shift_table.each do |shift| %> @@ -1000,22 +1008,27 @@ size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * context) } else if (parser_reduce_table[reduce_index].n_states > 0) { - void ** node_fields = calloc(parser_reduce_table[reduce_index].rule_set_node_field_array_size, sizeof(void *)); + size_t n_fields = parser_reduce_table[reduce_index].rule_set_node_field_array_size; + ASTNode * node = (ASTNode *)malloc(sizeof(ASTNode) + n_fields * sizeof(void *)); + for (size_t i = 0; i < n_fields; i++) + { + node->fields[i] = NULL; + } if (parser_reduce_table[reduce_index].rule_set_node_field_index_map == NULL) { for (size_t i = 0; i < parser_reduce_table[reduce_index].n_states; i++) { - node_fields[i] = state_values_stack_index(&statevalues, -(int)parser_reduce_table[reduce_index].n_states + (int)i)->ast_node; + node->fields[i] = state_values_stack_index(&statevalues, -(int)parser_reduce_table[reduce_index].n_states + (int)i)->ast_node; } } else { for (size_t i = 0; i < parser_reduce_table[reduce_index].n_states; i++) { - node_fields[parser_reduce_table[reduce_index].rule_set_node_field_index_map[i]] = state_values_stack_index(&statevalues, -(int)parser_reduce_table[reduce_index].n_states + (int)i)->ast_node; + node->fields[parser_reduce_table[reduce_index].rule_set_node_field_index_map[i]] = state_values_stack_index(&statevalues, -(int)parser_reduce_table[reduce_index].n_states + (int)i)->ast_node; } } - reduced_parser_node = node_fields; + reduced_parser_node = node; } else { diff --git a/assets/parser.d.erb b/assets/parser.d.erb index a83d00c..9ec5cb0 100644 --- a/assets/parser.d.erb +++ b/assets/parser.d.erb @@ -8,6 +8,8 @@ module <%= @grammar.modulename %>; <% end %> +import core.stdc.stdlib : malloc; + /************************************************************************** * User code blocks *************************************************************************/ @@ -86,11 +88,21 @@ public struct <%= @grammar.ast_prefix %>Token<%= @grammar.ast_suffix %> <%= @grammar.prefix %>position_t end_position; } +/** Common AST node structure. */ +private struct ASTNode +{ + <%= @grammar.prefix %>position_t position; + <%= @grammar.prefix %>position_t end_position; + void *[0] fields; +} + <% @parser.rule_sets.each do |name, rule_set| %> <% next if name.start_with?("$") %> <% next if rule_set.optional? %> public struct <%= @grammar.ast_prefix %><%= name %><%= @grammar.ast_suffix %> { + <%= @grammar.prefix %>position_t position; + <%= @grammar.prefix %>position_t end_position; <% rule_set.ast_fields.each do |fields| %> union { @@ -1049,26 +1061,27 @@ public size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * cont } else if (parser_reduce_table[reduce_index].n_states > 0) { - void *[] node_fields = new void *[parser_reduce_table[reduce_index].rule_set_node_field_array_size]; - foreach (i; 0..parser_reduce_table[reduce_index].rule_set_node_field_array_size) + size_t n_fields = parser_reduce_table[reduce_index].rule_set_node_field_array_size; + ASTNode * node = cast(ASTNode *)malloc(ASTNode.sizeof + n_fields * (void *).sizeof); + foreach (i; 0..n_fields) { - node_fields[i] = null; + node.fields[i] = null; } if (parser_reduce_table[reduce_index].rule_set_node_field_index_map is null) { foreach (i; 0..parser_reduce_table[reduce_index].n_states) { - node_fields[i] = statevalues[$ - parser_reduce_table[reduce_index].n_states + i].ast_node; + node.fields[i] = statevalues[$ - parser_reduce_table[reduce_index].n_states + i].ast_node; } } else { foreach (i; 0..parser_reduce_table[reduce_index].n_states) { - node_fields[parser_reduce_table[reduce_index].rule_set_node_field_index_map[i]] = statevalues[$ - parser_reduce_table[reduce_index].n_states + i].ast_node; + node.fields[parser_reduce_table[reduce_index].rule_set_node_field_index_map[i]] = statevalues[$ - parser_reduce_table[reduce_index].n_states + i].ast_node; } } - reduced_parser_node = node_fields.ptr; + reduced_parser_node = node; } else { diff --git a/assets/parser.h.erb b/assets/parser.h.erb index 8657ef6..a7f1744 100644 --- a/assets/parser.h.erb +++ b/assets/parser.h.erb @@ -89,6 +89,8 @@ struct <%= name %>; <% next if rule_set.optional? %> typedef struct <%= @grammar.ast_prefix %><%= name %><%= @grammar.ast_suffix %> { + <%= @grammar.prefix %>position_t position; + <%= @grammar.prefix %>position_t end_position; <% rule_set.ast_fields.each do |fields| %> union {