Class: Stupidedi::Builder::ConstraintTable
- Defined in:
- lib/stupidedi/builder/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
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
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::Builder::ConstraintTable.
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 |
# File 'lib/stupidedi/builder/constraint_table.rb', line 414 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. instructions.head.segment_id == :ISA ? ConstraintTable::Deepest.new(instructions) : ConstraintTable::Shallowest.new(instructions) else ConstraintTable::ValueBased.new(instructions) end end end |
Instance Method Details
#matches ⇒ Array<Instruction>
21 |
# File 'lib/stupidedi/builder/constraint_table.rb', line 21 abstract :matches, :args => %w(segment_tok) |