taipo 1.3.0 → 1.4.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 +1 -1
- data/lib/taipo.rb +0 -86
- data/lib/taipo/cache.rb +2 -1
- data/lib/taipo/check.rb +9 -7
- data/lib/taipo/parser.rb +292 -153
- data/lib/taipo/parser/stack.rb +143 -0
- data/lib/taipo/parser/syntax_state.rb +12 -11
- data/lib/taipo/parser/validater.rb +126 -58
- data/lib/taipo/refinements.rb +30 -0
- data/lib/taipo/type_element.rb +50 -68
- data/lib/taipo/type_element/children.rb +47 -0
- data/lib/taipo/type_element/constraint.rb +11 -15
- data/lib/taipo/type_element/constraints.rb +36 -0
- data/lib/taipo/type_elements.rb +33 -0
- data/lib/taipo/utilities.rb +81 -0
- data/lib/taipo/version.rb +1 -1
- metadata +8 -3
- data/lib/taipo/type_element/child_type.rb +0 -40
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'taipo/type_elements'
|
2
|
+
require 'taipo/type_element'
|
3
|
+
require 'taipo/type_element/children'
|
4
|
+
require 'taipo/type_element/constraints'
|
5
|
+
require 'taipo/type_element/constraint'
|
6
|
+
|
7
|
+
module Taipo
|
8
|
+
module Parser
|
9
|
+
|
10
|
+
# A stack of parsed or partially parsed elements
|
11
|
+
#
|
12
|
+
# @since 1.4.0
|
13
|
+
# @api private
|
14
|
+
class Stack < Array
|
15
|
+
|
16
|
+
# Initialize the stack
|
17
|
+
#
|
18
|
+
# @since 1.4.0
|
19
|
+
# @api private
|
20
|
+
def initialize
|
21
|
+
self.push Taipo::TypeElements.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return the resulting {Taipo::TypeElements} object
|
25
|
+
#
|
26
|
+
# @note This should not be called until parsing is complete.
|
27
|
+
#
|
28
|
+
# @return [Taipo::TypeElements] the parsed object representing the
|
29
|
+
# relevant type definition
|
30
|
+
#
|
31
|
+
# @raise [RuntimeError] if there is more than one element in the stack
|
32
|
+
#
|
33
|
+
# @since 1.4.0
|
34
|
+
# @api private
|
35
|
+
def result
|
36
|
+
msg = "Something went wrong. There should only be one element left."
|
37
|
+
raise RuntimeError, msg if self.size != 1
|
38
|
+
self.first
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add a {Taipo::TypeElement::Children} object to the top of the stack
|
42
|
+
#
|
43
|
+
# @note Due to the way {Taipo::Parser} is implemented, this method will
|
44
|
+
# also add an empty {Taipo::TypeElements} object to the stack. This
|
45
|
+
# represents the first (and possibly only) component of the collection.
|
46
|
+
#
|
47
|
+
# @return [Taipo::Parser::Stack] the updated stack
|
48
|
+
#
|
49
|
+
# @since 1.4.0
|
50
|
+
# @api private
|
51
|
+
def add_children
|
52
|
+
self.push Taipo::TypeElement::Children.new
|
53
|
+
self.push Taipo::TypeElements.new
|
54
|
+
end
|
55
|
+
|
56
|
+
# Remove a {Taipo::TypeElement::Children} object from the top of the stack
|
57
|
+
#
|
58
|
+
# @note Due to the way {Taipo::Parser} is implemented, this method first
|
59
|
+
# removes the child that is at the top of the stack, adds that to the
|
60
|
+
# set of children and then returns the children.
|
61
|
+
#
|
62
|
+
# @return [Taipo::TypeElement::Children] the children
|
63
|
+
#
|
64
|
+
# @since 1.4.0
|
65
|
+
# @api private
|
66
|
+
def remove_children
|
67
|
+
child = self.pop
|
68
|
+
self.last.push child
|
69
|
+
self.pop
|
70
|
+
end
|
71
|
+
|
72
|
+
# Add a {Taipo::TypeElements} object to the top of the stack
|
73
|
+
#
|
74
|
+
# @note Due to the way {Taipo::Parser} is implemented, this method first
|
75
|
+
# removes the child that is at the top of the stack, adds that to the
|
76
|
+
# set of children and then add a new child.
|
77
|
+
#
|
78
|
+
# @return [Taipo::Parser::Stack] the updated stack
|
79
|
+
#
|
80
|
+
# @since 1.4.0
|
81
|
+
# @api private
|
82
|
+
def add_child
|
83
|
+
child = self.pop
|
84
|
+
self.last.push child
|
85
|
+
self.push Taipo::TypeElements.new
|
86
|
+
end
|
87
|
+
|
88
|
+
# Add a {Taipo::TypeElement::Constraints} object to the top of the stack
|
89
|
+
#
|
90
|
+
# @return [Taipo::Parser::Stack] the updated stack
|
91
|
+
#
|
92
|
+
# @since 1.4.0
|
93
|
+
# @api private
|
94
|
+
def add_constraints
|
95
|
+
self.push Taipo::TypeElement::Constraints.new
|
96
|
+
end
|
97
|
+
|
98
|
+
# Remove a {Taipo::TypeElement::Constraints} object from the top of the
|
99
|
+
# stack
|
100
|
+
#
|
101
|
+
# @return [Taipo::TypeElement::Constraints] the constraints
|
102
|
+
#
|
103
|
+
# @since 1.4.0
|
104
|
+
# @api private
|
105
|
+
def remove_constraints
|
106
|
+
self.pop
|
107
|
+
end
|
108
|
+
|
109
|
+
# Add a {Taipo::TypeElement::Constraint} object to the top of the stack
|
110
|
+
#
|
111
|
+
# @return [Taipo::Parser::Stack] the updated stack
|
112
|
+
#
|
113
|
+
# @since 1.4.0
|
114
|
+
# @api private
|
115
|
+
def add_constraint(constraint)
|
116
|
+
self.last.push constraint
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
# Add a {Taipo::TypeElement} object to the top of the stack
|
121
|
+
#
|
122
|
+
# @return [Taipo::Parser::Stack] the updated stack
|
123
|
+
#
|
124
|
+
# @since 1.4.0
|
125
|
+
# @api private
|
126
|
+
def add_element(name:)
|
127
|
+
self.last.push Taipo::TypeElement.new(name: name)
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
# Update the {Taipo::TypeElement} object at the top of the stack
|
132
|
+
#
|
133
|
+
# @return [Taipo::Parser::Stack] the updated stack
|
134
|
+
#
|
135
|
+
# @since 1.4.0
|
136
|
+
# @api private
|
137
|
+
def update_element(method, arg)
|
138
|
+
self.last.last.send method, arg
|
139
|
+
self
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -6,14 +6,14 @@ module Taipo
|
|
6
6
|
# @since 1.0.0
|
7
7
|
# @api private
|
8
8
|
class SyntaxState
|
9
|
-
|
9
|
+
|
10
10
|
# Initialize a new state machine
|
11
11
|
#
|
12
12
|
# @param state_names [Array<Symbol>] an array of symbols designating the
|
13
13
|
# particular states to be used
|
14
14
|
# @param counter_names_and_closers [Array<Array<Symbol>,Hash<Symbol,
|
15
15
|
# String>>] an array of two collections: an array of symbols
|
16
|
-
# designating the names the state machine will use for counting
|
16
|
+
# designating the names the state machine will use for counting
|
17
17
|
# brackets and a hash of closing characters used for each bracket (the
|
18
18
|
# key for each closing character should have the same name as the name
|
19
19
|
# used for the counter)
|
@@ -58,10 +58,10 @@ module Taipo
|
|
58
58
|
@status[key] = :allowed
|
59
59
|
end
|
60
60
|
|
61
|
-
# Set all statuses to be +:allowed+ except those specified in the
|
61
|
+
# Set all statuses to be +:allowed+ except those specified in the
|
62
62
|
# +except+ array
|
63
63
|
#
|
64
|
-
# @note Statuses which have been set to +:disabled+ will not be updated
|
64
|
+
# @note Statuses which have been set to +:disabled+ will not be updated.
|
65
65
|
#
|
66
66
|
# @param except [Array<Symbol>] keys not to update to +:allowed+ (will
|
67
67
|
# instead be set to +:prohibited+)
|
@@ -79,7 +79,7 @@ module Taipo
|
|
79
79
|
# @return [Boolean] the result
|
80
80
|
#
|
81
81
|
# @since 1.0.0
|
82
|
-
# @api private
|
82
|
+
# @api private
|
83
83
|
def allowed?(key)
|
84
84
|
@status[key] == :allowed
|
85
85
|
end
|
@@ -99,7 +99,7 @@ module Taipo
|
|
99
99
|
# Decrement the count for the given +key+ by 1
|
100
100
|
#
|
101
101
|
# @param key [Symbol] the key for the counter
|
102
|
-
#
|
102
|
+
#
|
103
103
|
# @since 1.0.0
|
104
104
|
# @api private
|
105
105
|
def decrement(key)
|
@@ -146,7 +146,7 @@ module Taipo
|
|
146
146
|
# @return [Boolean] the result
|
147
147
|
#
|
148
148
|
# @since 1.0.0
|
149
|
-
# @api private
|
149
|
+
# @api private
|
150
150
|
def inside?(key)
|
151
151
|
@counter[key] > 0
|
152
152
|
end
|
@@ -177,7 +177,7 @@ module Taipo
|
|
177
177
|
# Set all statuses to be +:prohibited+ except those specified in the
|
178
178
|
# +except+ array
|
179
179
|
#
|
180
|
-
# @note Statuses which have been set to +:disabled+ will not be updated
|
180
|
+
# @note Statuses which have been set to +:disabled+ will not be updated.
|
181
181
|
#
|
182
182
|
# @param except [Array<Symbol>] keys not to update to +:prohibited+ (will
|
183
183
|
# instead be set to +:allowed+)
|
@@ -201,11 +201,12 @@ module Taipo
|
|
201
201
|
# Set all statuses to be +status+ except those specified in the +except+
|
202
202
|
# array
|
203
203
|
#
|
204
|
-
# @note Statuses which have been set to +:disabled+ will not be updated
|
204
|
+
# @note Statuses which have been set to +:disabled+ will not be updated.
|
205
205
|
#
|
206
206
|
# @param status [Symbol] the value for all statuses
|
207
207
|
# @param except [Hash<Array<Symbol>, Symbol>] the exceptions
|
208
|
-
# @option except [Array<Symbol>] :exceptions keys not to update to
|
208
|
+
# @option except [Array<Symbol>] :exceptions keys not to update to
|
209
|
+
# +status+
|
209
210
|
# @option except [Symbol] :status the value for exceptions
|
210
211
|
#
|
211
212
|
# @since 1.0.0
|
@@ -223,7 +224,7 @@ module Taipo
|
|
223
224
|
# brackets
|
224
225
|
#
|
225
226
|
# @since 1.0.0
|
226
|
-
# @api
|
227
|
+
# @api
|
227
228
|
def unbalanced()
|
228
229
|
@counter.reduce(Array.new) do |memo, c|
|
229
230
|
(c[1] == 0) ? memo : memo.push(@closers[c[0]])
|
@@ -11,9 +11,10 @@ module Taipo
|
|
11
11
|
#
|
12
12
|
# === Names
|
13
13
|
#
|
14
|
-
# 'String', 'Numeric'
|
14
|
+
# 'String', 'Numeric', 'Foo::Bar'
|
15
15
|
#
|
16
|
-
# A name should be the name of a class or a module.
|
16
|
+
# A name should be the name of a class or a module. A name can include a
|
17
|
+
# namespace.
|
17
18
|
#
|
18
19
|
# The validater does not check whether the name represents a valid name in
|
19
20
|
# the current context nor does it check whether the name complies with
|
@@ -120,8 +121,8 @@ module Taipo
|
|
120
121
|
# ':foo|:bar', ':one|:two|:three'
|
121
122
|
#
|
122
123
|
# It's possible to approximate the enum idiom available in many languages
|
123
|
-
# by creating a sum type consisting of Symbols. As a convenience, Taipo
|
124
|
-
# parses these values as constraints on the Object class. In other words,
|
124
|
+
# by creating a sum type consisting of Symbols. As a convenience, Taipo
|
125
|
+
# parses these values as constraints on the Object class. In other words,
|
125
126
|
# +':foo|:bar'+ is really +'Object(val: :foo)|Object(val: :bar)'+.
|
126
127
|
#
|
127
128
|
# @since 1.0.0
|
@@ -143,92 +144,159 @@ module Taipo
|
|
143
144
|
msg = "The string to be checked was empty."
|
144
145
|
raise Taipo::SyntaxError, msg if str.empty?
|
145
146
|
|
146
|
-
status_array = [ :bar, :lab, :rab, :lpr, :
|
147
|
-
:
|
148
|
-
|
149
|
-
|
147
|
+
status_array = [ :bar, :lab, :rab, :lpr, :hsh, :cln, :cma, :spc_bar,
|
148
|
+
:spc_rab, :spc_rpr, :spc_cma, :spc_oth, :mth, :sym,
|
149
|
+
:nme, :end ]
|
150
|
+
counter_array = [ [ :angle ], { angle: '>' } ]
|
151
|
+
|
150
152
|
state = Taipo::Parser::SyntaxState.new(status_array, counter_array)
|
153
|
+
state.prohibit_all except: [ :lpr, :hsh, :cln, :nme ]
|
151
154
|
|
152
155
|
i = 0
|
153
156
|
chars = str.chars
|
154
|
-
str_length = chars.size
|
155
|
-
|
156
|
-
state.prohibit_all except: [ :lpr, :hsh, :cln, :oth ]
|
157
157
|
|
158
|
-
while (i <
|
158
|
+
while (i < chars.size)
|
159
159
|
msg = "The string '#{str}' has an error here: #{str[0, i+1]}"
|
160
160
|
case chars[i]
|
161
|
+
when ')', '/', '"'
|
162
|
+
raise Taipo::SyntaxError, msg
|
161
163
|
when '|' # bar
|
162
164
|
conditions = [ state.allowed?(:bar) ]
|
163
165
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
164
|
-
state.
|
165
|
-
state.enable :lpr
|
166
|
-
state.prohibit_all except: [ :lpr, :hsh, :cln, :oth ]
|
166
|
+
state.prohibit_all except: [ :lpr, :hsh, :cln, :spc_bar, :nme ]
|
167
167
|
when '<' # lab
|
168
168
|
conditions = [ state.allowed?(:lab) ]
|
169
169
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
170
|
-
state.prohibit_all except: [ :lpr, :hsh, :cln, :
|
170
|
+
state.prohibit_all except: [ :lpr, :hsh, :cln, :nme ]
|
171
171
|
state.increment :angle
|
172
172
|
when '>' # rab
|
173
173
|
conditions = [ state.allowed?(:rab), state.inside?(:angle) ]
|
174
174
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
175
|
-
state.prohibit_all except: [ :bar, :rab, :lpr, :end ]
|
175
|
+
state.prohibit_all except: [ :bar, :rab, :lpr, :spc_rab, :end ]
|
176
176
|
state.decrement :angle
|
177
177
|
when '(' # lpr
|
178
|
-
conditions = [ state.allowed?(:lpr)
|
178
|
+
conditions = [ state.allowed?(:lpr) ]
|
179
179
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
180
|
-
|
181
|
-
state.
|
182
|
-
state.increment :const
|
183
|
-
when ')' # rpr
|
184
|
-
conditions = [ state.allowed?(:rpr), state.inside?(:paren) ]
|
185
|
-
raise Taipo::SyntaxError, msg unless conditions.all?
|
186
|
-
state.prohibit_all except: [ :bar, :rab, :end ]
|
187
|
-
state.decrement :paren
|
180
|
+
i = Taipo::Parser::Validater.validate_constraints(str, start: i+1)
|
181
|
+
state.prohibit_all except: [ :bar, :rab, :spc_rpr, :end ]
|
188
182
|
when '#' # hsh
|
189
183
|
conditions = [ state.allowed?(:hsh) ]
|
190
184
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
185
|
+
state.prohibit_all except: [ :mth ]
|
186
|
+
when ':' # cln
|
187
|
+
if chars[i+1] == ':' && chars[i+2] != ':'
|
188
|
+
conditions = [ state.allowed?(:nme) ]
|
189
|
+
raise Taipo::SyntaxError, msg unless conditions.all?
|
190
|
+
state.prohibit_all except: [ :nme ]
|
191
|
+
i = i + 1
|
195
192
|
else
|
196
|
-
|
197
|
-
|
193
|
+
conditions = [ state.allowed?(:cln) ]
|
194
|
+
raise Taipo::SyntaxError, msg unless conditions.all?
|
195
|
+
state.prohibit_all except: [ :sym ]
|
196
|
+
end
|
197
|
+
when ',' # cma
|
198
|
+
conditions = [ state.allowed?(:cma), state.inside?(:angle)]
|
199
|
+
raise Taipo::SyntaxError, msg unless conditions.all?
|
200
|
+
state.prohibit_all except: [ :hsh, :cln, :spc_cma, :nme ]
|
201
|
+
when ' ' # spc
|
202
|
+
conditions = [ state.allowed?(:spc_bar), state.allowed?(:spc_cma),
|
203
|
+
state.allowed?(:spc_oth) ]
|
204
|
+
raise Taipo::SyntaxError, msg unless conditions.any?
|
205
|
+
if state.allowed?(:spc_bar) || state.allowed?(:spc_cma)
|
206
|
+
state.prohibit_all except: [ :hsh, :cln, :nme ]
|
207
|
+
elsif state.allowed?(:spc_rab) || state.allowed?(:spc_rpr)
|
208
|
+
state.prohibit_all except: [ :bar, :hsh, :cln, :nme ]
|
209
|
+
elsif state.allowed?(:spc_oth)
|
210
|
+
state.prohibit_all except: [ :bar ]
|
211
|
+
end
|
212
|
+
else # oth
|
213
|
+
conditions = [ state.allowed?(:mth), state.allowed?(:sym),
|
214
|
+
state.allowed?(:nme) ]
|
215
|
+
raise Taipo::SyntaxError, msg unless conditions.any?
|
216
|
+
if state.allowed?(:mth)
|
217
|
+
state.prohibit_all except: [ :bar, :rab, :cma, :spc_oth, :mth,
|
218
|
+
:end ]
|
219
|
+
elsif state.allowed?(:sym)
|
220
|
+
state.prohibit_all except: [ :bar, :rab, :cma, :spc_oth, :sym,
|
221
|
+
:end ]
|
222
|
+
elsif state.allowed?(:nme)
|
223
|
+
state.prohibit_all except: [ :bar, :lab, :rab, :lpr, :cma,
|
224
|
+
:spc_oth, :nme, :end ]
|
198
225
|
end
|
226
|
+
end
|
227
|
+
i += 1
|
228
|
+
end
|
229
|
+
|
230
|
+
msg_end = "The string '#{str}' ends with an illegal character."
|
231
|
+
raise Taipo::SyntaxError, msg_end unless state.allowed?(:end)
|
232
|
+
|
233
|
+
missing = state.unbalanced
|
234
|
+
msg_bal = "The string '#{str}' is missing a '#{missing.first}'."
|
235
|
+
raise Taipo::SyntaxError, msg_bal unless missing.size == 0
|
236
|
+
end
|
237
|
+
|
238
|
+
# Check +str+ is a valid set of constraints
|
239
|
+
#
|
240
|
+
# @param str [String] the type definition
|
241
|
+
# @param start [Integer] the index within the type definition where this
|
242
|
+
# set of constraints begins
|
243
|
+
#
|
244
|
+
# @return [Integer] the index within the type definition where this set of
|
245
|
+
# set of constraints end
|
246
|
+
#
|
247
|
+
# @raise [Taipo::SyntaxError] if +str+ is not a valid set of constraints
|
248
|
+
#
|
249
|
+
# @since 1.4.0
|
250
|
+
# @api private
|
251
|
+
def self.validate_constraints(str, start: 0)
|
252
|
+
status_array = [ :rpr, :hsh, :cln, :sls, :qut, :cma, :spc, :oth ]
|
253
|
+
counter_array = [ [ :const ], { const: ":' or '#" } ]
|
254
|
+
|
255
|
+
state = SyntaxState.new(status_array, counter_array)
|
256
|
+
state.prohibit_all except: [ :hsh, :oth ]
|
257
|
+
state.increment(:const)
|
258
|
+
|
259
|
+
i = start
|
260
|
+
chars = str.chars
|
261
|
+
|
262
|
+
while (i < chars.size)
|
263
|
+
msg = "The string '#{str}' has an error here: #{str[0, i+1]}"
|
264
|
+
case chars[i]
|
265
|
+
when '|', '<', '>', '('
|
266
|
+
raise Taipo::SyntaxError, msg
|
267
|
+
when ')' # rpr
|
268
|
+
conditions = [ state.allowed?(:rpr) ]
|
269
|
+
raise Taipo::SyntaxError, msg unless conditions.all?
|
270
|
+
break # The constraints have ended.
|
271
|
+
when '#' # hsh
|
272
|
+
conditions = [ state.allowed?(:hsh) ]
|
273
|
+
raise Taipo::SyntaxError, msg unless conditions.all?
|
274
|
+
state.prohibit_all except: [ :oth ]
|
275
|
+
state.decrement :const
|
199
276
|
when ':' # cln
|
200
277
|
conditions = [ state.allowed?(:cln) ]
|
201
278
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
202
|
-
if state.
|
203
|
-
state.
|
204
|
-
state.disable :lpr
|
205
|
-
state.prohibit_all except: [ :oth ]
|
279
|
+
if state.count(:const) == 0 # This is a symbol.
|
280
|
+
state.prohibit_all except: [ :qut, :oth ]
|
206
281
|
else
|
207
|
-
|
208
|
-
|
209
|
-
else
|
210
|
-
state.prohibit_all except: [ :cln, :sls, :qut, :spc, :oth ]
|
211
|
-
state.decrement :const
|
212
|
-
end
|
282
|
+
state.prohibit_all except: [ :cln, :sls, :qut, :spc, :oth ]
|
283
|
+
state.decrement :const
|
213
284
|
end
|
214
285
|
when '/' #sls
|
215
|
-
conditions = [ state.allowed?(:sls), state.
|
216
|
-
state.outside?(:const) ]
|
286
|
+
conditions = [ state.allowed?(:sls), state.outside?(:const) ]
|
217
287
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
218
288
|
i = Taipo::Parser::Validater.validate_regex(str, start: i+1)
|
219
289
|
state.prohibit_all except: [ :rpr, :cma ]
|
220
290
|
when '"' #qut
|
221
|
-
conditions = [ state.allowed?(:qut), state.
|
222
|
-
state.outside?(:const) ]
|
291
|
+
conditions = [ state.allowed?(:qut), state.outside?(:const) ]
|
223
292
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
224
293
|
i = Taipo::Parser::Validater.validate_string(str, start: i+1)
|
225
294
|
state.prohibit_all except: [ :rpr, :cma ]
|
226
295
|
when ',' # cma
|
227
|
-
conditions = [ state.allowed?(:cma)
|
228
|
-
state.inside?(:angle) || state.inside?(:paren) ]
|
296
|
+
conditions = [ state.allowed?(:cma) ]
|
229
297
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
230
298
|
state.prohibit_all except: [ :spc, :oth ]
|
231
|
-
state.increment :const
|
299
|
+
state.increment :const
|
232
300
|
when ' ' # spc
|
233
301
|
conditions = [ state.allowed?(:spc) ]
|
234
302
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
@@ -236,25 +304,24 @@ module Taipo
|
|
236
304
|
else # oth
|
237
305
|
conditions = [ state.allowed?(:oth) ]
|
238
306
|
raise Taipo::SyntaxError, msg unless conditions.all?
|
239
|
-
|
240
|
-
state.allow_all except: [ :hsh, :spc ]
|
241
|
-
else
|
242
|
-
state.allow_all except: [ :hsh, :cln, :spc ]
|
243
|
-
end
|
307
|
+
state.allow_all except: [ :hsh, :spc ]
|
244
308
|
end
|
245
309
|
i += 1
|
246
310
|
end
|
247
|
-
|
248
|
-
|
311
|
+
|
312
|
+
msg = "The string '#{str}' is missing a ')'."
|
313
|
+
raise Taipo::SyntaxError, msg if i == chars.size
|
249
314
|
|
250
315
|
missing = state.unbalanced
|
251
316
|
msg_bal = "The string '#{str}' is missing a '#{missing.first}'."
|
252
317
|
raise Taipo::SyntaxError, msg_bal unless missing.size == 0
|
318
|
+
|
319
|
+
i
|
253
320
|
end
|
254
321
|
|
255
322
|
# Check +str+ is a valid regular expression
|
256
323
|
#
|
257
|
-
# @param str [String]
|
324
|
+
# @param str [String] the type definition
|
258
325
|
# @param start [Integer] the index within the type definition where this
|
259
326
|
# regex begins
|
260
327
|
#
|
@@ -308,12 +375,13 @@ module Taipo
|
|
308
375
|
|
309
376
|
# Check +str+ is a valid string
|
310
377
|
#
|
311
|
-
# @param str [String]
|
378
|
+
# @param str [String] the type definition
|
312
379
|
# @param start [Integer] the index within the type definition where this
|
313
380
|
# string begins
|
314
381
|
#
|
315
382
|
# @return [Integer] the index within the type definition where this
|
316
383
|
# string ends
|
384
|
+
#
|
317
385
|
# @raise [Taipo::SyntaxError] if +str+ is not a valid string
|
318
386
|
#
|
319
387
|
# @since 1.0.0
|