calyx 0.10.4 → 0.11.0
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 +4 -4
- data/README.md +79 -2
- data/lib/calyx.rb +2 -2
- data/lib/calyx/errors.rb +9 -1
- data/lib/calyx/format.rb +37 -0
- data/lib/calyx/grammar.rb +4 -0
- data/lib/calyx/{modifier.rb → modifiers.rb} +1 -1
- data/lib/calyx/registry.rb +9 -7
- data/lib/calyx/version.rb +1 -1
- metadata +4 -4
- data/lib/calyx/file_converter.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a89c9fc6b0ecc0e8779331da13072f11d810eab
|
4
|
+
data.tar.gz: 8a74d06ae8feb2e547426fbf893a3d2922010f29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c178d2441191f82aa308ae5d8599bb904a68128daa636435830b6ec58443cfa3ea1dd9a8e534b206442d658542f4aae8a5d906b9cd0677e22db7e983116529f9
|
7
|
+
data.tar.gz: 8ba8bb5db4ed05e66d9c1fb19986282607d6cbd10fac4de6ed70a18be5ae08b39367fd3931fd8c485b6bfc7687aae7610817547a6668b6de94a078fb843b240e
|
data/README.md
CHANGED
@@ -181,6 +181,8 @@ class Fruit < Calyx::Grammar
|
|
181
181
|
end
|
182
182
|
```
|
183
183
|
|
184
|
+
## String Modifiers
|
185
|
+
|
184
186
|
Dot-notation is supported in template expressions, allowing you to call any available method on the `String` object returned from a rule. Formatting methods can be chained arbitrarily and will execute in the same way as they would in native Ruby code.
|
185
187
|
|
186
188
|
```ruby
|
@@ -193,7 +195,77 @@ end
|
|
193
195
|
# => "Why, hello there."
|
194
196
|
```
|
195
197
|
|
196
|
-
|
198
|
+
You can also extend the grammar with custom modifiers that provide useful formatting functions.
|
199
|
+
|
200
|
+
### Filters
|
201
|
+
|
202
|
+
Filters accept an input string and return the transformed output:
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
class Greeting < Calyx::Grammar
|
206
|
+
filter :shoutycaps do |input|
|
207
|
+
input.upcase
|
208
|
+
end
|
209
|
+
start '{hello.shoutycaps} there.', 'Why, {hello} there.'
|
210
|
+
rule :hello, 'hello'
|
211
|
+
end
|
212
|
+
|
213
|
+
# => "HELLO there."
|
214
|
+
# => "Why, HELLO there."
|
215
|
+
```
|
216
|
+
|
217
|
+
### Mappings
|
218
|
+
|
219
|
+
The mapping shortcut allows you to specify a map of regex patterns pointing to their resulting substitution strings:
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
class GreenBottle < Calyx::Grammar
|
223
|
+
mapping :pluralize, /(.+)/ => '\\1s'
|
224
|
+
start 'One green {bottle}.', 'Two green {bottle.pluralize}.'
|
225
|
+
rule :bottle, 'bottle'
|
226
|
+
end
|
227
|
+
|
228
|
+
# => "One green bottle."
|
229
|
+
# => "Two green bottles."
|
230
|
+
```
|
231
|
+
|
232
|
+
### Modifier Mixins
|
233
|
+
|
234
|
+
In order to use more intricate natural language processing capabilities, you can add modifier methods to a module and extend the grammar with it:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
module FullStop
|
238
|
+
def full_stop
|
239
|
+
self << '.'
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
class Hello < Calyx::Grammar
|
244
|
+
modifier FullStop
|
245
|
+
start '{hello.capitalize.full_stop}'
|
246
|
+
rule :hello, 'hello'
|
247
|
+
end
|
248
|
+
|
249
|
+
# => "Hello."
|
250
|
+
```
|
251
|
+
|
252
|
+
To share custom modifiers across multiple grammars, you can include the module in `Calyx::Modifiers`. This will make the methods available to all subsequent instances:
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
module FullStop
|
256
|
+
def full_stop
|
257
|
+
self << '.'
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
class Calyx::Modifiers
|
262
|
+
include FullStop
|
263
|
+
end
|
264
|
+
```
|
265
|
+
|
266
|
+
### Monkeypatching String
|
267
|
+
|
268
|
+
Alternatively, you can combine methods from existing Gems that monkeypatch `String`:
|
197
269
|
|
198
270
|
```ruby
|
199
271
|
require 'indefinite_article'
|
@@ -305,7 +377,12 @@ Rough plan for stabilising the API and features for a `1.0` release.
|
|
305
377
|
|
306
378
|
## Credits
|
307
379
|
|
308
|
-
|
380
|
+
### Author & Maintainer
|
381
|
+
|
382
|
+
- [Mark Rickerby](https://github.com/maetl)
|
383
|
+
|
384
|
+
### Contributors
|
385
|
+
|
309
386
|
- [Tariq Ali](https://github.com/tra38)
|
310
387
|
|
311
388
|
## License
|
data/lib/calyx.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'calyx/version'
|
2
2
|
require 'calyx/grammar'
|
3
3
|
require 'calyx/errors'
|
4
|
-
require 'calyx/
|
4
|
+
require 'calyx/format'
|
5
5
|
require 'calyx/registry'
|
6
|
-
require 'calyx/
|
6
|
+
require 'calyx/modifiers'
|
7
7
|
require 'calyx/production/memo'
|
8
8
|
require 'calyx/production/choices'
|
9
9
|
require 'calyx/production/concat'
|
data/lib/calyx/errors.rb
CHANGED
data/lib/calyx/format.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Calyx
|
2
|
+
module Format
|
3
|
+
def self.load(filename)
|
4
|
+
file = File.read(filename)
|
5
|
+
extension = File.extname(filename)
|
6
|
+
if extension == ".yml"
|
7
|
+
self.load_yml(file)
|
8
|
+
elsif extension == ".json"
|
9
|
+
self.load_json(file)
|
10
|
+
else
|
11
|
+
raise "Cannot convert #{extension} files."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.load_yml(file)
|
16
|
+
require 'yaml'
|
17
|
+
yaml = YAML.load(file)
|
18
|
+
self.build_grammar(yaml)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load_json(file)
|
22
|
+
require 'json'
|
23
|
+
json = JSON.parse(file)
|
24
|
+
self.build_grammar(json)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.build_grammar(rules)
|
30
|
+
Calyx::Grammar.new do
|
31
|
+
rules.each do |label, productions|
|
32
|
+
rule(label, *productions)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/calyx/grammar.rb
CHANGED
data/lib/calyx/registry.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module Calyx
|
2
2
|
class Registry
|
3
|
-
attr_reader :rules, :transforms
|
3
|
+
attr_reader :rules, :transforms, :modifiers
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@rules = {}
|
7
7
|
@transforms = {}
|
8
|
-
@
|
8
|
+
@modifiers = Modifiers.new
|
9
9
|
end
|
10
10
|
|
11
11
|
def method_missing(name, *arguments)
|
@@ -13,7 +13,7 @@ module Calyx
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def modifier(name)
|
16
|
-
|
16
|
+
modifiers.extend_with(name)
|
17
17
|
end
|
18
18
|
|
19
19
|
def mapping(name, pairs)
|
@@ -40,7 +40,7 @@ module Calyx
|
|
40
40
|
if transforms.key?(name)
|
41
41
|
transforms[name].call(value)
|
42
42
|
else
|
43
|
-
|
43
|
+
modifiers.transform(name, value)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -57,7 +57,7 @@ module Calyx
|
|
57
57
|
|
58
58
|
rules_map.each do |key, value|
|
59
59
|
if rules.key?(key.to_sym)
|
60
|
-
raise
|
60
|
+
raise Error::DuplicateRule.new(key)
|
61
61
|
end
|
62
62
|
|
63
63
|
context[key.to_sym] = if value.is_a?(Array)
|
@@ -72,7 +72,7 @@ module Calyx
|
|
72
72
|
if expansion.respond_to?(:evaluate)
|
73
73
|
[start_symbol, expansion.evaluate]
|
74
74
|
else
|
75
|
-
raise RuleNotFound.new(start_symbol)
|
75
|
+
raise Errors::RuleNotFound.new(start_symbol)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -93,7 +93,9 @@ module Calyx
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def construct_rule(productions)
|
96
|
-
if productions.first.is_a?(
|
96
|
+
if productions.first.is_a?(Hash)
|
97
|
+
Production::WeightedChoices.parse(productions.first.to_a, self)
|
98
|
+
elsif productions.first.is_a?(Enumerable)
|
97
99
|
Production::WeightedChoices.parse(productions, self)
|
98
100
|
else
|
99
101
|
Production::Choices.parse(productions, self)
|
data/lib/calyx/version.rb
CHANGED
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.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Rickerby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -69,9 +69,9 @@ files:
|
|
69
69
|
- examples/tiny_woodland.rb
|
70
70
|
- lib/calyx.rb
|
71
71
|
- lib/calyx/errors.rb
|
72
|
-
- lib/calyx/
|
72
|
+
- lib/calyx/format.rb
|
73
73
|
- lib/calyx/grammar.rb
|
74
|
-
- lib/calyx/
|
74
|
+
- lib/calyx/modifiers.rb
|
75
75
|
- lib/calyx/production/choices.rb
|
76
76
|
- lib/calyx/production/concat.rb
|
77
77
|
- lib/calyx/production/expression.rb
|
data/lib/calyx/file_converter.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module Calyx
|
5
|
-
class Grammar
|
6
|
-
class << self
|
7
|
-
def load(filename)
|
8
|
-
file = File.read(filename)
|
9
|
-
extension = File.extname(filename)
|
10
|
-
if extension == ".yml"
|
11
|
-
load_yml(file)
|
12
|
-
elsif extension == ".json"
|
13
|
-
load_json(file)
|
14
|
-
else
|
15
|
-
raise "Cannot convert #{extension} files."
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def load_yml(file)
|
20
|
-
yaml = YAML.load(file)
|
21
|
-
build_grammar(yaml)
|
22
|
-
end
|
23
|
-
|
24
|
-
def load_json(file)
|
25
|
-
json = JSON.parse(file)
|
26
|
-
build_grammar(json)
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def build_grammar(rules)
|
32
|
-
Calyx::Grammar.new do
|
33
|
-
rules.each do |label, productions|
|
34
|
-
rule(label, *productions)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|