Warn on unused rules

This commit is contained in:
josh committed 2026-11-03 22:07:51 -05:00
1 parent 66af46a4f6
commit e5805d2db4
6 files changed
+87 -6

No files matched your search

+2 -2
View File
@@ -10,8 +10,8 @@ Options:
debugging a grammar.
--version Show program version and exit.
-w Treat warnings as errors. This option will treat shift/reduce
conflicts as fatal errors and will print them to stderr in
addition to the log file.
conflicts and unused rules as fatal errors and will print
them to stderr in addition to the log file.
EOF
class << self
+29
View File
@@ -50,6 +50,7 @@ class Propane
build_reduce_actions!
build_tables!
check_unused_rules!
write_log!
errormessage = ""
if @errors.size > 0
@@ -68,6 +69,34 @@ class Propane
private
# Record a warning for each user-defined rule that cannot be reached from
# any start rule.
#
# @return [void]
def check_unused_rules!
reachable = Set.new
pending = @grammar.rules[0...@grammar.start_rules.length].map(&:rule_set)
while rule_set = pending.pop
next if reachable.include?(rule_set)
reachable << rule_set
rule_set.rules.each do |rule|
rule.components.each do |component|
if component.is_a?(RuleSet) && !reachable.include?(component)
pending << component
end
end
end
end
@rule_sets.each do |name, rule_set|
# Skip rule sets generated internally (real start rules and optional
# component rules).
next if name.start_with?("$") || rule_set.optional?
unless reachable.include?(rule_set)
@warnings << "Unused rule #{name} (defined on line #{rule_set.rules.first.line_number})"
end
end
end
def build_tables!
@state_table = []
@shift_table = []