This commit is contained in:
Josh Holtrop 2026-02-08 22:22:27 -05:00
parent cb426b4be1
commit 7122bdc2db
5 changed files with 24 additions and 21 deletions

View File

@ -974,7 +974,7 @@ size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * context)
{ {
/* Successful parse. */ /* Successful parse. */
<% if @grammar.ast %> <% if @grammar.ast %>
context->parse_result = (<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> *)state_values_stack_index(&statevalues, -1)->ast_node; context->parse_result = state_values_stack_index(&statevalues, -1)->ast_node;
<% else %> <% else %>
context->parse_result = state_values_stack_index(&statevalues, -1)->pvalue; context->parse_result = state_values_stack_index(&statevalues, -1)->pvalue;
<% end %> <% end %>
@ -1110,13 +1110,13 @@ size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * context)
* @return Parse result value. * @return Parse result value.
*/ */
<% if @grammar.ast %> <% if @grammar.ast %>
<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context) <%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> * <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context)
<% else %> <% else %>
<%= start_rule_type[1] %> <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context) <%= start_rule_type[1] %> <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context)
<% end %> <% end %>
{ {
<% if @grammar.ast %> <% if @grammar.ast %>
return context->parse_result; return (<%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> *) context->parse_result;
<% else %> <% else %>
return context->parse_result.v_<%= start_rule_type[0] %>; return context->parse_result.v_<%= start_rule_type[0] %>;
<% end %> <% end %>
@ -1184,7 +1184,7 @@ static void free_ast_node(ASTNode * node)
/** /**
* Free all AST node memory. * Free all AST node memory.
*/ */
void <%= @grammar.prefix %>free_ast(<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * ast) void <%= @grammar.prefix %>free_ast(<%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> * ast)
{ {
free_ast_node((ASTNode *)ast); free_ast_node((ASTNode *)ast);
} }

View File

@ -173,7 +173,7 @@ public struct <%= @grammar.prefix %>context_t
/** Parse result value. */ /** Parse result value. */
<% if @grammar.ast %> <% if @grammar.ast %>
<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * parse_result; void * parse_result;
<% else %> <% else %>
<%= @grammar.prefix %>value_t parse_result; <%= @grammar.prefix %>value_t parse_result;
<% end %> <% end %>
@ -1031,7 +1031,7 @@ public size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * cont
{ {
/* Successful parse. */ /* Successful parse. */
<% if @grammar.ast %> <% if @grammar.ast %>
context.parse_result = cast(<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> *)statevalues[$-1].ast_node; context.parse_result = statevalues[$-1].ast_node;
<% else %> <% else %>
context.parse_result = statevalues[$-1].pvalue; context.parse_result = statevalues[$-1].pvalue;
<% end %> <% end %>
@ -1156,13 +1156,13 @@ public size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * cont
* @return Parse result value. * @return Parse result value.
*/ */
<% if @grammar.ast %> <% if @grammar.ast %>
public <%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context) public <%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> * <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context)
<% else %> <% else %>
public <%= start_rule_type[1] %> <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context) public <%= start_rule_type[1] %> <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context)
<% end %> <% end %>
{ {
<% if @grammar.ast %> <% if @grammar.ast %>
return context.parse_result; return cast(<%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> *)context.parse_result;
<% else %> <% else %>
return context.parse_result.v_<%= start_rule_type[0] %>; return context.parse_result.v_<%= start_rule_type[0] %>;
<% end %> <% end %>

View File

@ -162,7 +162,7 @@ typedef struct
/** Parse result value. */ /** Parse result value. */
<% if @grammar.ast %> <% if @grammar.ast %>
<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * parse_result; void * parse_result;
<% else %> <% else %>
<%= @grammar.prefix %>value_t parse_result; <%= @grammar.prefix %>value_t parse_result;
<% end %> <% end %>
@ -191,9 +191,9 @@ size_t <%= @grammar.prefix %>lex(<%= @grammar.prefix %>context_t * context, <%=
size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * context); size_t <%= @grammar.prefix %>parse(<%= @grammar.prefix %>context_t * context);
<% if @grammar.ast %> <% if @grammar.ast %>
<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context); <%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> * <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context);
void <%= @grammar.prefix %>free_ast(<%= @grammar.ast_prefix %><%= @grammar.start_rule %><%= @grammar.ast_suffix %> * ast); void <%= @grammar.prefix %>free_ast(<%= @grammar.ast_prefix %><%= @grammar.start_rules[0] %><%= @grammar.ast_suffix %> * ast);
<% else %> <% else %>
<%= start_rule_type[1] %> <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context); <%= start_rule_type[1] %> <%= @grammar.prefix %>result(<%= @grammar.prefix %>context_t * context);
<% end %> <% end %>

View File

@ -71,12 +71,14 @@ class Propane
end end
tokens_by_name[token.name] = token tokens_by_name[token.name] = token
end end
# Check for user start rule. # Check for user start rules.
unless @grammar.rules.find {|rule| rule.name == @grammar.start_rule} @grammar.start_rules.each_with_index do |start_rule, i|
raise Error.new("Start rule `#{@grammar.start_rule}` not found") unless @grammar.rules.find {|rule| rule.name == start_rule}
raise Error.new("Start rule `#{start_rule}` not found")
end
# Add "real" start rule.
@grammar.rules.unshift(Rule.new("$#{start_rule}", [start_rule, "$EOF"], nil, nil, nil))
end end
# Add "real" start rule.
@grammar.rules.unshift(Rule.new("$Start", [@grammar.start_rule, "$EOF"], nil, nil, nil))
# Generate and add rules for optional components. # Generate and add rules for optional components.
generate_optional_component_rules!(tokens_by_name) generate_optional_component_rules!(tokens_by_name)
# Build rule sets. # Build rule sets.
@ -332,9 +334,9 @@ class Propane
# #
# @return [Array<String>] # @return [Array<String>]
# Start rule parser value type name and type string. # Start rule parser value type name and type string.
def start_rule_type def start_rule_type(start_rule_index = 0)
start_rule = @grammar.rules.find do |rule| start_rule = @grammar.rules.find do |rule|
rule.name == @grammar.start_rule rule.name == @grammar.start_rules[start_rule_index]
end end
[start_rule.ptypename, @grammar.ptypes[start_rule.ptypename]] [start_rule.ptypename, @grammar.ptypes[start_rule.ptypename]]
end end

View File

@ -12,7 +12,7 @@ class Propane
attr_reader :modulename attr_reader :modulename
attr_reader :patterns attr_reader :patterns
attr_reader :rules attr_reader :rules
attr_reader :start_rule attr_reader :start_rules
attr_reader :tokens attr_reader :tokens
attr_reader :code_blocks attr_reader :code_blocks
attr_reader :ptypes attr_reader :ptypes
@ -20,7 +20,7 @@ class Propane
def initialize(input) def initialize(input)
@patterns = [] @patterns = []
@start_rule = "Start" @start_rules = []
@tokens = [] @tokens = []
@rules = [] @rules = []
@code_blocks = {} @code_blocks = {}
@ -35,6 +35,7 @@ class Propane
@ast_suffix = "" @ast_suffix = ""
@free_token_node = nil @free_token_node = nil
parse_grammar! parse_grammar!
@start_rules << "Start" if @start_rules.empty?
end end
def ptype def ptype
@ -242,7 +243,7 @@ class Propane
def parse_start_statement! def parse_start_statement!
if md = consume!(/start\s+(\w+)\s*;/) if md = consume!(/start\s+(\w+)\s*;/)
@start_rule = md[1] @start_rules << md[1] unless @start_rules.include?(md[1])
end end
end end