Class: Calyx::Grammar

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

Overview

The main public interface to Calyx. Grammars represent the concept of a template grammar defined by a set of production rules that can be chained and nested from a given starting rule.

Calyx works like a traditional phrase-structured grammar in reverse. Instead of recognising strings based on a union of possible matches, it generates strings by representing the union as a choice and randomly picking one of the options each time the grammar runs.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &block) ⇒ Grammar

Create a new grammar instance, passing in a random seed if needed.

Grammar rules can be constructed on the fly when the passed-in block is evaluated.

Parameters:

  • options (Numeric, Random, Hash) (defaults to: {})


115
116
117
118
119
120
121
122
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/grammar.rb', line 115

def initialize(options={}, &block)
  unless options.is_a?(Hash)
    config_opts = {}
    if options.is_a?(Numeric)
      warn [
        "NOTE: Passing a numeric seed arg directly is deprecated. ",
        "Use the options hash instead: `Calyx::Grammar.new(seed: 1234)`"
      ].join
      config_opts[:seed] = options
    elsif options.is_a?(Random)
      warn [
        "NOTE: Passing a Random object directly is deprecated. ",
        "Use the options hash instead: `Calyx::Grammar.new(rng: Random.new)`"
      ].join
      config_opts[:rng] = options
    end
  else
    config_opts = options
  end

  @options = Options.new(config_opts)

  if block_given?
    @registry = Registry.new
    @registry.instance_eval(&block)
  else
    @registry = self.class.registry
  end

  @registry.options(@options)
end

Class Method Details

.filter(name) {|the| ... } ⇒ Object

DSL helper method for registering the given block as a string filter.

Parameters:

  • name (Symbol)

Yield Parameters:

  • the (String)

    input string to be processed by the filter

Yield Returns:

  • (String)

    the processed output string



60
61
62
63
64
65
66
# File 'lib/calyx/grammar.rb', line 60

def filter(name, &block)
  warn [
    "NOTE: The fixed `filter` class method is deprecated.",
    "This will be removed in 0.22. Use the API for modifers instead."
  ].join
  registry.filter(name, &block)
end

.inherit_registry(child_registry) ⇒ Object

Hook for combining the registry of a parent grammar into the child that inherits from it.

Parameters:



94
95
96
# File 'lib/calyx/grammar.rb', line 94

def inherit_registry(child_registry)
  registry.combine(child_registry) unless child_registry.nil?
end

.inherited(subclass) ⇒ Object

Hook for combining the rules from a parent grammar into the child that inherits from it.

This is automatically called by the Ruby engine.

Parameters:

  • subclass (Class)


104
105
106
# File 'lib/calyx/grammar.rb', line 104

def inherited(subclass)
  subclass.inherit_registry(registry)
end

.load(filename) ⇒ Calyx::Grammar

Load a grammar instance from the given file.

Accepts a JSON or YAML file path, identified by its extension (‘.json` or `.yml`).

Parameters:

  • filename (String)

Returns:



28
29
30
# File 'lib/calyx/grammar.rb', line 28

def load(filename)
  Format.load(filename)
end

.mapping(name, pairs) ⇒ Object

DSL helper method for registering a paired mapping regex.

Parameters:

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


47
48
49
50
51
52
53
# File 'lib/calyx/grammar.rb', line 47

def mapping(name, pairs)
  warn [
    "NOTE: The fixed `mapping` class method is deprecated.",
    "This still works but will be replaced with a new mapping format."
  ].join
  registry.mapping(name, pairs)
end

.method_missing(name, *productions) ⇒ Object

Augument the grammar with a method missing hook that treats class method calls as declarations of a new rule.

This must be bypassed by calling ‘#rule` directly if the name of the desired rule clashes with an existing helper method.

Parameters:

  • name (Symbol)
  • productions (Array)


86
87
88
# File 'lib/calyx/grammar.rb', line 86

def method_missing(name, *productions)
  registry.define_rule(name, caller_locations.first, productions)
end

.modifier(module_name) ⇒ Object

DSL helper method for registering a modifier module with the grammar.

Parameters:

  • module_name (Module)


35
36
37
38
39
40
41
# File 'lib/calyx/grammar.rb', line 35

def modifier(module_name)
  warn [
    "NOTE: Loading modifiers via grammar class methods is deprecated.",
    "Alternative API TBD. For now this method still works."
  ].join
  registry.modifier(module_name)
end

.registryCalyx::Registry

Access the registry belonging to this grammar class.

Constructs a new registry if it isn’t already available.

Returns:



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

def registry
  @registry ||= Registry.new
end

.rule(name, *productions) ⇒ Object

DSL helper method for registering a new grammar rule.

Not usually used directly, as the method missing API is less verbose.

Parameters:

  • name (Symbol)
  • productions (Array)


74
75
76
# File 'lib/calyx/grammar.rb', line 74

def rule(name, *productions)
  registry.define_rule(name, caller_locations.first, productions)
end

Instance Method Details

#evaluate(*args) ⇒ Object

Deprecated.

Please use #generate_result instead.

Produces a syntax tree of nested list nodes as an output of the grammar.



165
166
167
168
169
170
171
172
173
174
# File 'lib/calyx/grammar.rb', line 165

def evaluate(*args)
  warn <<~DEPRECATION
    [DEPRECATION] `evaluate` is deprecated and will be removed in 1.0.
    Please use #generate_result instead.
    See https://github.com/maetl/calyx/issues/23 for more details.
  DEPRECATION

  result = generate_result(*args)
  result.tree
end

#generate(start_symbol) ⇒ String #generate(rules_map) ⇒ String #generate(start_symbol, rules_map) ⇒ String

Produces a string as an output of the grammar.

Overloads:

  • #generate(start_symbol) ⇒ String

    Parameters:

    • start_symbol (Symbol)
  • #generate(rules_map) ⇒ String

    Parameters:

    • rules_map (Hash)
  • #generate(start_symbol, rules_map) ⇒ String

    Parameters:

    • start_symbol (Symbol)
    • rules_map (Hash)

Returns:

  • (String)


157
158
159
160
# File 'lib/calyx/grammar.rb', line 157

def generate(*args)
  result = generate_result(*args)
  result.text
end

#generate_result(start_symbol) ⇒ Calyx::Result #generate_result(rules_map) ⇒ Calyx::Result #generate_result(start_symbol, rules_map) ⇒ Calyx::Result

Produces a generated result from evaluating the grammar.

Overloads:

  • #generate_result(start_symbol) ⇒ Calyx::Result

    Parameters:

    • start_symbol (Symbol)
  • #generate_result(rules_map) ⇒ Calyx::Result

    Parameters:

    • rules_map (Hash)
  • #generate_result(start_symbol, rules_map) ⇒ Calyx::Result

    Parameters:

    • start_symbol (Symbol)
    • rules_map (Hash)

Returns:

See Also:



187
188
189
190
191
# File 'lib/calyx/grammar.rb', line 187

def generate_result(*args)
  start_symbol, rules_map = map_default_args(*args)

  Result.new(@registry.evaluate(start_symbol, rules_map))
end