Skip to content

Commit

Permalink
Refactor for parameterizing_rule_resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
ydah committed Apr 17, 2024
1 parent 4d285d5 commit 514e61c
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 31 deletions.
12 changes: 8 additions & 4 deletions lib/lrama/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def initialize(rule_counter)
append_special_symbols
end

def create_rule_builder(rule_counter, midrule_action_counter)
RuleBuilder.new(rule_counter, midrule_action_counter, @parameterizing_rule_resolver)
end

def add_percent_code(id:, code:)
@percent_codes << PercentCode.new(id.s_value, code.s_value)
end
Expand Down Expand Up @@ -256,7 +260,7 @@ def compute_first_set

def setup_rules
@rule_builders.each do |builder|
builder.setup_rules(@parameterizing_rule_resolver)
builder.setup_rules
end
end

Expand Down Expand Up @@ -291,10 +295,10 @@ def append_special_symbols
end

def resolve_inline_rules
while @rule_builders.any? {|r| r.has_inline_rules?(@parameterizing_rule_resolver) } do
while @rule_builders.any? {|r| r.has_inline_rules? } do
@rule_builders.map! do |builder|
if builder.has_inline_rules?(@parameterizing_rule_resolver)
builder.resolve_inline_rules(@parameterizing_rule_resolver)
if builder.has_inline_rules?
builder.resolve_inline_rules
else
builder
end
Expand Down
33 changes: 17 additions & 16 deletions lib/lrama/grammar/rule_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ class RuleBuilder
attr_accessor :lhs, :line
attr_reader :lhs_tag, :rhs, :user_code, :precedence_sym

def initialize(rule_counter, midrule_action_counter, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false)
def initialize(rule_counter, midrule_action_counter, parameterizing_rule_resolver, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false)
@rule_counter = rule_counter
@midrule_action_counter = midrule_action_counter
@parameterizing_rule_resolver = parameterizing_rule_resolver
@position_in_original_rule_rhs = position_in_original_rule_rhs
@skip_preprocess_references = skip_preprocess_references

Expand Down Expand Up @@ -53,26 +54,26 @@ def complete_input
freeze_rhs
end

def setup_rules(parameterizing_rule_resolver)
def setup_rules
preprocess_references unless @skip_preprocess_references
process_rhs(parameterizing_rule_resolver)
process_rhs
build_rules
end

def rules
@parameterizing_rules + @midrule_action_rules + @rules
end

def has_inline_rules?(parameterizing_rule_resolver)
rhs.any? { |token| parameterizing_rule_resolver.find_inline(token) }
def has_inline_rules?
rhs.any? { |token| @parameterizing_rule_resolver.find_inline(token) }
end

def resolve_inline_rules(parameterizing_rule_resolver)
def resolve_inline_rules
resolved_builders = []
rhs.each_with_index do |token, i|
if inline_rule = parameterizing_rule_resolver.find_inline(token)
if inline_rule = @parameterizing_rule_resolver.find_inline(token)
inline_rule.rhs_list.each do |inline_rhs|
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: lhs_tag)
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: lhs_tag)
resolve_inline_rhs(rule_builder, inline_rhs, i)
rule_builder.lhs = lhs
rule_builder.line = line
Expand Down Expand Up @@ -117,7 +118,7 @@ def build_rules

# rhs is a mixture of variety type of tokens like `Ident`, `InstantiateRule`, `UserCode` and so on.
# `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`.
def process_rhs(parameterizing_rule_resolver)
def process_rhs
return if @replaced_rhs

@replaced_rhs = []
Expand All @@ -129,26 +130,26 @@ def process_rhs(parameterizing_rule_resolver)
when Lrama::Lexer::Token::Ident
@replaced_rhs << token
when Lrama::Lexer::Token::InstantiateRule
parameterizing_rule = parameterizing_rule_resolver.find_rule(token)
parameterizing_rule = @parameterizing_rule_resolver.find_rule(token)
raise "Unexpected token. #{token}" unless parameterizing_rule

bindings = Binding.new(parameterizing_rule, token.args)
lhs_s_value = lhs_s_value(token, bindings)
if (created_lhs = parameterizing_rule_resolver.created_lhs(lhs_s_value))
if (created_lhs = @parameterizing_rule_resolver.created_lhs(lhs_s_value))
@replaced_rhs << created_lhs
else
lhs_token = Lrama::Lexer::Token::Ident.new(s_value: lhs_s_value, location: token.location)
@replaced_rhs << lhs_token
parameterizing_rule_resolver.created_lhs_list << lhs_token
@parameterizing_rule_resolver.created_lhs_list << lhs_token
parameterizing_rule.rhs_list.each do |r|
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag, skip_preprocess_references: true)
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: token.lhs_tag, skip_preprocess_references: true)
rule_builder.lhs = lhs_token
r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
rule_builder.line = line
rule_builder.precedence_sym = r.precedence_sym
rule_builder.user_code = r.user_code
rule_builder.complete_input
rule_builder.setup_rules(parameterizing_rule_resolver)
rule_builder.setup_rules
@rule_builders_for_parameterizing_rules << rule_builder
end
end
Expand All @@ -158,11 +159,11 @@ def process_rhs(parameterizing_rule_resolver)
new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s)
@replaced_rhs << new_token

rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag: tag, skip_preprocess_references: true)
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, i, lhs_tag: tag, skip_preprocess_references: true)
rule_builder.lhs = new_token
rule_builder.user_code = token
rule_builder.complete_input
rule_builder.setup_rules(parameterizing_rule_resolver)
rule_builder.setup_rules

@rule_builders_for_derived_rules << rule_builder
else
Expand Down
4 changes: 2 additions & 2 deletions lib/lrama/parser.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,12 @@ rule
rhs: /* empty */
{
reset_precs
result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter)
result = @grammar.create_rule_builder(@rule_counter, @midrule_action_counter)
}
| "%empty"
{
reset_precs
result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter)
result = @grammar.create_rule_builder(@rule_counter, @midrule_action_counter)
}
| rhs symbol named_ref_opt
{
Expand Down
9 changes: 5 additions & 4 deletions sig/lrama/grammar/rule_builder.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Lrama

@rule_counter: Counter
@midrule_action_counter: Counter
@parameterizing_rule_resolver: Grammar::ParameterizingRule::Resolver
@position_in_original_rule_rhs: Integer?
@skip_preprocess_references: bool
@user_code: Lexer::Token::UserCode?
Expand All @@ -20,22 +21,22 @@ module Lrama
@parameterizing_rules: Array[Rule]
@midrule_action_rules: Array[Rule]

def initialize: (Counter rule_counter, Counter midrule_action_counter, ?Integer position_in_original_rule_rhs, ?lhs_tag: Lexer::Token::Tag?, ?skip_preprocess_references: bool) -> void
def initialize: (Counter rule_counter, Counter midrule_action_counter, Grammar::ParameterizingRule::Resolver parameterizing_rule_resolver, ?Integer position_in_original_rule_rhs, ?lhs_tag: Lexer::Token::Tag?, ?skip_preprocess_references: bool) -> void
def add_rhs: (Lexer::Token rhs) -> void
def user_code=: (Lexer::Token::UserCode? user_code) -> void
def precedence_sym=: (Lexer::Token? precedence_sym) -> void
def complete_input: () -> void
def setup_rules: (Grammar::ParameterizingRule::Resolver parameterizing_rule_resolver) -> void
def setup_rules: () -> void
def rules: () -> Array[Rule]

private

def freeze_rhs: () -> void
def preprocess_references: () -> void
def build_rules: () -> void
def process_rhs: (Grammar::ParameterizingRule::Resolver parameterizing_rule_resolver) -> void
def process_rhs: () -> void
def lhs_s_value: (Lexer::Token::InstantiateRule token, Grammar::Binding bindings) -> String
def resolve_inline: (Grammar::ParameterizingRule::Resolver parameterizing_rule_resolver) -> void
def resolve_inline: () -> void
def resolve_inline_rhs: (RuleBuilder rule_builder, Grammar::ParameterizingRule::Rhs inline_rhs, Integer index) -> void
def replace_inline_user_code: (Grammar::ParameterizingRule::Rhs inline_rhs, Integer index) -> Lexer::Token::UserCode?
def numberize_references: () -> void
Expand Down
6 changes: 3 additions & 3 deletions spec/lrama/grammar/rule_builder_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
RSpec.describe Lrama::Grammar::RuleBuilder do
let(:rule_counter) { Lrama::Grammar::Counter.new(1) }
let(:midrule_action_counter) { Lrama::Grammar::Counter.new(1) }
let(:rule_builder) { Lrama::Grammar::RuleBuilder.new(rule_counter, midrule_action_counter) }
let(:rule_builder) { Lrama::Grammar::RuleBuilder.new(rule_counter, midrule_action_counter, Lrama::Grammar::ParameterizingRule::Resolver.new) }
let(:path) { "parse.y" }

describe "#add_rhs" do
Expand Down Expand Up @@ -464,7 +464,7 @@ class : keyword_class tSTRING keyword_end { $classes = $1; }
rule_builder.add_rhs(token_6)
rule_builder.user_code = token_7
rule_builder.complete_input
rule_builder.setup_rules(Lrama::Grammar::ParameterizingRule::Resolver.new)
rule_builder.setup_rules

rules = rule_builder.rules
midrule_1 = rules.find {|rule| rule._lhs.s_value == "@1"}
Expand Down Expand Up @@ -501,7 +501,7 @@ class : keyword_class tSTRING keyword_end { $classes = $1; }
rule_builder.add_rhs(token_6)
rule_builder.user_code = token_7
rule_builder.complete_input
rule_builder.setup_rules(Lrama::Grammar::ParameterizingRule::Resolver.new)
rule_builder.setup_rules

tokens = rule_builder.instance_variable_get(:@replaced_rhs)

Expand Down

0 comments on commit 514e61c

Please sign in to comment.