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.
Direct Known Subclasses
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 = {})
- #critique(segment_tok, segment_uses)
- #matches(segment_tok, strict, mode) ⇒ Array<Instruction>
-
#pretty_print(q)
: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.
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 459 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 = {})
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)
50 51 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 50 def critique(segment_tok, segment_uses) end |
#matches(segment_tok, strict, mode) ⇒ Array<Instruction>
21 |
# File 'lib/stupidedi/parser/constraint_table.rb', line 21 abstract :matches, :args => %w(segment_tok strict mode) |
#pretty_print(q)
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 |