Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion 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 @@ -255,7 +259,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
35 changes: 18 additions & 17 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 @@ -55,12 +56,12 @@ def complete_input
freeze_rhs
end

def setup_rules(parameterizing_rule_resolver)
def setup_rules
preprocess_references unless @skip_preprocess_references
if rhs.any? { |token| parameterizing_rule_resolver.find_inline(token) }
resolve_inline(parameterizing_rule_resolver)
if rhs.any? { |token| @parameterizing_rule_resolver.find_inline(token) }
resolve_inline
else
process_rhs(parameterizing_rule_resolver)
process_rhs
end
build_rules
end
Expand Down Expand Up @@ -106,7 +107,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 @@ -118,26 +119,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 || parameterizing_rule.tag)
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: token.lhs_tag || parameterizing_rule.tag)
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.resolve_user_code(bindings)
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 @@ -147,11 +148,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 All @@ -172,17 +173,17 @@ def lhs_s_value(token, bindings)
"#{token.rule_name}_#{s_values.join('_')}"
end

def resolve_inline(parameterizing_rule_resolver)
def resolve_inline
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_with_index do |inline_rhs|
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: lhs_tag, skip_preprocess_references: true)
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: lhs_tag, skip_preprocess_references: true)
resolve_inline_rhs(rule_builder, inline_rhs, i)
rule_builder.lhs = lhs
rule_builder.line = line
rule_builder.user_code = replace_inline_user_code(inline_rhs, i)
rule_builder.complete_input
rule_builder.setup_rules(parameterizing_rule_resolver)
rule_builder.setup_rules
@rule_builders_for_inline_rules << rule_builder
end
end
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 @@ -22,22 +23,22 @@ module Lrama
@inline_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