calyx 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba09252aa5dedcc03c190a14c68be4eb446fc01c
4
- data.tar.gz: cf7c1287f4dcfbc35682d74a1f83d3f7eeb8b2a4
3
+ metadata.gz: 5b983f729355f2a8ee4266d2d2564c041f4d3fd5
4
+ data.tar.gz: 2815d2887cefe608c285537b8ef1cd9d34204497
5
5
  SHA512:
6
- metadata.gz: 670da35d3148a5aaaba3eb81edd7ba9635f3667cc2c1f6288b64cf2f79cafbc2649f752799911e8156609887f9fa260a95bb29765e9342b23bf5ca4f1fa87bca
7
- data.tar.gz: 013ab7c2761b8db39e3748fd80602cecbcefe547c1802ccf703a4e459f880d54c0104b502c0798bb9048bcee63e7cf380bf1e6f4d434a04c2bf422e72bfd4200
6
+ metadata.gz: f0a44222fd6aed60b2ae457e4e0b3cf3b9cae69c7433853f198420a4b9fd2091199a1d379c9c3e64eff281cc0dc39bb61ada8d366304f25319ddb12a5a2319f0
7
+ data.tar.gz: 565bfb3335ef9c3c87c2769da6c7f1276432998bcd2b6cf273eda62536f8dcd62123005f4a1aaf5d1cc55882a0119c8fb682df1d0717fad07a8344662e0c08a0
data/lib/calyx.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'calyx/version'
2
+ require 'calyx/options'
2
3
  require 'calyx/rule'
3
4
  require 'calyx/grammar'
4
5
  require 'calyx/errors'
data/lib/calyx/grammar.rb CHANGED
@@ -99,40 +99,36 @@ module Calyx
99
99
  # evaluated.
100
100
  #
101
101
  # @param [Numeric, Random, Hash] options
102
- def initialize(options={}, &block)
103
- unless options.is_a?(Hash)
102
+ def initialize(opts={}, &block)
103
+ unless opts.is_a?(Hash)
104
104
  config_opts = {}
105
- if options.is_a?(Numeric)
105
+ if opts.is_a?(Numeric)
106
106
  warn [
107
107
  "NOTE: Passing a numeric seed arg directly is deprecated. ",
108
108
  "Use the options hash instead: `Calyx::Grammar.new(seed: 1234)`"
109
109
  ].join
110
- config_opts[:seed] = options
111
- elsif options.is_a?(Random)
110
+ config_opts[:seed] = opts
111
+ elsif opts.is_a?(Random)
112
112
  warn [
113
113
  "NOTE: Passing a Random object directly is deprecated. ",
114
114
  "Use the options hash instead: `Calyx::Grammar.new(rng: Random.new)`"
115
115
  ].join
116
- config_opts[:rng] = options
116
+ config_opts[:rng] = opts
117
117
  end
118
118
  else
119
- config_opts = options.dup
119
+ config_opts = opts
120
120
  end
121
121
 
122
- @random = if config_opts.key?(:seed)
123
- Random.new(config_opts[:seed])
124
- elsif config_opts.key?(:rng)
125
- config_opts[:rng]
126
- else
127
- Random.new
128
- end
122
+ @options = Options.new(config_opts)
129
123
 
130
124
  if block_given?
131
- @registry = Registry.new(config_opts)
125
+ @registry = Registry.new
132
126
  @registry.instance_eval(&block)
133
127
  else
134
128
  @registry = self.class.registry
135
129
  end
130
+
131
+ @registry.options(@options)
136
132
  end
137
133
 
138
134
  # Produces a string as an output of the grammar.
@@ -144,7 +140,7 @@ module Calyx
144
140
  def generate(*args)
145
141
  start_symbol, rules_map = map_default_args(*args)
146
142
 
147
- @registry.evaluate(start_symbol, @random, rules_map).flatten.reject do |obj|
143
+ @registry.evaluate(start_symbol, rules_map).flatten.reject do |obj|
148
144
  obj.is_a?(Symbol)
149
145
  end.join
150
146
  end
@@ -158,7 +154,7 @@ module Calyx
158
154
  def evaluate(*args)
159
155
  start_symbol, rules_map = map_default_args(*args)
160
156
 
161
- @registry.evaluate(start_symbol, @random, rules_map)
157
+ @registry.evaluate(start_symbol, rules_map)
162
158
  end
163
159
 
164
160
  private
