Skip to content

Commit

Permalink
Do not include mid-rule actions when tracing rules
Browse files Browse the repository at this point in the history
This PR, midrule actions should not be included when tracing rules.

Before:
```
❯ exe/lrama --trace=rules ./spec/fixtures/common/basic.y
Grammar rules:
$accept -> program EOI
program -> class
program -> '+' strings_1
program -> '-' strings_2
class -> keyword_class tSTRING keyword_end
$@1 -> ε
$@2 -> ε
class -> keyword_class $@1 tSTRING '!' keyword_end $@2
$@3 -> ε
$@4 -> ε
class -> keyword_class $@3 tSTRING '?' keyword_end $@4
strings_1 -> string_1
strings_2 -> string_1
strings_2 -> string_2
string_1 -> string
string_2 -> string '+'
string -> tSTRING
unused -> tNUMBER
```

After:
```
❯ exe/lrama --trace=rules ./spec/fixtures/common/basic.y
Grammar rules:
$accept -> program EOI
program -> class
program -> '+' strings_1
program -> '-' strings_2
class -> keyword_class tSTRING keyword_end
class -> keyword_class tSTRING '!' keyword_end
class -> keyword_class tSTRING '?' keyword_end
strings_1 -> string_1
strings_2 -> string_1
strings_2 -> string_2
string_1 -> string
string_2 -> string '+'
string -> tSTRING
unused -> tNUMBER
```
  • Loading branch information
ydah committed Jan 1, 2025
1 parent 317b7d1 commit e05bcf8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
8 changes: 8 additions & 0 deletions lib/lrama/grammar/rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def ==(other)
def display_name
l = lhs.id.s_value
r = empty_rule? ? "ε" : rhs.map {|r| r.id.s_value }.join(" ")
"#{l} -> #{r}"
end

def display_name_without_action
l = lhs.id.s_value
r = empty_rule? ? "ε" : rhs.map do |r|
r.id.s_value if r.first_set.any?
end.compact.join(" ")

"#{l} -> #{r}"
end
Expand Down
4 changes: 3 additions & 1 deletion lib/lrama/trace_reporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def _report(rules: false, actions: false, **_)

def report_rules
puts "Grammar rules:"
@grammar.rules.each { |rule| puts rule.display_name }
@grammar.rules.each do |rule|
puts rule.display_name_without_action if rule.lhs.first_set.any?
end
end

def report_actions
Expand Down
74 changes: 74 additions & 0 deletions spec/lrama/trace_reporter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

RSpec.describe Lrama::TraceReporter do
describe "#report" do
let(:path) { "common/basic.y" }
let(:y) { File.read(fixture_path(path)) }
let(:grammar) do
grammar = Lrama::Parser.new(y, path).parse
grammar.prepare
grammar.validate!
grammar
end

context "when rules: true" do
it "prints the rules" do
expect do
described_class.new(grammar).report(rules: true)
end.to output(<<~RULES).to_stdout
Grammar rules:
$accept -> program EOI
program -> class
program -> '+' strings_1
program -> '-' strings_2
class -> keyword_class tSTRING keyword_end
class -> keyword_class tSTRING '!' keyword_end
class -> keyword_class tSTRING '?' keyword_end
strings_1 -> string_1
strings_2 -> string_1
strings_2 -> string_2
string_1 -> string
string_2 -> string '+'
string -> tSTRING
unused -> tNUMBER
RULES
end
end

context "when actions: true" do
it "prints the actions" do
expect do
described_class.new(grammar).report(actions: true)
end.to output(<<~RULES).to_stdout
Grammar rules with actions:
$accept -> program EOI {}
program -> class {}
program -> '+' strings_1 {}
program -> '-' strings_2 {}
class -> keyword_class tSTRING keyword_end { code 1 }
$@1 -> ε { code 2 }
$@2 -> ε { code 3 }
class -> keyword_class $@1 tSTRING '!' keyword_end $@2 {}
$@3 -> ε { code 4 }
$@4 -> ε { code 5 }
class -> keyword_class $@3 tSTRING '?' keyword_end $@4 {}
strings_1 -> string_1 {}
strings_2 -> string_1 {}
strings_2 -> string_2 {}
string_1 -> string {}
string_2 -> string '+' {}
string -> tSTRING {}
unused -> tNUMBER {}
RULES
end
end

context 'when empty options' do
it 'does not print anything' do
expect do
described_class.new(grammar).report
end.to_not output.to_stdout
end
end
end
end

0 comments on commit e05bcf8

Please sign in to comment.