Lrama v0.6.6
This commit is contained in:
parent
2ba7c1b142
commit
bf1f16ef47
@ -47,6 +47,11 @@ module Lrama
|
||||
puts grammar.rules
|
||||
end
|
||||
|
||||
if options.trace_opts && options.trace_opts[:actions]
|
||||
puts "Grammar rules with actions:"
|
||||
grammar.rules.each { |rule| puts rule.with_actions }
|
||||
end
|
||||
|
||||
File.open(options.outfile, "w+") do |f|
|
||||
Lrama::Output.new(
|
||||
out: f,
|
||||
|
@ -13,8 +13,12 @@ module Lrama
|
||||
@rules << rule
|
||||
end
|
||||
|
||||
def find(token)
|
||||
select_rules(token).last
|
||||
def find_rule(token)
|
||||
select_rules(@rules, token).last
|
||||
end
|
||||
|
||||
def find_inline(token)
|
||||
@rules.select { |rule| rule.name == token.s_value && rule.is_inline }.last
|
||||
end
|
||||
|
||||
def created_lhs(lhs_s_value)
|
||||
@ -23,8 +27,9 @@ module Lrama
|
||||
|
||||
private
|
||||
|
||||
def select_rules(token)
|
||||
rules = select_rules_by_name(token.rule_name)
|
||||
def select_rules(rules, token)
|
||||
rules = select_not_inline_rules(rules)
|
||||
rules = select_rules_by_name(rules, token.rule_name)
|
||||
rules = rules.select { |rule| rule.required_parameters_count == token.args_count }
|
||||
if rules.empty?
|
||||
raise "Invalid number of arguments. `#{token.rule_name}`"
|
||||
@ -33,8 +38,12 @@ module Lrama
|
||||
end
|
||||
end
|
||||
|
||||
def select_rules_by_name(rule_name)
|
||||
rules = @rules.select { |rule| rule.name == rule_name }
|
||||
def select_not_inline_rules(rules)
|
||||
rules.select { |rule| !rule.is_inline }
|
||||
end
|
||||
|
||||
def select_rules_by_name(rules, rule_name)
|
||||
rules = rules.select { |rule| rule.name == rule_name }
|
||||
if rules.empty?
|
||||
raise "Parameterizing rule does not exist. `#{rule_name}`"
|
||||
else
|
||||
|
@ -2,12 +2,13 @@ module Lrama
|
||||
class Grammar
|
||||
class ParameterizingRule
|
||||
class Rule
|
||||
attr_reader :name, :parameters, :rhs_list, :required_parameters_count
|
||||
attr_reader :name, :parameters, :rhs_list, :required_parameters_count, :is_inline
|
||||
|
||||
def initialize(name, parameters, rhs_list)
|
||||
def initialize(name, parameters, rhs_list, is_inline: false)
|
||||
@name = name
|
||||
@parameters = parameters
|
||||
@rhs_list = rhs_list
|
||||
@is_inline = is_inline
|
||||
@required_parameters_count = parameters.count
|
||||
end
|
||||
end
|
||||
|
@ -19,7 +19,7 @@ module Lrama
|
||||
# TODO: Change this to display_name
|
||||
def to_s
|
||||
l = lhs.id.s_value
|
||||
r = empty_rule? ? "ε" : rhs.map {|r| r.id.s_value }.join(", ")
|
||||
r = empty_rule? ? "ε" : rhs.map {|r| r.id.s_value }.join(" ")
|
||||
|
||||
"#{l} -> #{r}"
|
||||
end
|
||||
@ -32,6 +32,10 @@ module Lrama
|
||||
"#{l}: #{r}"
|
||||
end
|
||||
|
||||
def with_actions
|
||||
"#{to_s} {#{token_code&.s_value}}"
|
||||
end
|
||||
|
||||
# opt_nl: ε <-- empty_rule
|
||||
# | '\n' <-- not empty_rule
|
||||
def empty_rule?
|
||||
|
@ -16,8 +16,13 @@ module Lrama
|
||||
@user_code = nil
|
||||
@precedence_sym = nil
|
||||
@line = nil
|
||||
@rules = []
|
||||
@rule_builders_for_parameterizing_rules = []
|
||||
@rule_builders_for_derived_rules = []
|
||||
@rule_builders_for_inline_rules = []
|
||||
@parameterizing_rules = []
|
||||
@inline_rules = []
|
||||
@midrule_action_rules = []
|
||||
end
|
||||
|
||||
def add_rhs(rhs)
|
||||
@ -52,12 +57,16 @@ module Lrama
|
||||
|
||||
def setup_rules(parameterizing_rule_resolver)
|
||||
preprocess_references unless @skip_preprocess_references
|
||||
process_rhs(parameterizing_rule_resolver)
|
||||
if rhs.any? { |token| parameterizing_rule_resolver.find_inline(token) }
|
||||
resolve_inline(parameterizing_rule_resolver)
|
||||
else
|
||||
process_rhs(parameterizing_rule_resolver)
|
||||
end
|
||||
build_rules
|
||||
end
|
||||
|
||||
def rules
|
||||
@parameterizing_rules + @midrule_action_rules + @rules
|
||||
@parameterizing_rules + @inline_rules + @midrule_action_rules + @rules
|
||||
end
|
||||
|
||||
private
|
||||
@ -73,19 +82,25 @@ module Lrama
|
||||
def build_rules
|
||||
tokens = @replaced_rhs
|
||||
|
||||
rule = Rule.new(
|
||||
id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, lhs_tag: lhs_tag, token_code: user_code,
|
||||
position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line
|
||||
)
|
||||
@rules = [rule]
|
||||
@parameterizing_rules = @rule_builders_for_parameterizing_rules.map do |rule_builder|
|
||||
rule_builder.rules
|
||||
end.flatten
|
||||
@midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder|
|
||||
rule_builder.rules
|
||||
end.flatten
|
||||
@midrule_action_rules.each do |r|
|
||||
r.original_rule = rule
|
||||
if tokens
|
||||
rule = Rule.new(
|
||||
id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, lhs_tag: lhs_tag, token_code: user_code,
|
||||
position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line
|
||||
)
|
||||
@rules = [rule]
|
||||
@parameterizing_rules = @rule_builders_for_parameterizing_rules.map do |rule_builder|
|
||||
rule_builder.rules
|
||||
end.flatten
|
||||
@midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder|
|
||||
rule_builder.rules
|
||||
end.flatten
|
||||
@midrule_action_rules.each do |r|
|
||||
r.original_rule = rule
|
||||
end
|
||||
else
|
||||
@inline_rules = @rule_builders_for_inline_rules.map do |rule_builder|
|
||||
rule_builder.rules
|
||||
end.flatten
|
||||
end
|
||||
end
|
||||
|
||||
@ -103,7 +118,7 @@ module Lrama
|
||||
when Lrama::Lexer::Token::Ident
|
||||
@replaced_rhs << token
|
||||
when Lrama::Lexer::Token::InstantiateRule
|
||||
parameterizing_rule = parameterizing_rule_resolver.find(token)
|
||||
parameterizing_rule = parameterizing_rule_resolver.find_rule(token)
|
||||
raise "Unexpected token. #{token}" unless parameterizing_rule
|
||||
|
||||
bindings = Binding.new(parameterizing_rule, token.args)
|
||||
@ -115,7 +130,7 @@ module Lrama
|
||||
@replaced_rhs << 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, lhs_tag: token.lhs_tag)
|
||||
rule_builder.lhs = lhs_token
|
||||
r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
|
||||
rule_builder.line = line
|
||||
@ -157,6 +172,41 @@ module Lrama
|
||||
"#{token.rule_name}_#{s_values.join('_')}"
|
||||
end
|
||||
|
||||
def resolve_inline(parameterizing_rule_resolver)
|
||||
rhs.each_with_index do |token, i|
|
||||
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)
|
||||
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_builders_for_inline_rules << rule_builder
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def resolve_inline_rhs(rule_builder, inline_rhs, index)
|
||||
rhs.each_with_index do |token, i|
|
||||
if index == i
|
||||
inline_rhs.symbols.each { |sym| rule_builder.add_rhs(sym) }
|
||||
else
|
||||
rule_builder.add_rhs(token)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def replace_inline_user_code(inline_rhs, index)
|
||||
return user_code if inline_rhs.user_code.nil?
|
||||
return user_code if user_code.nil?
|
||||
|
||||
code = user_code.s_value.gsub(/\$#{index + 1}/, inline_rhs.user_code.s_value)
|
||||
Lrama::Lexer::Token::UserCode.new(s_value: code, location: user_code.location)
|
||||
end
|
||||
|
||||
def numberize_references
|
||||
# Bison n'th component is 1-origin
|
||||
(rhs + [user_code]).compact.each.with_index(1) do |token, i|
|
||||
|
@ -37,6 +37,7 @@ module Lrama
|
||||
%code
|
||||
%rule
|
||||
%no-stdlib
|
||||
%inline
|
||||
)
|
||||
|
||||
def initialize(grammar_file)
|
||||
|
@ -1,11 +1,21 @@
|
||||
module Lrama
|
||||
class Lexer
|
||||
class GrammarFile
|
||||
class Text < String
|
||||
def inspect
|
||||
length <= 50 ? super : "#{self[0..47]}...".inspect
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :path, :text
|
||||
|
||||
def initialize(path, text)
|
||||
@path = path
|
||||
@text = text.freeze
|
||||
@text = Text.new(text).freeze
|
||||
end
|
||||
|
||||
def inspect
|
||||
"<#{self.class}: @path=#{path}, @text=#{text.inspect}>"
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
|
@ -119,8 +119,9 @@ module Lrama
|
||||
|
||||
VALID_TRACES = %w[
|
||||
none locations scan parse automaton bitsets
|
||||
closure grammar rules resource sets muscles tools
|
||||
m4-early m4 skeleton time ielr cex all
|
||||
closure grammar rules actions resource
|
||||
sets muscles tools m4-early m4 skeleton time
|
||||
ielr cex all
|
||||
]
|
||||
|
||||
def validate_trace(trace)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -70,38 +70,16 @@ module Lrama
|
||||
reduce.look_ahead = look_ahead
|
||||
end
|
||||
|
||||
# Returns array of [Shift, next_state]
|
||||
def nterm_transitions
|
||||
return @nterm_transitions if @nterm_transitions
|
||||
|
||||
@nterm_transitions = []
|
||||
|
||||
shifts.each do |shift|
|
||||
next if shift.next_sym.term?
|
||||
|
||||
@nterm_transitions << [shift, @items_to_state[shift.next_items]]
|
||||
end
|
||||
|
||||
@nterm_transitions
|
||||
@nterm_transitions ||= transitions.select {|shift, _| shift.next_sym.nterm? }
|
||||
end
|
||||
|
||||
# Returns array of [Shift, next_state]
|
||||
def term_transitions
|
||||
return @term_transitions if @term_transitions
|
||||
|
||||
@term_transitions = []
|
||||
|
||||
shifts.each do |shift|
|
||||
next if shift.next_sym.nterm?
|
||||
|
||||
@term_transitions << [shift, @items_to_state[shift.next_items]]
|
||||
end
|
||||
|
||||
@term_transitions
|
||||
@term_transitions ||= transitions.select {|shift, _| shift.next_sym.term? }
|
||||
end
|
||||
|
||||
def transitions
|
||||
term_transitions + nterm_transitions
|
||||
@transitions ||= shifts.map {|shift| [shift, @items_to_state[shift.next_items]] }
|
||||
end
|
||||
|
||||
def selected_term_transitions
|
||||
|
@ -1,3 +1,3 @@
|
||||
module Lrama
|
||||
VERSION = "0.6.5".freeze
|
||||
VERSION = "0.6.6".freeze
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user