jsgf 0.4.1 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/bfoz/jsgf-ruby.png)](https://travis-ci.org/bfoz/jsgf-ruby)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/jsgf.svg)](http://badge.fury.io/rb/jsgf)
|
6
|
+
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg?style=flat)](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
|