Class: Musa::GenerativeGrammar::Implementation::Node Private

Inherits:
Object
  • Object
show all
Defined in:
lib/musa-dsl/generative/generative-grammar.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Base node class for grammar elements.

Provides core operations for combining and transforming nodes. All node types (FinalNode, BlockNode, OrNode, etc.) inherit from this.

Instance Method Summary collapse

Instance Method Details

#_options(parent: nil) {|option| ... } ⇒ Array<Array<OptionElement>>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal method to generate option arrays.

Parameters:

Yield Parameters:

  • option (Array<OptionElement>)

    option so far -- PARTIAL as well as complete: the block is asked while the tree grows, not once at the end

Yield Returns:

  • (Boolean)

    true if this option may continue growing. A predicate that rejects the partials it passes through prunes them and never reaches the complete option it was written for

Returns:

Raises:

  • (NotImplementedError)


432
433
434
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 432

def _options(parent: nil, &condition)
  raise NotImplementedError
end

#get(index) ⇒ Node Also known as: []

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Gets option at index as series node.

Parameters:

  • index (Integer)

    option index

Returns:

  • (Node)

    option converted to node



389
390
391
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 389

def get(index)
  options[index].to_serie.to_node
end

#limit(attribute = nil, after_collect_operation = nil, comparison_method = nil, comparison_value = nil) {|option| ... } ⇒ ConditionNode

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Limits generated options by condition.

Filters options to only those satisfying the given condition. Can use simplified arguments or custom block.

Examples:

Block form

grammar = (a | b).repeat.limit { |o|
  o.collect { |e| e.attributes[:size] }.sum == 3
}

Simplified form

grammar = (a | b).repeat.limit(:size, :sum, :==, 3)

Parameters:

  • attribute (Symbol, nil) (defaults to: nil)

    attribute to check (simplified form)

  • after_collect_operation (Symbol, nil) (defaults to: nil)

    operation on collected values

  • comparison_method (Symbol, nil) (defaults to: nil)

    comparison method to apply

  • comparison_value (Object, nil) (defaults to: nil)

    value to compare against

Yield Parameters:

  • option (Array<OptionElement>)

    option so far -- PARTIAL as well as complete: the block is asked while the tree grows, not once at the end

Yield Returns:

  • (Boolean)

    true if this option may continue growing. A predicate that rejects the partials it passes through prunes them and never reaches the complete option it was written for

Returns:

Raises:

  • (ArgumentError)

    if both simplified arguments and block given



276
277
278
279
280
281
282
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 276

def limit(attribute = nil, after_collect_operation = nil, comparison_method = nil, comparison_value = nil, &block)
  raise ArgumentError, 'Cannot use simplified arguments and yield block at the same time' if (attribute || after_collect_operation || comparison_method || comparison_value) && @block

  block ||= generate_simple_condition_block(attribute, after_collect_operation, comparison_method, comparison_value)

  ConditionNode.new(self, &block)
end

#next(other) ⇒ NextNode Also known as: +

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates sequence of this node followed by another.

Generates options with this node's content followed by the other's.

Examples:

a = N('a')
b = N('b')
ab = a.next(b)  # or a + b

Parameters:

  • other (Node)

    node to follow

Returns:



296
297
298
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 296

def next(other)
  NextNode.new(self, other)
end

#options(attribute = nil, after_collect_operation = nil, comparison_method = nil, comparison_value = nil, raw: nil, content: nil) {|option| ... } ⇒ Array

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generates all options from this grammar node.

Produces all valid combinations matching the grammar definition. Can filter with condition and control output format.

Examples:

Basic usage

a = N('a', size: 1)
b = N('b', size: 1)
grammar = (a | b).repeat(2)

grammar.options  # => [["a", "a"], ["a", "b"], ["b", "a"], ["b", "b"]]

With content formatting

grammar.options(content: :join)  # => ["aa", "ab", "ba", "bb"]

With filtering

# The block prunes during growth, so it sees options of size 1 too:
# `option.size == 2` would kill them and yield nothing at all.
grammar.options { |option| option.size <= 2 }.size  # => 4
grammar.options(content: :join) { |option| option.all? { |e| e.content == 'a' } }
# => ["aa"]

Simplified filtering

# The first argument names an ATTRIBUTE of the nodes, not a method of
# the option: `size` here is the `size: 1` each N was given. Nodes
# without it make this form fail on nil.
grammar.options(:size, :sum, :<=, 4, content: :join)
# => ["aa", "ab", "ba", "bb"]

Raw OptionElements

grammar.options(raw: true).size  # => 4

