Skip to content

Commit

Permalink
Add support for parameterizing-redefined category
Browse files Browse the repository at this point in the history
Specify this category in the `-W` or `--warning` option to output a warning about the redefinition of parameterizing rules.

## Motivation

Currently, for example, users have no way of knowing the parameterizing rules provided in the standard library are redefined.
Therefore, by specifying the `parameterizing-redefined` option, users will be able to know parameterizing rules have been redefined.
  • Loading branch information
ydah committed Jun 18, 2024
1 parent 63d32bf commit 0b4f711
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/lrama/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def run(argv)

logger = Lrama::Logger.new
exit false unless Lrama::GrammarValidator.new(grammar, states, logger).valid?
Lrama::Diagnostics.new(states, logger).run(**options.diagnostic_opts)
Lrama::Diagnostics.new(grammar, states, logger).run(**options.diagnostic_opts)
end
end
end
12 changes: 10 additions & 2 deletions lib/lrama/diagnostics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

module Lrama
class Diagnostics
def initialize(states, logger)
def initialize(grammar, states, logger)
@grammar = grammar
@states = states
@logger = logger
end

def run(conflicts_sr: false, conflicts_rr: false)
def run(conflicts_sr: false, conflicts_rr: false, parameterizing_redefined: false)
diagnose_conflict(conflicts_sr, conflicts_rr)
diagnose_parameterizing_redefined if parameterizing_redefined
end

private
Expand All @@ -22,5 +24,11 @@ def diagnose_conflict(conflicts_sr, conflicts_rr)
@logger.warn("reduce/reduce conflicts: #{@states.rr_conflicts_count} found")
end
end

def diagnose_parameterizing_redefined
@grammar.parameterizing_rule_resolver.redefined_rules.each do |rule|
@logger.warn("parameterizing rule redefined: #{rule}")
end
end
end
end
2 changes: 1 addition & 1 deletion lib/lrama/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module Lrama
class Grammar
extend Forwardable

attr_reader :percent_codes, :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux
attr_reader :percent_codes, :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux, :parameterizing_rule_resolver
attr_accessor :union, :expect,
:printers, :error_tokens,
:lex_param, :parse_param, :initial_action,
Expand Down
4 changes: 4 additions & 0 deletions lib/lrama/grammar/parameterizing_rule/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def created_lhs(lhs_s_value)
@created_lhs_list.reverse.find { |created_lhs| created_lhs.s_value == lhs_s_value }
end

def redefined_rules
@rules.select { |rule| @rules.count { |r| r.name == rule.name && r.required_parameters_count == rule.required_parameters_count } > 1 }
end

private

def select_rules(rules, token)
Expand Down
4 changes: 4 additions & 0 deletions lib/lrama/grammar/parameterizing_rule/rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def initialize(name, parameters, rhs_list, tag: nil, is_inline: false)
@is_inline = is_inline
@required_parameters_count = parameters.count
end

def to_s
"#{@name}(#{@parameters.map(&:s_value).join(', ')})"
end
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/lrama/option_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def parse_by_option_parser(argv)
o.separator 'Warning categories include:'
o.separator ' conflicts-sr Shift/Reduce conflicts (enabled by default)'
o.separator ' conflicts-rr Reduce/Reduce conflicts (enabled by default)'
o.separator ' parameterizing-redefined redefinition of parameterizing rule'
o.separator ' all all warnings'
o.separator ' none turn off all warnings'
o.separator ''
Expand Down Expand Up @@ -152,7 +153,7 @@ def validate_trace(trace)
end

DIAGNOSTICS = %w[]
HYPHENATED_DIAGNOSTICS = %w[conflicts-sr conflicts-rr]
HYPHENATED_DIAGNOSTICS = %w[conflicts-sr conflicts-rr parameterizing-redefined]

def validate_diagnostic(diagnostic)
h = { conflicts_sr: true, conflicts_rr: true }
Expand Down
36 changes: 35 additions & 1 deletion spec/lrama/diagnostics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,44 @@ class : keyword_class tSTRING keyword_end %prec tPLUS
states.compute
logger = Lrama::Logger.new
allow(logger).to receive(:warn)
Lrama::Diagnostics.new(states, logger).run(conflicts_sr: true, conflicts_rr: true)
Lrama::Diagnostics.new(grammar, states, logger).run(conflicts_sr: true, conflicts_rr: true)
expect(logger).to have_received(:warn).with("shift/reduce conflicts: 2 found")
expect(logger).to have_received(:warn).with("reduce/reduce conflicts: 1 found")
end
end

context "when rule has parameterizing redefined" do
let(:y) do
<<~STR
%{
// Prologue
%}
%union {
int i;
}
%token <i> tNUMBER
%rule foo(X) : X
;
%rule foo(Y) : Y
;
%%
program: foo(tNUMBER)
;
STR
end

it "has warns for parameterizing redefined" do
grammar = Lrama::Parser.new(y, "states/parameterizing_rule_redefined.y").parse
grammar.prepare
grammar.validate!
states = Lrama::States.new(grammar)
states.compute
logger = Lrama::Logger.new
allow(logger).to receive(:warn)
Lrama::Diagnostics.new(grammar, states, logger).run(parameterizing_redefined: true)
expect(logger).to have_received(:warn).with("parameterizing rule redefined: foo(X)")
expect(logger).to have_received(:warn).with("parameterizing rule redefined: foo(Y)")
end
end
end
end
1 change: 1 addition & 0 deletions spec/lrama/option_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
Warning categories include:
conflicts-sr Shift/Reduce conflicts (enabled by default)
conflicts-rr Reduce/Reduce conflicts (enabled by default)
parameterizing-redefined redefinition of parameterizing rule
all all warnings
none turn off all warnings
Expand Down

0 comments on commit 0b4f711

Please sign in to comment.