jsgf 0.4.1 → 0.5
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 +12 -2
- data/jsgf.gemspec +1 -1
- data/lib/jsgf/alternation.rb +6 -1
- data/lib/jsgf/atom.rb +16 -2
- data/lib/jsgf/builder.rb +26 -2
- data/lib/jsgf/grammar.rb +2 -4
- data/lib/jsgf/parser.rb +1 -1
- data/lib/jsgf/rule.rb +5 -3
- data/test/jsgf/builder.rb +115 -9
- data/test/jsgf/parser.rb +2 -2
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc08df8d2819a5f14a5c0a037dc0cf1b6c337e0b
|
4
|
+
data.tar.gz: d605f5c4211fce201299b52fb824e90d7148034e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09e2f534bf4bfeff71a197b21b83f816b7311a8c2242f7815bf3e5ace6ae158da5ec95af03c5a8995aceb53c3440e8275d3a3531ae8295d1159c6aa3eefada3d
|
7
|
+
data.tar.gz: d90cf4b5c10039c20282d533393ffb2e9eb8e138a4c8cb98bb6c5b4e08f9e29642b133cd1cd24f1ced87b08da44fda4a3cbb88e4db4c90ac8f188f73ec7b1e40
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@ JSGF
|
|
3
3
|
|
4
4
|
[](https://travis-ci.org/bfoz/jsgf-ruby)
|
5
5
|
[](http://badge.fury.io/rb/jsgf)
|
6
|
+
[](http://www.rubydoc.info/gems/jsgf/frames)
|
6
7
|
|
7
8
|
For all of your [Java Speech Grammar Format](http://www.w3.org/TR/jsgf/) parsing needs.
|
8
9
|
|
@@ -37,7 +38,7 @@ The JSGF gem includes a simple DSL for generating new grammars. The syntax follo
|
|
37
38
|
the [JSGF](http://www.w3.org/TR/jsgf/) syntax, but with a few differences.
|
38
39
|
|
39
40
|
- Rule names can be either Symbols or Strings (they're converted to Strings internally)
|
40
|
-
- Rules can be referenced using symbols in addition to the angle-bracket syntax used by JSGF
|
41
|
+
- Rules can be referenced using symbols in addition to the angle-bracket syntax used by JSGF
|
41
42
|
- Alternations are created using arrays
|
42
43
|
- Rules are private by default, however the root rules are automatically made public
|
43
44
|
|
@@ -51,6 +52,15 @@ grammar = JSGF.grammar 'Turtle' do
|
|
51
52
|
end
|
52
53
|
```
|
53
54
|
|
55
|
+
Atoms can be made optional using the JSGF square-bracket syntax...
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
grammar = JSGF.grammar 'PoliteTurtle' do
|
59
|
+
rule move: '[please] go :direction :distance'
|
60
|
+
...
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
54
64
|
Installation
|
55
65
|
------------
|
56
66
|
|
@@ -71,4 +81,4 @@ Or install it yourself as:
|
|
71
81
|
License
|
72
82
|
-------
|
73
83
|
|
74
|
-
Copyright 2015 Brandon Fosdick <bfoz@bfoz.net> and released under the BSD license.
|
84
|
+
Copyright 2015-2016 Brandon Fosdick <bfoz@bfoz.net> and released under the BSD license.
|
data/jsgf.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "jsgf"
|
7
|
-
spec.version = '0.
|
7
|
+
spec.version = '0.5'
|
8
8
|
spec.authors = ["Brandon Fosdick"]
|
9
9
|
spec.email = ["bfoz@bfoz.net"]
|
10
10
|
spec.summary = %q{Java Speech Grammar Format}
|
data/lib/jsgf/alternation.rb
CHANGED
@@ -5,14 +5,19 @@ module JSGF
|
|
5
5
|
include Enumerable
|
6
6
|
|
7
7
|
attr_reader :elements
|
8
|
+
|
9
|
+
# @!attribute
|
10
|
+
# @return [Bool] Sometimes an {Alternation} is optional
|
8
11
|
attr_accessor :optional
|
12
|
+
alias optional? optional
|
13
|
+
|
9
14
|
attr_reader :tags
|
10
15
|
|
11
16
|
def initialize(*args)
|
12
17
|
@elements = args.map do |a|
|
13
18
|
case a
|
14
19
|
when String then Rule.parse_atom(a)
|
15
|
-
when Symbol then
|
20
|
+
when Symbol then JSGF::Atom.new(a.to_s, reference:true)
|
16
21
|
else
|
17
22
|
a
|
18
23
|
end
|
data/lib/jsgf/atom.rb
CHANGED
@@ -4,6 +4,16 @@ module JSGF
|
|
4
4
|
# @return [String] the atom of the {Atom}
|
5
5
|
attr_accessor :atom
|
6
6
|
|
7
|
+
# @!attribute
|
8
|
+
# @return [Bool] Sometimes an {Atom} is optional
|
9
|
+
attr_accessor :optional
|
10
|
+
alias optional? optional
|
11
|
+
|
12
|
+
# @!attribute reference
|
13
|
+
# @return [Bool] The {Atom} is a reference to a {Rule}
|
14
|
+
attr_accessor :reference
|
15
|
+
alias reference? reference
|
16
|
+
|
7
17
|
# @!attribute weight
|
8
18
|
# @return [Number] the {Atom}'s weight, when part of an {Alternation}. Defaults to 1.0.
|
9
19
|
attr_accessor :weight
|
@@ -15,8 +25,10 @@ module JSGF
|
|
15
25
|
# @param atom [String] the atom of the {Atom}
|
16
26
|
# @param weight [Number] the weight to be used when part of an {Alternation}. Valid values are 0..1.0.
|
17
27
|
# @param tags [Array] any tags to be stored with the {Atom}
|
18
|
-
def initialize(atom, *tags, weight:nil)
|
28
|
+
def initialize(atom, *tags, weight:nil, optional:nil, reference:nil)
|
19
29
|
@atom = atom
|
30
|
+
@optional = optional
|
31
|
+
@reference = reference
|
20
32
|
@tags = tags
|
21
33
|
@weight = (weight && (weight != 1.0)) ? weight : nil
|
22
34
|
end
|
@@ -28,7 +40,9 @@ module JSGF
|
|
28
40
|
|
29
41
|
# Stringify in a manner suitable for output to a JSGF file
|
30
42
|
def to_s
|
31
|
-
[(weight && (weight != 1.0)) ? "/#{weight}/" : nil, atom, *tags].compact.join(' ')
|
43
|
+
s = [(weight && (weight != 1.0)) ? "/#{weight}/" : nil, reference? ? '<'+atom+'>' : atom, *tags].compact.join(' ')
|
44
|
+
s = '[' + s + ']' if optional?
|
45
|
+
s
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
data/lib/jsgf/builder.rb
CHANGED
@@ -38,9 +38,33 @@ module JSGF
|
|
38
38
|
options.each do |name, v|
|
39
39
|
@rules[name.to_s] = case v
|
40
40
|
when Array then Rule.new [Alternation.new(*v)]
|
41
|
-
when Symbol then Rule.new [
|
41
|
+
when Symbol then Rule.new [Rule.parse_atom(v.to_s).tap {|a| a.reference=true}]
|
42
42
|
else
|
43
|
-
|
43
|
+
stack = nil
|
44
|
+
v.split(' ').map do |a|
|
45
|
+
if stack
|
46
|
+
if a == ']'
|
47
|
+
next if stack.empty?
|
48
|
+
|
49
|
+
if stack.length == 1
|
50
|
+
stack.first.optional = true
|
51
|
+
stack.first
|
52
|
+
else
|
53
|
+
Optional.new(*stack)
|
54
|
+
end.tap do
|
55
|
+
stack = nil
|
56
|
+
end
|
57
|
+
else
|
58
|
+
stack.push(Rule.parse_atom(a))
|
59
|
+
next
|
60
|
+
end
|
61
|
+
elsif a == '['
|
62
|
+
stack = []
|
63
|
+
next
|
64
|
+
else
|
65
|
+
Rule.parse_atom(a)
|
66
|
+
end
|
67
|
+
end.compact
|
44
68
|
end
|
45
69
|
end
|
46
70
|
end
|
data/lib/jsgf/grammar.rb
CHANGED
@@ -27,11 +27,9 @@ module JSGF
|
|
27
27
|
case rule
|
28
28
|
when Alternation, Array, Optional
|
29
29
|
rule.flat_map {|a| find_rule_names(a) }
|
30
|
-
when Atom then []
|
31
|
-
when Hash
|
32
|
-
rule[:name]
|
30
|
+
when Atom then rule.reference ? rule.atom : []
|
33
31
|
else
|
34
|
-
raise StandardError, "Unkown atom #{rule.class}"
|
32
|
+
raise StandardError, "Unkown atom #{rule.class}: #{rule}"
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
data/lib/jsgf/parser.rb
CHANGED
data/lib/jsgf/rule.rb
CHANGED
@@ -2,11 +2,13 @@ module JSGF
|
|
2
2
|
class Rule < Array
|
3
3
|
# Convert a string containing a single atom into an {Atom} or a rule reference
|
4
4
|
# @param atom [String] the text to parse
|
5
|
-
def self.parse_atom(atom)
|
5
|
+
def self.parse_atom(atom, optional:nil)
|
6
6
|
case atom
|
7
|
-
|
7
|
+
# Parse optionals first to prevent the reference-regex from grabbing it first
|
8
|
+
when /\[(.*)\]/ then parse_atom($1, optional:true)
|
9
|
+
when /\<(.*)\>/, /:(.*)/ then Atom.new($1, optional:optional, reference:true)
|
8
10
|
else
|
9
|
-
Atom.new(atom)
|
11
|
+
Atom.new(atom, optional:optional)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/test/jsgf/builder.rb
CHANGED
@@ -20,13 +20,13 @@ describe JSGF::Builder do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
grammar.rules.size.must_equal 1
|
23
|
-
grammar.rules['rule1'].must_equal [Atom.new('one')]
|
23
|
+
grammar.rules['rule1'].must_equal [JSGF::Atom.new('one')]
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'must build a multi-atom rule' do
|
27
27
|
grammar = JSGF::Builder.build {rule rule1: 'one two' }
|
28
28
|
grammar.rules.size.must_equal 1
|
29
|
-
grammar.rules['rule1'].must_equal [Atom.new('one'), Atom.new('two')]
|
29
|
+
grammar.rules['rule1'].must_equal [JSGF::Atom.new('one'), JSGF::Atom.new('two')]
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'must build a rule with a rule reference as a Symbol' do
|
@@ -36,7 +36,7 @@ describe JSGF::Builder do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
grammar.rules.size.must_equal 2
|
39
|
-
grammar.rules['rule1'].must_equal [
|
39
|
+
grammar.rules['rule1'].must_equal [JSGF::Atom.new('one', reference:true)]
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'must build a rule with a JSGF-style rule reference embedded in a string' do
|
@@ -46,7 +46,7 @@ describe JSGF::Builder do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
grammar.rules.size.must_equal 2
|
49
|
-
grammar.rules['rule1'].must_equal [
|
49
|
+
grammar.rules['rule1'].must_equal [JSGF::Atom.new('one', reference:true)]
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'must build a rule with a rule reference symbol embedded in a string' do
|
@@ -56,7 +56,7 @@ describe JSGF::Builder do
|
|
56
56
|
end
|
57
57
|
|
58
58
|
grammar.rules.size.must_equal 2
|
59
|
-
grammar.rules['rule1'].must_equal [
|
59
|
+
grammar.rules['rule1'].must_equal [JSGF::Atom.new('one', reference:true)]
|
60
60
|
end
|
61
61
|
|
62
62
|
describe 'alternation' do
|
@@ -66,7 +66,7 @@ describe JSGF::Builder do
|
|
66
66
|
end
|
67
67
|
grammar.rules.size.must_equal 1
|
68
68
|
grammar.rules['rule1'].first.must_be_kind_of JSGF::Alternation
|
69
|
-
grammar.rules['rule1'].first.elements.must_equal [Atom.new('one'), Atom.new('two')]
|
69
|
+
grammar.rules['rule1'].first.elements.must_equal [JSGF::Atom.new('one'), JSGF::Atom.new('two')]
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'must build an alternation from an array of rule reference symbols' do
|
@@ -78,7 +78,7 @@ describe JSGF::Builder do
|
|
78
78
|
|
79
79
|
grammar.rules.size.must_equal 3
|
80
80
|
grammar.rules['rule1'].first.must_be_kind_of JSGF::Alternation
|
81
|
-
grammar.rules['rule1'].first.elements.must_equal [
|
81
|
+
grammar.rules['rule1'].first.elements.must_equal [JSGF::Atom.new('one', reference:true), JSGF::Atom.new('two', reference:true)]
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'must build an alternation from an array of strings containing embedded rule reference symbols' do
|
@@ -90,7 +90,7 @@ describe JSGF::Builder do
|
|
90
90
|
|
91
91
|
grammar.rules.size.must_equal 3
|
92
92
|
grammar.rules['rule1'].first.must_be_kind_of JSGF::Alternation
|
93
|
-
grammar.rules['rule1'].first.elements.must_equal [
|
93
|
+
grammar.rules['rule1'].first.elements.must_equal [JSGF::Atom.new('one', reference:true), JSGF::Atom.new('two', reference:true)]
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'must build an alternation from an array of strings containing embedded JSGF-style rule reference names' do
|
@@ -102,7 +102,113 @@ describe JSGF::Builder do
|
|
102
102
|
|
103
103
|
grammar.rules.size.must_equal 3
|
104
104
|
grammar.rules['rule1'].first.must_be_kind_of JSGF::Alternation
|
105
|
-
grammar.rules['rule1'].first.elements.must_equal [
|
105
|
+
grammar.rules['rule1'].first.elements.must_equal [JSGF::Atom.new('one', reference:true), JSGF::Atom.new('two', reference:true)]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'optional' do
|
110
|
+
it 'must parse a rule with an optional word' do
|
111
|
+
grammar = JSGF::Builder.build do
|
112
|
+
rule rule1: "this [is] optional"
|
113
|
+
end
|
114
|
+
|
115
|
+
grammar.rules.size.must_equal 1
|
116
|
+
rule = grammar.rules['rule1']
|
117
|
+
rule.size.must_equal 3
|
118
|
+
|
119
|
+
rule.first.atom.must_equal 'this'
|
120
|
+
rule.first.wont_be :optional?
|
121
|
+
|
122
|
+
rule[1].atom.must_equal 'is'
|
123
|
+
rule[1].must_be :optional?
|
124
|
+
|
125
|
+
rule.last.atom.must_equal 'optional'
|
126
|
+
rule.last.wont_be :optional?
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'must parse a rule with an optional reference' do
|
130
|
+
grammar = JSGF::Builder.build do
|
131
|
+
rule rule1: "this [:is] optional"
|
132
|
+
end
|
133
|
+
|
134
|
+
grammar.rules.size.must_equal 1
|
135
|
+
rule = grammar.rules['rule1']
|
136
|
+
rule.size.must_equal 3
|
137
|
+
|
138
|
+
rule.first.atom.must_equal 'this'
|
139
|
+
rule.first.wont_be :optional?
|
140
|
+
|
141
|
+
rule[1].atom.must_equal 'is'
|
142
|
+
rule[1].must_be :optional?
|
143
|
+
rule[1].must_be :reference?
|
144
|
+
|
145
|
+
rule.last.atom.must_equal 'optional'
|
146
|
+
rule.last.wont_be :optional?
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'must parse a rule with an optional word surrounded by whitespace' do
|
150
|
+
grammar = JSGF::Builder.build do
|
151
|
+
rule rule1: "this [ is ] optional"
|
152
|
+
end
|
153
|
+
|
154
|
+
grammar.rules.size.must_equal 1
|
155
|
+
rule = grammar.rules['rule1']
|
156
|
+
rule.size.must_equal 3
|
157
|
+
rule.map(&:atom).must_equal ['this', 'is', 'optional']
|
158
|
+
|
159
|
+
rule.first.wont_be :optional?
|
160
|
+
rule[1].must_be :optional?
|
161
|
+
rule.last.wont_be :optional?
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'must parse a rule with an optional reference surrounded by whitespace' do
|
165
|
+
grammar = JSGF::Builder.build do
|
166
|
+
rule rule1: "this [ :is ] optional"
|
167
|
+
end
|
168
|
+
|
169
|
+
grammar.rules.size.must_equal 1
|
170
|
+
rule = grammar.rules['rule1']
|
171
|
+
rule.size.must_equal 3
|
172
|
+
rule.map(&:atom).must_equal ['this', 'is', 'optional']
|
173
|
+
|
174
|
+
rule.first.wont_be :optional?
|
175
|
+
|
176
|
+
rule[1].must_be :optional?
|
177
|
+
rule[1].must_be :reference?
|
178
|
+
|
179
|
+
rule.last.wont_be :optional?
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'must parse a rule with an optional words surrounded by whitespace' do
|
183
|
+
grammar = JSGF::Builder.build do
|
184
|
+
rule rule1: "this [ is optional ]"
|
185
|
+
end
|
186
|
+
|
187
|
+
grammar.rules.size.must_equal 1
|
188
|
+
rule = grammar.rules['rule1']
|
189
|
+
rule.size.must_equal 2
|
190
|
+
|
191
|
+
rule.first.atom.must_equal 'this'
|
192
|
+
rule.first.wont_be :optional?
|
193
|
+
|
194
|
+
rule[1].must_be_kind_of JSGF::Optional
|
195
|
+
rule[1].elements.map(&:atom).must_equal ['is', 'optional']
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'must parse a rule with an optional references surrounded by whitespace' do
|
199
|
+
grammar = JSGF::Builder.build do
|
200
|
+
rule rule1: "this [ :is :optional ]"
|
201
|
+
end
|
202
|
+
|
203
|
+
grammar.rules.size.must_equal 1
|
204
|
+
rule = grammar.rules['rule1']
|
205
|
+
rule.size.must_equal 2
|
206
|
+
|
207
|
+
rule.first.atom.must_equal 'this'
|
208
|
+
rule.first.wont_be :optional?
|
209
|
+
|
210
|
+
rule.last.must_be_kind_of JSGF::Optional
|
211
|
+
rule.last.elements.map(&:atom).must_equal ['is', 'optional']
|
106
212
|
end
|
107
213
|
end
|
108
214
|
end
|
data/test/jsgf/parser.rb
CHANGED
@@ -128,7 +128,7 @@ describe JSGF::Parser do
|
|
128
128
|
grammar = JSGF::Parser.new('#JSGF V1.0; grammar header_grammar;<rule>=<rule1>;<rule1>=one;').parse
|
129
129
|
grammar.rules.size.must_equal 2
|
130
130
|
grammar.rules.keys.must_equal ['rule', 'rule1']
|
131
|
-
grammar.rules['rule'].must_equal [
|
131
|
+
grammar.rules['rule'].must_equal [JSGF::Atom.new('rule1', reference:true)]
|
132
132
|
grammar.rules['rule1'].must_equal [Atom.new('one')]
|
133
133
|
end
|
134
134
|
|
@@ -139,7 +139,7 @@ describe JSGF::Parser do
|
|
139
139
|
|
140
140
|
grammar.rules['rule'].size.must_equal 1
|
141
141
|
grammar.rules['rule'].first.must_be_kind_of JSGF::Alternation
|
142
|
-
grammar.rules['rule'].first.elements.must_equal [
|
142
|
+
grammar.rules['rule'].first.elements.must_equal [JSGF::Atom.new('rule1', weight:0.5, reference:true), Atom.new('two', weight:0.5)]
|
143
143
|
|
144
144
|
grammar.rules['rule1'].must_equal [Atom.new('one')]
|
145
145
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsgf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Fosdick
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.7'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
description: A parser and DSL for JSGF files
|
@@ -45,8 +45,8 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .travis.yml
|
48
|
+
- ".gitignore"
|
49
|
+
- ".travis.yml"
|
50
50
|
- Gemfile
|
51
51
|
- README.md
|
52
52
|
- Rakefile
|
@@ -78,17 +78,17 @@ require_paths:
|
|
78
78
|
- lib
|
79
79
|
required_ruby_version: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
|
-
- -
|
86
|
+
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
89
|
requirements: []
|
90
90
|
rubyforge_project:
|
91
|
-
rubygems_version: 2.4.
|
91
|
+
rubygems_version: 2.4.3
|
92
92
|
signing_key:
|
93
93
|
specification_version: 4
|
94
94
|
summary: Java Speech Grammar Format
|