markov_chain_chat_bot 0.1.3 → 0.1.4
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.
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'markov_chain'
|
3
|
+
require 'strscan'
|
4
|
+
|
5
|
+
#
|
6
|
+
# A chat bot utilizing MarkovChain.
|
7
|
+
#
|
8
|
+
class MarkovChainChatBot
|
9
|
+
|
10
|
+
private_class_method :new
|
11
|
+
|
12
|
+
#
|
13
|
+
# +data+ is a map. It may be empty, in this case a brand new
|
14
|
+
# MarkovChainChatBot is created. +data+ becomes owned by the returned
|
15
|
+
# MarkovChainChatBot.
|
16
|
+
#
|
17
|
+
# +answer_limit+ is maximum size of the result of #answer().
|
18
|
+
#
|
19
|
+
def self.from(data, answer_limit = 1000)
|
20
|
+
new(data, answer_limit)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(data, answer_limit) # :nodoc:
|
24
|
+
@markov_chain =
|
25
|
+
if data.empty? then MarkovChain.new(data)
|
26
|
+
else MarkovChain.from(data)
|
27
|
+
end
|
28
|
+
@answer_limit = answer_limit
|
29
|
+
end
|
30
|
+
|
31
|
+
# +data+ passed to MarkovChainChatBot.from().
|
32
|
+
def data
|
33
|
+
@markov_chain.data
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# +message+ is String.
|
38
|
+
#
|
39
|
+
# It returns this (modified) MarkovChainChatBot.
|
40
|
+
#
|
41
|
+
def learn(message)
|
42
|
+
@markov_chain.append!(tokenize(message)).append!([EndOfMessage.new])
|
43
|
+
return self
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# +question+ is String.
|
48
|
+
#
|
49
|
+
# It returns String.
|
50
|
+
#
|
51
|
+
def answer(question)
|
52
|
+
answer = ""
|
53
|
+
previous_token = nil
|
54
|
+
catch :out_of_limit do
|
55
|
+
for token in @markov_chain.predict()
|
56
|
+
break if token.tkn_is_a? EndOfMessage or token.nil?
|
57
|
+
delimiter =
|
58
|
+
if (previous_token.tkn_is_a? Word and token.tkn_is_a? Word) then " "
|
59
|
+
else ""
|
60
|
+
end
|
61
|
+
answer.append_limited(delimiter + token.tkn_value, @answer_limit)
|
62
|
+
previous_token = token
|
63
|
+
end
|
64
|
+
end
|
65
|
+
return answer
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# :enddoc:
|
71
|
+
|
72
|
+
class ::String
|
73
|
+
|
74
|
+
# appends +appendment+ to this String or throws +:out_of_limit+ if
|
75
|
+
# this String will exceed +limit+ after the appending.
|
76
|
+
#
|
77
|
+
# It returns this (modified) String.
|
78
|
+
#
|
79
|
+
def append_limited(appendment, limit)
|
80
|
+
throw :out_of_limit if self.length + appendment.length > limit
|
81
|
+
self << appendment
|
82
|
+
return self
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# returns Array of Token-s.
|
89
|
+
#
|
90
|
+
def tokenize(text)
|
91
|
+
tokens = []
|
92
|
+
s = StringScanner.new(text)
|
93
|
+
until s.eos?
|
94
|
+
# Word.
|
95
|
+
(
|
96
|
+
w = s.scan(/([-–]?[a-zA-Zа-яёА-ЯЁ0-9]+)+/) and
|
97
|
+
tokens << Word.new(w)
|
98
|
+
) or
|
99
|
+
# Punctuation.
|
100
|
+
(
|
101
|
+
p = s.scan(/([#{WHITESPACE_CHARSET}]|[^\-–a-zA-Zа-яёА-ЯЁ0-9]|[-–](?![a-zA-Zа-яёА-ЯЁ0-9)]))+/o) and begin
|
102
|
+
p.gsub(/[#{WHITESPACE_CHARSET}]+/, " ")
|
103
|
+
if p != " " then
|
104
|
+
tokens << PunctuationMark.new(p)
|
105
|
+
end
|
106
|
+
true
|
107
|
+
end
|
108
|
+
) or
|
109
|
+
break
|
110
|
+
end
|
111
|
+
return tokens
|
112
|
+
end
|
113
|
+
|
114
|
+
# Accessible to #tokenize() only.
|
115
|
+
#
|
116
|
+
# White space characters as specified in "Unicode Standard Annex #44: Unicode
|
117
|
+
# Character Database" (http://www.unicode.org/reports/tr44, specifically
|
118
|
+
# http://www.unicode.org/Public/UNIDATA/PropList.txt).
|
119
|
+
#
|
120
|
+
WHITESPACE_CHARSET = "[\u0009-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]"
|
121
|
+
|
122
|
+
Token = Object
|
123
|
+
|
124
|
+
class Token
|
125
|
+
|
126
|
+
def tkn_value
|
127
|
+
self[1..-1]
|
128
|
+
end
|
129
|
+
|
130
|
+
def tkn_is_a?(clazz)
|
131
|
+
clazz === self
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
class Word < Token
|
137
|
+
|
138
|
+
def self.new(value)
|
139
|
+
"w" + value
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.===(x)
|
143
|
+
x.is_a? String and x[0] == "w"
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
class PunctuationMark < Token
|
149
|
+
|
150
|
+
def self.new(value)
|
151
|
+
"p" + value
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.===(x)
|
155
|
+
x.is_a? String and x[0] == "p"
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
class EndOfMessage < Token
|
161
|
+
|
162
|
+
def self.new()
|
163
|
+
nil
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.===(x)
|
167
|
+
x.nil?
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markov_chain_chat_bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-14 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A chat bot utilizing Markov chains. It speaks Russian and English.
|
15
15
|
email: Lavir.th.Whiolet@gmail.com
|
@@ -18,10 +18,10 @@ extensions: []
|
|
18
18
|
extra_rdoc_files:
|
19
19
|
- README
|
20
20
|
files:
|
21
|
-
- lib/auto_marshalling_map.rb
|
22
|
-
- lib/chat_bot.rb
|
23
|
-
- lib/markov_chain.rb
|
24
|
-
- lib/markov_chain_chat_bot.rb
|
21
|
+
- lib/lib/auto_marshalling_map.rb
|
22
|
+
- lib/lib/chat_bot.rb
|
23
|
+
- lib/lib/markov_chain.rb
|
24
|
+
- lib/lib/markov_chain_chat_bot.rb
|
25
25
|
- README
|
26
26
|
homepage: https://github.com/LavirtheWhiolet/markov-chain-bot-module
|
27
27
|
licenses:
|
@@ -49,3 +49,4 @@ signing_key:
|
|
49
49
|
specification_version: 3
|
50
50
|
summary: Markov chain chat bot
|
51
51
|
test_files: []
|
52
|
+
has_rdoc:
|
@@ -1,582 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'markov_chain'
|
3
|
-
require 'stringio'
|
4
|
-
|
5
|
-
#
|
6
|
-
# A chat bot utilizing MarkovChain.
|
7
|
-
#
|
8
|
-
class MarkovChainChatBot
|
9
|
-
|
10
|
-
private_class_method :new
|
11
|
-
|
12
|
-
#
|
13
|
-
# +data+ is a map. It may be empty, in this case a brand new
|
14
|
-
# MarkovChainChatBot is created. +data+ becomes owned by the returned
|
15
|
-
# MarkovChainChatBot.
|
16
|
-
#
|
17
|
-
# +answer_limit+ is maximum size of the result of #answer().
|
18
|
-
#
|
19
|
-
def self.from(data, answer_limit = 1000)
|
20
|
-
new(data, answer_limit)
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(data, answer_limit) # :nodoc:
|
24
|
-
@markov_chain =
|
25
|
-
if data.empty? then MarkovChain.new(data)
|
26
|
-
else MarkovChain.from(data)
|
27
|
-
end
|
28
|
-
@answer_limit = answer_limit
|
29
|
-
end
|
30
|
-
|
31
|
-
# +data+ passed to MarkovChainChatBot.from().
|
32
|
-
def data
|
33
|
-
@markov_chain.data
|
34
|
-
end
|
35
|
-
|
36
|
-
#
|
37
|
-
# +message+ is String.
|
38
|
-
#
|
39
|
-
# It returns this (modified) MarkovChainChatBot.
|
40
|
-
#
|
41
|
-
def learn(message)
|
42
|
-
@markov_chain.append!(tokenize(message)).append!([EndOfMessage.new])
|
43
|
-
return self
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# +question+ is String.
|
48
|
-
#
|
49
|
-
# It returns String.
|
50
|
-
#
|
51
|
-
def answer(question)
|
52
|
-
answer = ""
|
53
|
-
previous_token = nil
|
54
|
-
catch :out_of_limit do
|
55
|
-
for token in @markov_chain.predict()
|
56
|
-
break if token.tkn_is_a? EndOfMessage or token.nil?
|
57
|
-
delimiter =
|
58
|
-
if (previous_token.tkn_is_a? Word and token.tkn_is_a? Word) then " "
|
59
|
-
else ""
|
60
|
-
end
|
61
|
-
answer.append_limited(delimiter + token.tkn_value, @answer_limit)
|
62
|
-
previous_token = token
|
63
|
-
end
|
64
|
-
end
|
65
|
-
return answer
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
# :enddoc:
|
71
|
-
|
72
|
-
class ::String
|
73
|
-
|
74
|
-
# appends +appendment+ to this String or throws +:out_of_limit+ if
|
75
|
-
# this String will exceed +limit+ after the appending.
|
76
|
-
#
|
77
|
-
# It returns this (modified) String.
|
78
|
-
#
|
79
|
-
def append_limited(appendment, limit)
|
80
|
-
throw :out_of_limit if self.length + appendment.length > limit
|
81
|
-
self << appendment
|
82
|
-
return self
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
Token = Object
|
88
|
-
|
89
|
-
class Token
|
90
|
-
|
91
|
-
def tkn_value
|
92
|
-
self[1..-1]
|
93
|
-
end
|
94
|
-
|
95
|
-
def tkn_is_a?(clazz)
|
96
|
-
clazz === self
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
class Word < Token
|
102
|
-
|
103
|
-
def self.new(value)
|
104
|
-
"w" + value
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.===(x)
|
108
|
-
x.is_a? String and x[0] == "w"
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
class PunctuationMark < Token
|
114
|
-
|
115
|
-
def self.new(value)
|
116
|
-
"p" + value
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.===(x)
|
120
|
-
x.is_a? String and x[0] == "p"
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
class EndOfMessage < Token
|
126
|
-
|
127
|
-
def self.new()
|
128
|
-
nil
|
129
|
-
end
|
130
|
-
|
131
|
-
def self.===(x)
|
132
|
-
x.nil?
|
133
|
-
end
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
#
|
138
|
-
# returns Array of Token-s.
|
139
|
-
#
|
140
|
-
def tokenize(text)
|
141
|
-
yy_parse(StringIO.new(text))
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
#
|
147
|
-
# +input+ is IO. It must have working IO#pos, IO#pos= and
|
148
|
-
# IO#set_encoding() methods.
|
149
|
-
#
|
150
|
-
# It may raise YY_SyntaxError.
|
151
|
-
#
|
152
|
-
def yy_parse(input)
|
153
|
-
input.set_encoding("UTF-8", "UTF-8")
|
154
|
-
context = YY_ParsingContext.new(input)
|
155
|
-
yy_from_pcv(
|
156
|
-
yy_nonterm1(context) ||
|
157
|
-
# TODO: context.worst_error can not be nil here. Prove it.
|
158
|
-
raise(context.worst_error)
|
159
|
-
)
|
160
|
-
end
|
161
|
-
|
162
|
-
# TODO: Allow to pass String to the entry point.
|
163
|
-
|
164
|
-
|
165
|
-
# :nodoc:
|
166
|
-
### converts value to parser-compatible value (which is always non-false and
|
167
|
-
### non-nil).
|
168
|
-
def yy_to_pcv(value)
|
169
|
-
if value.nil? then :yy_nil
|
170
|
-
elsif value == false then :yy_false
|
171
|
-
else value
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# :nodoc:
|
176
|
-
### converts value got by #yy_to_pcv() to actual value.
|
177
|
-
def yy_from_pcv(value)
|
178
|
-
if value == :yy_nil then nil
|
179
|
-
elsif value == :yy_false then false
|
180
|
-
else value
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
# :nodoc:
|
185
|
-
class YY_ParsingContext
|
186
|
-
|
187
|
-
# +input+ is IO.
|
188
|
-
def initialize(input)
|
189
|
-
@input = input
|
190
|
-
@worst_error = nil
|
191
|
-
end
|
192
|
-
|
193
|
-
attr_reader :input
|
194
|
-
|
195
|
-
# It is YY_SyntaxExpectationError or nil.
|
196
|
-
attr_accessor :worst_error
|
197
|
-
|
198
|
-
# adds possible error to this YY_ParsingContext.
|
199
|
-
#
|
200
|
-
# +error+ is YY_SyntaxExpectationError.
|
201
|
-
#
|
202
|
-
def << error
|
203
|
-
# Update worst_error.
|
204
|
-
if worst_error.nil? or worst_error.pos < error.pos then
|
205
|
-
@worst_error = error
|
206
|
-
elsif worst_error.pos == error.pos then
|
207
|
-
@worst_error = @worst_error.or error
|
208
|
-
end
|
209
|
-
#
|
210
|
-
return self
|
211
|
-
end
|
212
|
-
|
213
|
-
end
|
214
|
-
|
215
|
-
# :nodoc:
|
216
|
-
def yy_string(context, string)
|
217
|
-
#
|
218
|
-
string_start_pos = context.input.pos
|
219
|
-
# Read string.
|
220
|
-
read_string = context.input.read(string.bytesize)
|
221
|
-
# Set the string's encoding; check if it fits the argument.
|
222
|
-
unless read_string and (read_string.force_encoding(Encoding::UTF_8)) == string then
|
223
|
-
#
|
224
|
-
context << YY_SyntaxExpectationError.new(yy_displayed(string), string_start_pos)
|
225
|
-
#
|
226
|
-
return nil
|
227
|
-
end
|
228
|
-
#
|
229
|
-
return read_string
|
230
|
-
end
|
231
|
-
|
232
|
-
# :nodoc:
|
233
|
-
def yy_end?(context)
|
234
|
-
#
|
235
|
-
if not context.input.eof?
|
236
|
-
context << YY_SyntaxExpectationError.new("the end", context.input.pos)
|
237
|
-
return nil
|
238
|
-
end
|
239
|
-
#
|
240
|
-
return true
|
241
|
-
end
|
242
|
-
|
243
|
-
# :nodoc:
|
244
|
-
def yy_begin?(context)
|
245
|
-
#
|
246
|
-
if not(context.input.pos == 0)
|
247
|
-
context << YY_SyntaxExpectationError.new("the beginning", context.input.pos)
|
248
|
-
return nil
|
249
|
-
end
|
250
|
-
#
|
251
|
-
return true
|
252
|
-
end
|
253
|
-
|
254
|
-
# :nodoc:
|
255
|
-
def yy_char(context)
|
256
|
-
#
|
257
|
-
char_start_pos = context.input.pos
|
258
|
-
# Read a char.
|
259
|
-
c = context.input.getc
|
260
|
-
#
|
261
|
-
unless c then
|
262
|
-
#
|
263
|
-
context << YY_SyntaxExpectationError.new("a character", char_start_pos)
|
264
|
-
#
|
265
|
-
return nil
|
266
|
-
end
|
267
|
-
#
|
268
|
-
return c
|
269
|
-
end
|
270
|
-
|
271
|
-
# :nodoc:
|
272
|
-
def yy_char_range(context, from, to)
|
273
|
-
#
|
274
|
-
char_start_pos = context.input.pos
|
275
|
-
# Read the char.
|
276
|
-
c = context.input.getc
|
277
|
-
# Check if it fits the range.
|
278
|
-
# NOTE: c has UTF-8 encoding.
|
279
|
-
unless c and (from <= c and c <= to) then
|
280
|
-
#
|
281
|
-
context << YY_SyntaxExpectationError.new(%(#{yy_displayed from}...#{yy_displayed to}), char_start_pos)
|
282
|
-
#
|
283
|
-
return nil
|
284
|
-
end
|
285
|
-
#
|
286
|
-
return c
|
287
|
-
end
|
288
|
-
|
289
|
-
# :nodoc:
|
290
|
-
### The form of +string+ suitable for displaying in messages.
|
291
|
-
def yy_displayed(string)
|
292
|
-
if string.length == 1 then
|
293
|
-
char = string[0]
|
294
|
-
char_code = char.ord
|
295
|
-
case char_code
|
296
|
-
when 0x00...0x20, 0x2028, 0x2029 then %(#{yy_unicode_s char_code})
|
297
|
-
when 0x20...0x80 then %("#{char}")
|
298
|
-
when 0x80...Float::INFINITY then %("#{char} (#{yy_unicode_s char_code})")
|
299
|
-
end
|
300
|
-
else
|
301
|
-
%("#{string}")
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
# :nodoc:
|
306
|
-
### "U+XXXX" string corresponding to +char_code+.
|
307
|
-
def yy_unicode_s(char_code)
|
308
|
-
"U+#{"%04X" % char_code}"
|
309
|
-
end
|
310
|
-
|
311
|
-
class YY_SyntaxError < Exception
|
312
|
-
|
313
|
-
def initialize(message, pos)
|
314
|
-
super(message)
|
315
|
-
@pos = pos
|
316
|
-
end
|
317
|
-
|
318
|
-
attr_reader :pos
|
319
|
-
|
320
|
-
end
|
321
|
-
|
322
|
-
# :nodoc:
|
323
|
-
class YY_SyntaxExpectationError < YY_SyntaxError
|
324
|
-
|
325
|
-
#
|
326
|
-
# +expectations+ are String-s.
|
327
|
-
#
|
328
|
-
def initialize(*expectations, pos)
|
329
|
-
super(nil, pos)
|
330
|
-
@expectations = expectations
|
331
|
-
end
|
332
|
-
|
333
|
-
#
|
334
|
-
# returns other YY_SyntaxExpectationError with #expectations combined.
|
335
|
-
#
|
336
|
-
# +other+ is another YY_SyntaxExpectationError.
|
337
|
-
#
|
338
|
-
# #pos of this YY_SyntaxExpectationError and +other+ must be equal.
|
339
|
-
#
|
340
|
-
def or other
|
341
|
-
raise %(can not "or" #{YY_SyntaxExpectationError}s with different pos) unless self.pos == other.pos
|
342
|
-
YY_SyntaxExpectationError.new(*(self.expectations + other.expectations), pos)
|
343
|
-
end
|
344
|
-
|
345
|
-
def message
|
346
|
-
expectations = self.expectations.uniq
|
347
|
-
(
|
348
|
-
if expectations.size == 1 then expectations.first
|
349
|
-
else [expectations[0...-1].join(", "), expectations[-1]].join(" or ")
|
350
|
-
end
|
351
|
-
) + " is expected"
|
352
|
-
end
|
353
|
-
|
354
|
-
protected
|
355
|
-
|
356
|
-
# Private
|
357
|
-
attr_reader :expectations
|
358
|
-
|
359
|
-
end
|
360
|
-
|
361
|
-
# :nodoc:
|
362
|
-
def yy_nonterm1(yy_context)
|
363
|
-
val = nil
|
364
|
-
(begin
|
365
|
-
val = []
|
366
|
-
true
|
367
|
-
end and while true
|
368
|
-
yy_vare = yy_context.input.pos
|
369
|
-
if not(begin; yy_var9 = yy_context.input.pos; (begin
|
370
|
-
yy_vara = yy_nontermf(yy_context)
|
371
|
-
if yy_vara then
|
372
|
-
w = yy_from_pcv(yy_vara)
|
373
|
-
end
|
374
|
-
yy_vara
|
375
|
-
end and begin
|
376
|
-
val << Word.new(w)
|
377
|
-
true
|
378
|
-
end) or (yy_context.input.pos = yy_var9; (begin
|
379
|
-
yy_varb = yy_nonterm14(yy_context)
|
380
|
-
if yy_varb then
|
381
|
-
p = yy_from_pcv(yy_varb)
|
382
|
-
end
|
383
|
-
yy_varb
|
384
|
-
end and begin
|
385
|
-
val << PunctuationMark.new(p)
|
386
|
-
true
|
387
|
-
end)) or (yy_context.input.pos = yy_var9; yy_nonterm24(yy_context) and while true
|
388
|
-
yy_vard = yy_context.input.pos
|
389
|
-
if not(yy_nonterm24(yy_context)) then
|
390
|
-
yy_context.input.pos = yy_vard
|
391
|
-
break true
|
392
|
-
end
|
393
|
-
end); end) then
|
394
|
-
yy_context.input.pos = yy_vare
|
395
|
-
break true
|
396
|
-
end
|
397
|
-
end) and yy_to_pcv(val)
|
398
|
-
end
|
399
|
-
|
400
|
-
# :nodoc:
|
401
|
-
def yy_nontermf(yy_context)
|
402
|
-
val = nil
|
403
|
-
(begin
|
404
|
-
val = ""
|
405
|
-
true
|
406
|
-
end and begin; yy_varp = yy_context.input.pos; begin
|
407
|
-
yy_varq = yy_nontermx(yy_context)
|
408
|
-
if yy_varq then
|
409
|
-
val << yy_from_pcv(yy_varq)
|
410
|
-
end
|
411
|
-
yy_varq
|
412
|
-
end or (yy_context.input.pos = yy_varp; (begin
|
413
|
-
yy_varr = yy_string(yy_context, "-")
|
414
|
-
if yy_varr then
|
415
|
-
h = yy_from_pcv(yy_varr)
|
416
|
-
end
|
417
|
-
yy_varr
|
418
|
-
end and begin
|
419
|
-
yy_varu = yy_context.input.pos
|
420
|
-
yy_varv = yy_nontermx(yy_context)
|
421
|
-
yy_context.input.pos = yy_varu
|
422
|
-
yy_varv
|
423
|
-
end and begin
|
424
|
-
val << h
|
425
|
-
true
|
426
|
-
end)); end and while true
|
427
|
-
yy_varw = yy_context.input.pos
|
428
|
-
if not(begin; yy_varp = yy_context.input.pos; begin
|
429
|
-
yy_varq = yy_nontermx(yy_context)
|
430
|
-
if yy_varq then
|
431
|
-
val << yy_from_pcv(yy_varq)
|
432
|
-
end
|
433
|
-
yy_varq
|
434
|
-
end or (yy_context.input.pos = yy_varp; (begin
|
435
|
-
yy_varr = yy_string(yy_context, "-")
|
436
|
-
if yy_varr then
|
437
|
-
h = yy_from_pcv(yy_varr)
|
438
|
-
end
|
439
|
-
yy_varr
|
440
|
-
end and begin
|
441
|
-
yy_varu = yy_context.input.pos
|
442
|
-
yy_varv = yy_nontermx(yy_context)
|
443
|
-
yy_context.input.pos = yy_varu
|
444
|
-
yy_varv
|
445
|
-
end and begin
|
446
|
-
val << h
|
447
|
-
true
|
448
|
-
end)); end) then
|
449
|
-
yy_context.input.pos = yy_varw
|
450
|
-
break true
|
451
|
-
end
|
452
|
-
end) and yy_to_pcv(val)
|
453
|
-
end
|
454
|
-
|
455
|
-
# :nodoc:
|
456
|
-
def yy_nontermx(yy_context)
|
457
|
-
val = nil
|
458
|
-
begin; yy_vary = yy_context.input.pos; begin
|
459
|
-
yy_varz = yy_char_range(yy_context, "a", "z")
|
460
|
-
if yy_varz then
|
461
|
-
val = yy_from_pcv(yy_varz)
|
462
|
-
end
|
463
|
-
yy_varz
|
464
|
-
end or (yy_context.input.pos = yy_vary; begin
|
465
|
-
yy_var10 = yy_char_range(yy_context, "A", "Z")
|
466
|
-
if yy_var10 then
|
467
|
-
val = yy_from_pcv(yy_var10)
|
468
|
-
end
|
469
|
-
yy_var10
|
470
|
-
end) or (yy_context.input.pos = yy_vary; begin
|
471
|
-
yy_var11 = yy_char_range(yy_context, "\u{430}", "\u{44f}")
|
472
|
-
if yy_var11 then
|
473
|
-
val = yy_from_pcv(yy_var11)
|
474
|
-
end
|
475
|
-
yy_var11
|
476
|
-
end) or (yy_context.input.pos = yy_vary; begin
|
477
|
-
yy_var12 = yy_char_range(yy_context, "\u{410}", "\u{42f}")
|
478
|
-
if yy_var12 then
|
479
|
-
val = yy_from_pcv(yy_var12)
|
480
|
-
end
|
481
|
-
yy_var12
|
482
|
-
end) or (yy_context.input.pos = yy_vary; begin
|
483
|
-
yy_var13 = yy_char_range(yy_context, "0", "9")
|
484
|
-
if yy_var13 then
|
485
|
-
val = yy_from_pcv(yy_var13)
|
486
|
-
end
|
487
|
-
yy_var13
|
488
|
-
end); end and yy_to_pcv(val)
|
489
|
-
end
|
490
|
-
|
491
|
-
# :nodoc:
|
492
|
-
def yy_nonterm14(yy_context)
|
493
|
-
val = nil
|
494
|
-
(begin
|
495
|
-
val = ""
|
496
|
-
true
|
497
|
-
end and while true
|
498
|
-
yy_var1b = yy_context.input.pos
|
499
|
-
if not(begin
|
500
|
-
yy_var1a = yy_nonterm24(yy_context)
|
501
|
-
if yy_var1a then
|
502
|
-
val << yy_from_pcv(yy_var1a)
|
503
|
-
end
|
504
|
-
yy_var1a
|
505
|
-
end) then
|
506
|
-
yy_context.input.pos = yy_var1b
|
507
|
-
break true
|
508
|
-
end
|
509
|
-
end and (begin
|
510
|
-
yy_var1s = yy_context.worst_error
|
511
|
-
yy_var1t = not(begin
|
512
|
-
yy_var1u = yy_context.input.pos
|
513
|
-
yy_var1v = yy_nontermx(yy_context)
|
514
|
-
yy_context.input.pos = yy_var1u
|
515
|
-
yy_var1v
|
516
|
-
end)
|
517
|
-
if yy_var1t
|
518
|
-
yy_context.worst_error = yy_var1s
|
519
|
-
else
|
520
|
-
# NOTE: No errors were added into context but the error is still there.
|
521
|
-
yy_context << YY_SyntaxExpectationError.new("different expression", yy_context.input.pos)
|
522
|
-
end
|
523
|
-
yy_var1t
|
524
|
-
end and begin
|
525
|
-
yy_var1w = yy_char(yy_context)
|
526
|
-
if yy_var1w then
|
527
|
-
val << yy_from_pcv(yy_var1w)
|
528
|
-
end
|
529
|
-
yy_var1w
|
530
|
-
end) and while true
|
531
|
-
yy_var1x = yy_context.input.pos
|
532
|
-
if not((begin
|
533
|
-
yy_var1s = yy_context.worst_error
|
534
|
-
yy_var1t = not(begin
|
535
|
-
yy_var1u = yy_context.input.pos
|
536
|
-
yy_var1v = yy_nontermx(yy_context)
|
537
|
-
yy_context.input.pos = yy_var1u
|
538
|
-
yy_var1v
|
539
|
-
end)
|
540
|
-
if yy_var1t
|
541
|
-
yy_context.worst_error = yy_var1s
|
542
|
-
else
|
543
|
-
# NOTE: No errors were added into context but the error is still there.
|
544
|
-
yy_context << YY_SyntaxExpectationError.new("different expression", yy_context.input.pos)
|
545
|
-
end
|
546
|
-
yy_var1t
|
547
|
-
end and begin
|
548
|
-
yy_var1w = yy_char(yy_context)
|
549
|
-
if yy_var1w then
|
550
|
-
val << yy_from_pcv(yy_var1w)
|
551
|
-
end
|
552
|
-
yy_var1w
|
553
|
-
end)) then
|
554
|
-
yy_context.input.pos = yy_var1x
|
555
|
-
break true
|
556
|
-
end
|
557
|
-
end and while true
|
558
|
-
yy_var23 = yy_context.input.pos
|
559
|
-
if not(begin
|
560
|
-
yy_var22 = yy_nonterm24(yy_context)
|
561
|
-
if yy_var22 then
|
562
|
-
val << yy_from_pcv(yy_var22)
|
563
|
-
end
|
564
|
-
yy_var22
|
565
|
-
end) then
|
566
|
-
yy_context.input.pos = yy_var23
|
567
|
-
break true
|
568
|
-
end
|
569
|
-
end) and yy_to_pcv(val)
|
570
|
-
end
|
571
|
-
|
572
|
-
# :nodoc:
|
573
|
-
def yy_nonterm24(yy_context)
|
574
|
-
val = nil
|
575
|
-
(begin; yy_var27 = yy_context.input.pos; yy_char_range(yy_context, "\t", "\r") or (yy_context.input.pos = yy_var27; yy_string(yy_context, " ")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{85}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{a0}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{1680}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{180e}")) or (yy_context.input.pos = yy_var27; yy_char_range(yy_context, "\u{2000}", "\u{200a}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{2028}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{2029}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{202f}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{205f}")) or (yy_context.input.pos = yy_var27; yy_string(yy_context, "\u{3000}")); end and begin
|
576
|
-
val = " "
|
577
|
-
true
|
578
|
-
end) and yy_to_pcv(val)
|
579
|
-
end
|
580
|
-
|
581
|
-
end
|
582
|
-
|