Skip to content

Commit

Permalink
Deduplicate grouping rules
Browse files Browse the repository at this point in the history
  • Loading branch information
nurse committed Jun 15, 2023
1 parent abb85bb commit d34618e
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions lib/racc/grammarfileparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,13 @@ def add_rule_block(list)
end

def _add_rule_block(target, enum)
rules = [] # [ [seqs, sprec], .. ]
curr = []
sprec = nil
while (sym, idx = enum.next rescue nil)
case sym
when OrMark
add_rule target, curr, sprec
rules << [curr, sprec]
curr = []
sprec = nil
when OptionMark
Expand All @@ -254,26 +255,41 @@ def _add_rule_block(target, enum)
when Many1Mark
curr << _add_many1_rule(curr.pop)
when GroupStartMark
@many_seq ||= 0
@many_seq += 1
t = _gen_target_name("group", @grammar.intern(@many_seq.to_s))
syms, _ = _add_rule_block(t, enum)
src = SourceText.new("result = val", __FILE__, __LINE__)
@grammar.add Rule.new(t, syms, UserAction.source_text(src))
curr << t
group_target = @grammar.intern("-temp-group")
group_rules, _ = _add_rule_block(group_target, enum)
group_target_name = _gen_group_target_name_str(group_rules)
@group_rule_registry ||= {}
if group_target = @group_rule_registry[group_target_name]
else
group_target = @grammar.intern("-group@#{group_target_name}")
@group_rule_registry[group_target_name] = group_target
src = SourceText.new("result = val", __FILE__, __LINE__)
act = UserAction.source_text(src)
group_rules.each do |syms, sprec|
rule = Rule.new(group_target, syms, act)
rule.specified_prec = sprec
@grammar.add rule
end
end
curr << group_target
when GroupEndMark
return curr, sym, idx
rules << [curr, sprec]
return rules, sym, idx
when Prec
raise CompileError, "'=<prec>' used twice in one rule" if sprec
sprec = sym.symbol
else
curr.push sym
end
end
add_rule target, curr, sprec
rules << [curr, sprec]
rules.each do |syms, sprec|
add_rule target, syms, sprec
end
nil
end


def _add_option_rule(prev)
@option_rule_registry ||= {}
target = @option_rule_registry[prev.to_s]
Expand Down Expand Up @@ -316,6 +332,10 @@ def _gen_target_name(type, sym)
@grammar.intern("-#{type}@#{sym.value}")
end

def _gen_group_target_name_str(rules)
rules.map{|syms, sprec| syms.join("-")}.join("|")
end

def add_rule(target, list, sprec)
if list.last.kind_of?(UserAction)
act = list.pop
Expand Down

0 comments on commit d34618e

Please sign in to comment.