Parameters:

  • attribute (Symbol, nil) (defaults to: nil)

    attribute for filtering (simplified)

  • after_collect_operation (Symbol, nil) (defaults to: nil)

    operation on collected values

  • comparison_method (Symbol, nil) (defaults to: nil)

    comparison method

  • comparison_value (Object, nil) (defaults to: nil)

    value to compare against

  • raw (Boolean) (defaults to: nil)

    if true, return raw OptionElement arrays

  • content (Symbol) (defaults to: nil)

    how to extract content (:itself, :join, etc.)

Yield Parameters:

  • option (Array<OptionElement>)

    option so far -- PARTIAL as well as complete: the block is asked while the tree grows, not once at the end

Yield Returns:

  • (Boolean)

    true if this option may continue growing. A predicate that rejects the partials it passes through prunes them and never reaches the complete option it was written for

Returns:

  • (Array)

    generated options

Raises:

  • (ArgumentError)

    if simplified arguments and block both given

  • (ArgumentError)

    if raw and content both specified



352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 352

def options(attribute = nil,
            after_collect_operation = nil,
            comparison_method = nil,
            comparison_value = nil,
            raw: nil,
            content: nil,
            &condition)

  raise ArgumentError, 'Cannot use simplified arguments and yield block at the same time' if (attribute || after_collect_operation || comparison_method || comparison_value) && @condition
  raise ArgumentError, 'Cannot use raw: true and content: option at the same time' if raw && content

  raw ||= false
  content ||= :itself

  condition ||= generate_simple_condition_block(attribute, after_collect_operation, comparison_method, comparison_value)

  if raw
    _options(&condition)
  else
    _options(&condition).collect { |o| o.collect(&:content).send(content) }
  end
end

#or(other) ⇒ OrNode Also known as: |

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates alternation between this node and another.

Generates options where either this node or the other is chosen.

Examples:

a = N('a')
b = N('b')
ab = a.or(b)  # or a | b

Parameters:

  • other (Node)

    alternative node

Returns:

  • (OrNode)

    alternation node



197
198
199
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 197

def or(other)
  OrNode.new(self, other)
end

#repeat(exactly = nil, min: nil, max: nil) ⇒ Node

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Repeats this node with optional min/max bounds.

Generates options with different repetition counts of this node. Without bounds, generates infinite options (use with limit).

Examples:

Fixed repetition

a = N('a')
aaa = a.repeat(3)  # exactly 3 times -- `exactly` is positional,
                   # so repeat(exactly: 3) is not accepted

Bounded repetition

a_range = a.repeat(min: 2, max: 4)  # 2, 3, or 4 times

Unbounded (use with limit)

a_any = a.repeat.limit { |o| o.size <= 5 }

Parameters:

  • exactly (Integer, nil) (defaults to: nil)

    exact repetition count

  • min (Integer, nil) (defaults to: nil)

    minimum repetitions

  • max (Integer, nil) (defaults to: nil)

    maximum repetitions

Returns:

  • (Node)

    node with repetition

Raises:

  • (ArgumentError)

    if both exactly and min/max are specified



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 226

def repeat(exactly = nil, min: nil, max: nil)
  raise ArgumentError, 'Only exactly value or min/max values are allowed' if exactly && (min || max)

  min = max = exactly if exactly

  if min && min > 0
    pre = self

    (min - 1).times do
      pre += self
    end
  end

  if pre && max == min
    pre
  elsif pre && max > min
    pre + RepeatNode.new(self, max - min)
  else
    RepeatNode.new(self, max)
  end
end

#sizeInteger Also known as: length

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Counts number of options generated by this node.

Returns:

  • (Integer)

    option count



378
379
380
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 378

def size
  options.size
end

#to_serie(flatten: true) {|option| ... } ⇒ Musa::Series::Serie Also known as: s

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts options to series.

Generates options and converts them to a Series::Serie.

Parameters:

  • flatten (Boolean) (defaults to: true)

    flatten nested series

Yield Parameters:

  • option (Array<OptionElement>)

    option so far -- PARTIAL as well as complete: the block is asked while the tree grows, not once at the end

Yield Returns:

  • (Boolean)

    true if this option may continue growing. A predicate that rejects the partials it passes through prunes them and never reaches the complete option it was written for

Returns:



409
410
411
412
413
414
# File 'lib/musa-dsl/generative/generative-grammar.rb', line 409

def to_serie(flatten: true, &condition)
  serie = _options(&condition).collect { |o| o.collect(&:content) }.to_serie(of_series: true).merge
  serie = serie.flatten if flatten

  serie.prototype
end