Module: RailroadDiagrams::Transform::Simplifier

Defined in:
lib/railroad_diagrams/transform/simplifier.rb

Overview

Applies semantics-preserving grammar simplification rules.

Examples:

Transform::Simplifier.call(Choice.new(0, 'a', 'a'))

Class Method Summary collapse

Class Method Details

.call(node, except: [], rule_name: nil) ⇒ Object

Returns a simplified copy of a diagram node.

Examples:

Transform::Simplifier.call(Choice.new(0, 'a', 'a'), except: [:s6])

Raises:



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/railroad_diagrams/transform/simplifier.rb', line 19

def call(node, except: [], rule_name: nil)
  raise InvalidArgument, 'node must be a diagram node' unless node.is_a?(DiagramItem)

  excluded = Array(except)
  raise InvalidArgument, 'unknown simplification rule' unless (excluded - RULES).empty?

  current = node.to_h
  10.times do
    updated = rewrite(current, excluded, rule_name, true)
    return RailroadDiagrams.from_h(current) if updated == current

    current = updated
  end
  RailroadDiagrams.from_h(current)
end

.plain?(node) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/railroad_diagrams/transform/simplifier.rb', line 58

def plain?(node)
  (node.keys & ATTRIBUTES).empty?
end

.references?(node, name) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/railroad_diagrams/transform/simplifier.rb', line 163

def references?(node, name)
  return node['text'] == name if node['type'] == 'non_terminal'

  node.values.any? do |value|
    if value.is_a?(Hash) && value['type']
      references?(value, name)
    elsif value.is_a?(Array)
      value.any? { |item| item.is_a?(Hash) && item['type'] && references?(item, name) }
    else
      false
    end
  end
end