@@ -0,0 +1,35 @@
1
+ module Calyx
2
+ class Options
3
+ DEFAULTS = {
4
+ strict: true
5
+ }
6
+
7
+ def initialize(opts={})
8
+ @options = DEFAULTS.merge(opts)
9
+ end
10
+
11
+ def rng
12
+ unless @options[:rng]
13
+ @options[:rng] = if @options[:seed]
14
+ Random.new(@options[:seed])
15
+ else
16
+ Random.new
17
+ end
18
+ end
19
+
20
+ @options[:rng]
21
+ end
22
+
23
+ def strict?
24
+ @options[:strict]
25
+ end
26
+
27
+ def merge(opts)
28
+ Options.new(@options.merge(opts.to_h))
29
+ end
30
+
31
+ def to_h
32
+ @options
33
+ end
34
+ end
35
+ end
@@ -36,10 +36,10 @@ module Calyx
36
36
 
37
37
  # Evaluate the choice by randomly picking one of its possible options.
38
38
  #
39
- # @param [Random] random
39
+ # @param [Calyx::Options] options
40
40
  # @return [Array]
41
- def evaluate(random)
42
- [:choice, @collection.sample(random: random).evaluate(random)]
41
+ def evaluate(options)
42
+ [:choice, @collection.sample(random: options.rng).evaluate(options)]
43
43
  end
44
44
  end
45
45
  end
@@ -52,11 +52,11 @@ module Calyx
52
52
  # Evaluate all the child nodes of this node and concatenate them together
53
53
  # into a single result.
54
54
  #
55
- # @param [Random] random
55
+ # @param [Calyx::Options] options
56
56
  # @return [Array]
57
- def evaluate(random)
57
+ def evaluate(options)
58
58
  concat = @expansion.reduce([]) do |exp, atom|
59
- exp << atom.evaluate(random)
59
+ exp << atom.evaluate(options)
60
60
  end
61
61
 
62
62
  [:concat, concat]
@@ -17,10 +17,10 @@ module Calyx
17
17
  # terminal string, then passing it through the given modifier chain and
18
18
  # returning the transformed result.
19
19
  #
20
- # @param [Random] random
20
+ # @param [Calyx::Options] options
21
21
  # @return [Array]
22
- def evaluate(random)
23
- terminal = @production.evaluate(random).flatten.reject { |o| o.is_a?(Symbol) }.join
22
+ def evaluate(options)
23
+ terminal = @production.evaluate(options).flatten.reject { |o| o.is_a?(Symbol) }.join
24
24
  expression = @methods.reduce(terminal) do |value, method|
25
25
  @registry.transform(method, value)
26
26
  end
@@ -17,9 +17,9 @@ module Calyx
17
17
 
18
18
  # Evaluate the memo, using the registry to handle the expansion.
19
19
  #
20
- # @param [Random] random
20
+ # @param [Calyx::Options] options
21
21
  # @return [Array]
22
- def evaluate(random)
22
+ def evaluate(options)
23
23
  [@symbol, @registry.memoize_expansion(@symbol)]
24
24
  end
25
25
  end
@@ -15,10 +15,10 @@ module Calyx
15
15
 
16
16
  # Evaluate the non-terminal, using the registry to handle the expansion.
17
17
  #
18
- # @param [Random] random
18
+ # @param [Calyx::Options] options
19
19
  # @return [Array]
20
- def evaluate(random)
21
- [@symbol, @registry.expand(@symbol).evaluate(random)]
20
+ def evaluate(options)
21
+ [@symbol, @registry.expand(@symbol).evaluate(options)]
22
22
  end
23
23
  end
24
24
  end
@@ -11,9 +11,9 @@ module Calyx
11
11
 
12
12
  # Evaluate the terminal by returning its identity directly.
13
13
  #
14
- # @param [Random] random
14
+ # @param [Calyx::Options] options
15
15
  # @return [Array]
16
- def evaluate(random)
16
+ def evaluate(options)
17
17
  [:atom, @atom]
18
18
  end
19
19
  end
@@ -22,9 +22,9 @@ module Calyx
22
22
  # Evaluate the unique rule, using the registry to handle the expansion
23
23
  # and keep track of previous selections.
24
24
  #
25
- # @param [Random] random
25
+ # @param [Calyx::Options] options
26
26
  # @return [Array]
27
- def evaluate(random)
27
+ def evaluate(options)
28
28
  [@symbol, @registry.unique_expansion(@symbol)]
29
29
  end
30
30
  end
@@ -40,14 +40,14 @@ module Calyx
40
40
  # The method for selecting weighted probabilities is based on a snippet
41
41
  # of code recommended in the Ruby standard library documentation.
42
42
  #
43
- # @param [Random] random
43
+ # @param [Calyx::Options] options
44
44
  # @return [Array]
45
- def evaluate(random)
45
+ def evaluate(options)
46
46
  choice = @collection.max_by do |_, weight|
