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