Class: Stupidedi::Parser::ConstraintTable
- Inherits:
-
Object
- Object
- Stupidedi::Parser::ConstraintTable
- Defined in:
- lib/stupidedi/parser/constraint_table.rb
Overview
The ConstraintTable is a data structure that contains one or more Instruction values for the same segment identifier. Each concrete subclass implements different strategies for narrowing down the Instruction list.
Reducing the number of valid Instruction values is important because executing more than one Instruction creates a non-deterministic state -- more than one valid parse tree exists -- which slows the parser. Most often there is only one valid Instruction but the parser cannot (efficiently or at all) narrow the tree down without evaluating the constraints declared by each Instruction's Schema::SegmentUse, which is done here.
Defined Under Namespace
Classes: Deepest, Shallowest, Stub, ValueBased
Instance Attribute Summary collapse
- #instructions ⇒ Array<Instruction> readonly
Constructors collapse
-
.build(instructions) ⇒ ConstraintTable
Given a list of Instruction values for the same segment identifier, this method constructs the appropriate concrete subclass of ConstraintTable.
Instance Method Summary collapse
- #copy(changes = {}) ⇒ Object
- #critique(segment_tok, segment_uses) ⇒ Object
- #matches ⇒ Array<Instruction>
-
#pretty_print(q) ⇒ void
:nocov:.
Instance Attribute Details
#instructions ⇒ Array<Instruction> (readonly)
24 25 26 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 24 def instructions @instructions end |
Class Method Details
.build(instructions) ⇒ ConstraintTable
Given a list of Instruction values for the same segment identifier, this method constructs the appropriate concrete subclass of Stupidedi::Parser::ConstraintTable.
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 537 def build(instructions) if instructions.length <= 1 ConstraintTable::Stub.new(instructions) elsif instructions.any?{|i| i.segment_use.nil? } and not instructions.all?{|i| i.segment_use.nil? } # When one of the instructions has a nil segment_use, it means # the SegmentUse is determined when pushing the new state. There # isn't a way to know the segment constraints from here. ConstraintTable::Stub.new(instructions) else segment_uses = instructions.map{|i| i.segment_use } if segment_uses.map{|u| u.object_id }.uniq.length <= 1 # The same SegmentUse may appear more than once, because the # segment can be placed at different levels in the tree. If # all the instructions have the same SegmentUse, they also have # the same element constraints so we can't use them to narrow # down the instruction list. ConstraintTable::Shallowest.new(instructions) else ConstraintTable::ValueBased.new(instructions) end end end |
Instance Method Details
#copy(changes = {}) ⇒ Object
26 27 28 29 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 26 def copy(changes = {}) self.class.new \ changes.fetch(:instructions, instructions) end |
#critique(segment_tok, segment_uses) ⇒ Object
50 51 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 50 def critique(segment_tok, segment_uses) end |
#matches ⇒ Array<Instruction>
21 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 21 abstract :matches, :args => %w(segment_tok strict mode state) |
#pretty_print(q) ⇒ void
This method returns an undefined value.
:nocov:
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 33 def pretty_print(q) name = self.class.name.split("::").last q.text "#{name}.build" q.group(2, "([", "])") do q.breakable instructions.each do |op| unless q.current_group.first? q.text "," q.breakable end q.pp op end end end |