Class: Stupidedi::Parser::ConstraintTable

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

Deepest, Shallowest, Stub, ValueBased

Defined Under Namespace

Classes: Deepest, Shallowest, Stub, ValueBased

Instance Attribute Summary collapse

Constructors collapse

Instance Method Summary collapse

Instance Attribute Details

#instructionsArray<Instruction> (readonly)

Returns:



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.

Parameters:

Returns:



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)

TODO:


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>

Returns:



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