calyx 0.15.0 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
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