Class: Calyx::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/calyx/registry.rb

Overview

Lookup table of all the available rules in the grammar.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRegistry

Construct an empty registry.



7
8
9
10
11
# File 'lib/calyx/registry.rb', line 7

def initialize
  @rules = {}
  @transforms = {}
  @modifiers = Modifiers.new
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *arguments) ⇒ Object

Hook for defining rules without explicitly calling the ‘#rule` method.

Parameters:

  • name (Symbol)
  • productions (Array)


17
18
19
# File 'lib/calyx/registry.rb', line 17

def method_missing(name, *arguments)
  rule(name, *arguments)
end

Instance Attribute Details

#modifiersObject (readonly)

Returns the value of attribute modifiers.



4
5
6
# File 'lib/calyx/registry.rb', line 4

def modifiers
  @modifiers
end

#rulesObject (readonly)

Returns the value of attribute rules.



4
5
6
# File 'lib/calyx/registry.rb', line 4

def rules
  @rules
end

#transformsObject (readonly)

Returns the value of attribute transforms.



4
5
6
# File 'lib/calyx/registry.rb', line 4

def transforms
  @transforms
end

Instance Method Details

#combine(registry) ⇒ Object

Merges the given registry instance with the target registry.

This is only needed at compile time, so that child classes can easily inherit the set of rules decared by their parent.

Parameters:



110
111
112
# File 'lib/calyx/registry.rb', line 110

def combine(registry)
  @rules = rules.merge(registry.rules)
end

#evaluate(start_symbol = :start, random = Random.new, rules_map = {}) ⇒ Array

Evaluates the grammar defined in this registry, combining it with rules from the passed in context.

Produces a syntax tree of nested list nodes.

Parameters:

  • start_symbol (Symbol) (defaults to: :start)
  • random (Random) (defaults to: Random.new)
  • rules_map (Hash) (defaults to: {})

Returns:

  • (Array)


123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/calyx/registry.rb', line 123

def evaluate(start_symbol=:start, random=Random.new, rules_map={})
  reset_evaluation_context(random)

  rules_map.each do |key, value|
    if rules.key?(key.to_sym)
      raise Errors::DuplicateRule.new(key)
    end

    context[key.to_sym] = if value.is_a?(Array)
      Production::Choices.parse(value, self)
    else
      Production::Concat.parse(value.to_s, self)
    end
  end

  expansion = expand(start_symbol)

  if expansion.respond_to?(:evaluate)
    [start_symbol, expansion.evaluate(random)]
  else
    raise Errors::MissingRule.new(start_symbol)
  end
end

#expand(symbol) ⇒ Object

Expands the given rule symbol to its production.

Parameters:

  • symbol (Symbol)


59
60
61
# File 'lib/calyx/registry.rb', line 59

def expand(symbol)
  rules[symbol] || context[symbol]
end

#filter(name, callable = nil, &block) ⇒ Object

Registers the given block as a string filter.

Parameters:

  • name (Symbol)


40
41
42
43
44
45
46
# File 'lib/calyx/registry.rb', line 40

def filter(name, callable=nil, &block)
  if block_given?
    transforms[name.to_sym] = block
  else
    transforms[name.to_sym] = callable
  end
end

#mapping(name, pairs) ⇒ Object

Registers a paired mapping regex.

Parameters:

  • name (Symbol)
  • pairs (Hash<Regex,String>)


32
33
34
# File 'lib/calyx/registry.rb', line 32

def mapping(name, pairs)
  transforms[name.to_sym] = construct_mapping(pairs)
end

#memoize_expansion(symbol) ⇒ Object

Expands a memoized rule symbol by evaluating it and storing the result for later.

Parameters:

  • symbol (Symbol)


80
81
82
# File 'lib/calyx/registry.rb', line 80

def memoize_expansion(symbol)
  memos[symbol] ||= expand(symbol).evaluate(@random)
end

#modifier(name) ⇒ Object

Attaches a modifier module to this instance.

Parameters:

  • module_name (Module)


24
25
26
# File 'lib/calyx/registry.rb', line 24

def modifier(name)
  modifiers.extend(name)
end

#rule(name, *productions) ⇒ Object

Registers a new grammar rule.

Parameters:

  • name (Symbol)
  • productions (Array)


52
53
54
# File 'lib/calyx/registry.rb', line 52

def rule(name, *productions)
  rules[name.to_sym] = construct_rule(productions)
end

#transform(name, value) ⇒ String

Applies the given modifier function to the given value to transform it.

Parameters:

  • name (Symbol)
  • value (String)

Returns:

  • (String)


68
69
70
71
72
73
74
# File 'lib/calyx/registry.rb', line 68

def transform(name, value)
  if transforms.key?(name)
    transforms[name].call(value)
  else
    modifiers.transform(name, value)
  end
end

#unique_expansion(symbol) ⇒ Object

Expands a unique rule symbol by evaluating it and checking that it hasn’t previously been selected.

Parameters:

  • symbol (Symbol)


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/calyx/registry.rb', line 88

def unique_expansion(symbol)
  pending = true
  uniques[symbol] = [] if uniques[symbol].nil?

  while pending
    result = expand(symbol).evaluate(@random)

    unless uniques[symbol].include?(result)
      uniques[symbol] << result
      pending = false
    end
  end

  result
end