Class: Stupidedi::Builder::ConstraintTable

Inherits:
Object
  • Object
show all
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

Deepest, Shallowest, Stub, ValueBased

Defined Under Namespace

Classes: Deepest, Shallowest, Stub, ValueBased

Constructors collapse

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.

Parameters:

Returns:



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

#matchesArray<Instruction>

Returns:



21
# File 'lib/stupidedi/builder/constraint_table.rb', line 21

abstract :matches, :args => %w(segment_tok)