diff options
Diffstat (limited to 'tool/lrama/lib/lrama/states/item.rb')
-rw-r--r-- | tool/lrama/lib/lrama/states/item.rb | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/tool/lrama/lib/lrama/states/item.rb b/tool/lrama/lib/lrama/states/item.rb new file mode 100644 index 0000000000..31b74b9d34 --- /dev/null +++ b/tool/lrama/lib/lrama/states/item.rb @@ -0,0 +1,81 @@ +# TODO: Validate position is not over rule rhs + +require "forwardable" + +module Lrama + class States + class Item < Struct.new(:rule, :position, keyword_init: true) + extend Forwardable + + def_delegators "rule", :lhs, :rhs + + # Optimization for States#setup_state + def hash + [rule_id, position].hash + end + + def rule_id + rule.id + end + + def empty_rule? + rule.empty_rule? + end + + def number_of_rest_symbols + rhs.count - position + end + + def next_sym + rhs[position] + end + + def next_next_sym + rhs[position + 1] + end + + def previous_sym + rhs[position - 1] + end + + def end_of_rule? + rhs.count == position + end + + def beginning_of_rule? + position == 0 + end + + def start_item? + rule.initial_rule? && beginning_of_rule? + end + + def new_by_next_position + Item.new(rule: rule, position: position + 1) + end + + def symbols_before_dot + rhs[0...position] + end + + def symbols_after_dot + rhs[position..-1] + end + + def to_s + "#{lhs.id.s_value}: #{display_name}" + end + + def display_name + r = rhs.map(&:display_name).insert(position, "•").join(" ") + "#{r} (rule #{rule_id})" + end + + # Right after position + def display_rest + r = rhs[position..-1].map(&:display_name).join(" ") + ". #{r} (rule #{rule_id})" + end + end + end +end |