47
- random.rand ** (1.0 / weight)
47
+ options.rng.rand ** (1.0 / weight)
48
48
  end.first
49
49
 
50
- [:weighted_choice, choice.evaluate(random)]
50
+ [:weighted_choice, choice.evaluate(options)]
51
51
  end
52
52
  end
53
53
  end
@@ -4,13 +4,20 @@ module Calyx
4
4
  attr_reader :rules, :transforms, :modifiers
5
5
 
6
6
  # Construct an empty registry.
7
- def initialize(options={})
8
- @options = {}
7
+ def initialize
8
+ @options = Options.new({})
9
9
  @rules = {}
10
10
  @transforms = {}
11
11
  @modifiers = Modifiers.new
12
12
  end
13
13
 
14
+ # Applies additional config options to this instance.
15
+ #
16
+ # @param [Options] opts
17
+ def options(opts)
18
+ @options = @options.merge(opts)
19
+ end
20
+
14
21
  # Attaches a modifier module to this instance.
15
22
  #
16
23
  # @param [Module] module_name
@@ -77,7 +84,15 @@ module Calyx
77
84
  # @return [Calyx::Rule]
78
85
  def expand(symbol)
79
86
  expansion = rules[symbol] || context[symbol]
80
- raise Errors::UndefinedRule.new(@last_expansion, symbol) if expansion.nil?
87
+
88
+ if expansion.nil?
89
+ if @options.strict?
90
+ raise Errors::UndefinedRule.new(@last_expansion, symbol)
91
+ else
92
+ expansion = Production::Terminal.new('')
93
+ end
94
+ end
95
+
81
96
  @last_expansion = expansion
82
97
  expansion
83
98
  end
@@ -100,7 +115,7 @@ module Calyx
100
115
  #
101
116
  # @param [Symbol] symbol
102
117
  def memoize_expansion(symbol)
103
- memos[symbol] ||= expand(symbol).evaluate(@random)
118
+ memos[symbol] ||= expand(symbol).evaluate(@options)
104
119
  end
105
120
 
106
121
  # Expands a unique rule symbol by evaluating it and checking that it hasn't
@@ -112,7 +127,7 @@ module Calyx
112
127
  uniques[symbol] = [] if uniques[symbol].nil?
113
128
 
114
129
  while pending
115
- result = expand(symbol).evaluate(@random)
130
+ result = expand(symbol).evaluate(@options)
116
131
 
117
132
  unless uniques[symbol].include?(result)
118
133
  uniques[symbol] << result
@@ -142,8 +157,8 @@ module Calyx
142
157
  # @param [Random] random
143
158
  # @param [Hash] rules_map
144
159
  # @return [Array]
145
- def evaluate(start_symbol=:start, random=Random.new, rules_map={})
146
- reset_evaluation_context(random)
160
+ def evaluate(start_symbol=:start, rules_map={})
161
+ reset_evaluation_context
147
162
 
148
163
  rules_map.each do |key, value|
149
164
  if rules.key?(key.to_sym)
@@ -153,15 +168,14 @@ module Calyx
153
168
  define_context_rule(key, caller_locations.last, value)
154
169
  end
155
170
 
156
- [start_symbol, expand(start_symbol).evaluate(random)]
171
+ [start_symbol, expand(start_symbol).evaluate(@options)]
157
172
  end
158
173
 
159
174
  private
160
175
 
161
- attr_reader :random, :memos, :context, :uniques
176
+ attr_reader :memos, :context, :uniques
162
177
 
163
- def reset_evaluation_context(random)
164
- @random = random
178
+ def reset_evaluation_context
165
179
  @context = {}
166
180
  @memos = {}
167
181
  @uniques = {}
data/lib/calyx/rule.rb CHANGED
@@ -10,8 +10,8 @@ module Calyx
10
10
  @trace = trace
11
11
  end
12
12
 
13
- def evaluate(random)
14
- productions.evaluate(random)
13
+ def evaluate(options)
14
+ productions.evaluate(options)
15
15
  end
16
16
  end
17
17
  end
data/lib/calyx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Calyx
2
- VERSION = '0.15.0'.freeze
2
+ VERSION = '0.15.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calyx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Rickerby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-27 00:00:00.000000000 Z
11
+ date: 2017-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,6 +76,7 @@ files:
76
76
  - lib/calyx/format.rb
77
77
  - lib/calyx/grammar.rb
78
78
  - lib/calyx/modifiers.rb
79
+ - lib/calyx/options.rb
79
80
  - lib/calyx/production/choices.rb
80
81
  - lib/calyx/production/concat.rb
81
82
  - lib/calyx/production/expression.rb