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:



90
91
92
# File 'lib/calyx/registry.rb', line 90

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

#evaluate(start_symbol = :start, rng = 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)
  • rules_map (Hash) (defaults to: {})

Returns:

  • (Array)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/calyx/registry.rb', line 102

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

  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(rng)]
  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(@rng)
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