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: {})


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/calyx/grammar.rb', line 103

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



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

def filter(name, &block)
  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:



82
83
84
# File 'lib/calyx/grammar.rb', line 82

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)


92
93
94
# File 'lib/calyx/grammar.rb', line 92

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>)


43
44
45
# File 'lib/calyx/grammar.rb', line 43

def mapping(name, pairs)
  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)


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

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
# File 'lib/calyx/grammar.rb', line 35

def modifier(module_name)
  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)


62
63
64
# File 'lib/calyx/grammar.rb', line 62

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.



153
154
155
156
157
158
159
160
161
162
# File 'lib/calyx/grammar.rb', line 153

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)


145
146
147
148
# File 'lib/calyx/grammar.rb', line 145

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:



175
176
177
178
179
# File 'lib/calyx/grammar.rb', line 175

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

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