yaparc 0.2.3 → 0.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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.envrc +1 -0
  4. data/.rdoc_options +1 -0
  5. data/CHANGELOG.md +19 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +20 -0
  8. data/README +106 -86
  9. data/Rakefile +27 -0
  10. data/TODO +11 -0
  11. data/lib/yaparc/abstract_parser.rb +16 -0
  12. data/lib/yaparc/alt.rb +22 -0
  13. data/lib/yaparc/apply.rb +18 -0
  14. data/lib/yaparc/char.rb +16 -0
  15. data/lib/yaparc/cr.rb +11 -0
  16. data/lib/yaparc/digit.rb +11 -0
  17. data/lib/yaparc/fail_parser.rb +11 -0
  18. data/lib/yaparc/ident.rb +18 -0
  19. data/lib/yaparc/identifier.rb +32 -0
  20. data/lib/yaparc/item.rb +17 -0
  21. data/lib/yaparc/literal.rb +13 -0
  22. data/lib/yaparc/many.rb +14 -0
  23. data/lib/yaparc/many_one.rb +27 -0
  24. data/lib/yaparc/nat.rb +11 -0
  25. data/lib/yaparc/natural.rb +12 -0
  26. data/lib/yaparc/no_fail.rb +20 -0
  27. data/lib/yaparc/parsable.rb +20 -0
  28. data/lib/yaparc/regex.rb +22 -0
  29. data/lib/yaparc/satisfy.rb +28 -0
  30. data/lib/yaparc/seq.rb +33 -0
  31. data/lib/yaparc/space.rb +11 -0
  32. data/lib/yaparc/string.rb +24 -0
  33. data/lib/yaparc/succeed.rb +14 -0
  34. data/lib/yaparc/symbol.rb +11 -0
  35. data/lib/yaparc/tokenize.rb +18 -0
  36. data/lib/yaparc/white_space.rb +11 -0
  37. data/lib/yaparc/zero_one.rb +20 -0
  38. data/lib/yaparc.rb +40 -605
  39. data/sig/yaparc.gen.rbs +217 -0
  40. data/sig/yaparc.rbs +4 -0
  41. data/yaparc.gemspec +36 -0
  42. metadata +115 -58
  43. data/test/n3-report.html +0 -169
  44. data/test/n3.bnf +0 -129
  45. data/test/test_abc.rb.bak +0 -112
  46. data/test/test_calc.rb +0 -112
  47. data/test/test_lambda.rb +0 -87
  48. data/test/test_metric.rb +0 -617
  49. data/test/test_owl.rb +0 -1039
  50. data/test/test_parser.rb +0 -460
  51. data/test/test_prolog.rb +0 -287
  52. data/test/test_sql.rb +0 -317
  53. data/test/test_uri.rb +0 -752
data/lib/yaparc.rb CHANGED
@@ -1,612 +1,47 @@
1
- module Yaparc
2
- module Result
3
- class Base
4
- attr_accessor :message, :input, :value
5
- def initialize(options = {})
6
- @message = options[:message] if options[:message]
7
- @input = options[:input] if options[:input]
8
- @value = options[:value]
9
- end
10
- end
11
-
12
- class OK < Base
13
- end
14
-
15
- class Fail < Base
16
- end
17
-
18
- class Error < Base
19
- end
20
- end # of module Result
21
-
22
- module Parsable
23
- attr_accessor :tree
24
-
25
- IS_LOWER = lambda {|c| c >= 'a' and c <= 'z'}
26
- IS_ALPHANUM = lambda {|c| (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9')}
27
- IS_DIGIT = lambda {|i| i >= '0' and i <= '9'}
28
- IS_SPACE = lambda {|i| i == ' '}
29
- IS_WHITESPACE = lambda {|i| i == ' ' or i == "\n" or i == "\t"}
30
- IS_CR = lambda {|i| i == "\n"}
31
-
32
- def parse(input) #, &block)
33
- result = @parser.call(input)
34
-
35
- if result.respond_to?(:parse)
36
- result.parse(input)
37
- else
38
- result
39
- end
40
- end
41
-
42
- end # of Module Parsable
43
-
44
- class Succeed
45
- include Parsable
46
- attr_reader :remaining
47
-
48
- def initialize(value, remaining = nil)
49
- @parser = lambda do |input|
50
- Result::OK.new(:value => value, :input => input)
51
- end
52
- @remaining = remaining
53
- end
54
- end
55
-
56
- class Fail
57
- include Parsable
58
- def initialize
59
- @parser = lambda do |input|
60
- Result::Fail.new(:input => input)
61
- end
62
- end
63
- end
64
-
65
-
66
- class Item
67
- include Parsable
68
-
69
- def initialize
70
- @parser = lambda do |input|
71
- if input.nil? or input.empty?
72
- Result::Fail.new(:input => input)
73
- else
74
- Result::OK.new(:value => input[0..0],:input => input[1..input.length])
75
- end
76
- end
77
- end
78
- end
79
-
80
- class ZeroOne
81
- include Parsable
82
-
83
- def initialize(parser, identity = [])
84
- @parser = lambda do |input|
85
- case result = parser.parse(input)
86
- when Result::Fail
87
- Result::OK.new(:value => identity, :input => input)
88
- # Succeed.new(identity)
89
- when Result::Error
90
- Result::Error.new(:value => result.value, :input => result.input)
91
- when Result::OK
92
- result
93
- else
94
- raise
95
- end
96
- end
97
- end
98
- end
99
-
100
- class Satisfy
101
- include Parsable
102
-
103
- def initialize(predicate)
104
- raise unless predicate.instance_of?(Proc)
105
- @parser = lambda do |input|
106
- result = Item.new.parse(input)
107
- if result.instance_of?(Result::OK) and predicate.call(result.value)
108
- Succeed.new(result.value, result.input)
109
- else
110
- Fail.new
111
- end
112
- end
113
- end
114
-
115
- def parse(input)
116
- case parser = @parser.call(input)
117
- when Succeed
118
- parser.parse(parser.remaining)
119
- when Fail
120
- parser.parse(input)
121
- else
122
- raise
123
- end
124
- end
125
- end
126
-
127
-
128
- class NoFail
129
- # hutton92:_higher_order_funct_parsin,p.19
130
- include Parsable
131
-
132
- def initialize(parser, &block)
133
- @parser = lambda do |input|
134
- result = parser.parse(input)
135
- if result.instance_of?(Result::Fail)
136
- Result::Error.new(:value => result.value, :input => result.input)
137
- else
138
- Succeed.new(result.value)
139
- end
140
- end
141
- end
142
- end # of NoFail
143
-
144
-
145
- class Seq
146
- include Parsable
147
-
148
- def initialize(*parsers, &block)
149
- @parser = lambda do |input|
150
- args = []
151
- initial_result = Result::OK.new(:input => input)
152
- final_result = parsers.inject(initial_result) do |subsequent, parser|
153
- result = parser.parse(subsequent.input)
154
- if result.instance_of?(Result::Fail)
155
- break Result::Fail.new(:input => subsequent.input)
156
- else
157
- args << result.value
158
- result
159
- end
160
- end
161
-
162
- case final_result
163
- when Result::Fail
164
- Result::Fail.new(:input => final_result.input)
165
- when Result::OK
166
- final_value = if block_given?
167
- yield(*args)
168
- else
169
- args.last
170
- end
171
- Result::OK.new(:value => final_value, :input => final_result.input)
172
- else
173
- raise
174
- end
175
- end
176
- end # of initialize
177
- end # of Seq
178
-
179
- class Alt
180
- include Parsable
181
- def initialize(*parsers)
182
- @parser = lambda do |input|
183
- final_result = Result::Fail.new(:input => input)
184
- parsers.each do |parser|
185
- case result = parser.parse(input)
186
- when Result::Fail
187
- next
188
- # when Result::Error
189
- # raise
190
- # return Result::Error.new(:value => result.value, :input => result.input)
191
- when Result::OK
192
- break final_result = result
193
- else
194
- raise
195
- end
196
- end
197
- final_result
198
- end
199
- end # of initialize
200
- end
201
-
202
- # class Alt
203
- # include Parsable
204
- # def initialize(*parsers)
205
- # @parser = lambda do |input|
206
- # if head = parsers[0]
207
- # case result = head.parse(input)
208
- # when Result::Fail
209
- # if parsers.empty?
210
- # result
211
- # else
212
- # Alt.new(*parsers[1..-1]).parse(input)
213
- # end
214
- # when Result::OK
215
- # result
216
- # else
217
- # raise
218
- # end
219
- # else
220
- # Result::Fail.new(:input => input)
221
- # end
222
- # end
223
- # end # of initialize
224
- # end
225
-
226
-
227
- class Apply
228
- include Parsable
229
-
230
- def initialize(parser, &block)
231
- @parser = lambda do |input|
232
- result = parser.parse(input)
233
- if result.instance_of?(Result::OK)
234
- Succeed.new(yield(result.value)).parse(result.input)
235
- else
236
- Fail.new.parse(input)
237
- end
238
- end
239
- end # of initialize
240
- end # of Apply
241
-
242
-
243
- class String
244
- include Parsable
245
-
246
- def initialize(string, case_sensitive = true)
247
- @parser = lambda do |input|
248
- result = Item.new.parse(string)
249
- if result.instance_of?(Result::OK)
250
- Seq.new(
251
- Char.new(result.value, case_sensitive),
252
- Yaparc::String.new(result.input, case_sensitive),
253
- Succeed.new(result.value + result.input)
254
- # ) do |char_result, string_result, succeed_result|
255
- ) do |_, _, succeed_result|
256
- succeed_result
257
- end
258
- else
259
- Succeed.new(result)
260
- end
261
- end
262
- end
263
- end
264
-
265
- class Regex
266
- include Parsable
267
-
268
- def initialize(regex, &block)
269
- @regex = regex
270
- @parser = lambda do |input|
271
- if match = Regexp.new(regex).match(input)
272
- if block_given?
273
- Succeed.new(yield(*match.to_a[1..match.to_a.length])).parse(match.post_match)
274
- else
275
- Result::OK.new(:value => match[0], :input => match.post_match)
276
- end
277
- else
278
- Result::Fail.new(:input => input)
279
- end
280
- end
281
- end
282
-
283
- # def parse_with_parameter(input)
284
- # raise "Deprecated!! Use Regex with block"
285
- # if match = Regexp.new(@regex).match(input)
286
- # if block_given?
287
- # yield match.to_a[1..match.to_a.length]
288
- # else
289
- # Result::OK.new(:value => match, :input => match.post_match)
290
- # end
291
- # else
292
- # Result::Fail.new(:input => input)
293
- # end
294
- # end
295
- end
296
-
297
- # permits zero or more applications of parser.
298
- class Many
299
- include Parsable
300
-
301
- def initialize(parser, identity = [])
302
- @parser = lambda do |input|
303
- Alt.new(ManyOne.new(parser, identity), Succeed.new(identity))
304
- end
305
- end
306
- end
307
-
308
- # requires at least one successfull application of parser.
309
- class ManyOne
310
- include Parsable
311
-
312
- def initialize(parser, identity = [])
313
- @parser = lambda do |input|
314
- Seq.new(parser, Many.new(parser, identity)) do |head, tail|
315
- case head
316
- when ::String
317
- if tail.instance_of?(::String)
318
- head + tail
319
- else
320
- raise "Incompatible type: head => #{head.inspect}, tail => #{tail.inspect}"
321
- end
322
- when ::Array
323
- if tail.instance_of?(Array)
324
- head + tail
325
- else
326
- raise "Incompatible type: head => #{head.inspect}, tail => #{tail.inspect}"
327
- end
328
- when ::Hash
329
- if tail.instance_of?(Hash)
330
- head.merge(tail)
331
- else
332
- raise "Incompatible type: head => #{head.inspect}, tail => #{tail.inspect}"
333
- end
334
- when ::Integer
335
- if tail.kind_of?(Integer)
336
- head + tail
337
- else
338
- raise "Incompatible type: head => #{head.inspect}, tail => #{tail.inspect}"
339
- end
340
- else
341
- if tail.nil?
342
- head
343
- else
344
- [head] + tail
345
- end
346
- end
347
- end
348
- end
349
- end
350
- end
351
-
352
- class Space
353
- include Parsable
354
- def initialize
355
- @parser = lambda do |input|
356
- #Many.new(Satisfy.new(IS_SPACE),"")
357
- Regex.new(/\A[ ]*/)
358
- end
359
- end
360
- end
361
-
362
- class CR
363
- include Parsable
364
- def initialize
365
- @parser = lambda do |input|
366
- Regex.new(/\A[ \t]+[\n][ \t\n]+/)
367
- end
368
- end
369
- end
370
-
371
- class WhiteSpace
372
- include Parsable
373
-
374
- def initialize
375
- @parser = lambda do |input|
376
- #Many.new(Satisfy.new(IS_WHITESPACE),'')
377
- Regex.new(/\A[\t\n ]*/)
378
- end
379
- end
380
- end
381
-
382
- class Tokenize
383
- include Parsable
384
- attr_accessor :prefix, :postfix
385
-
386
- def initialize(parser, args = {}, &block)
387
- @parser = lambda do |input|
388
- @prefix = args[:prefix] ? args[:prefix] : WhiteSpace.new
389
- @postfix = args[:postfix] ? args[:postfix] : WhiteSpace.new
390
- if block_given?
391
- yield self
392
- Seq.new(@prefix, parser, @postfix) do |_, vs, _|
393
- vs
394
- end
395
- else
396
- Seq.new(@prefix, parser, @postfix) do |_, vs, _|
397
- vs
398
- end
399
- end
400
- end
401
- end
402
- end
403
-
404
- class Literal
405
- include Parsable
406
-
407
- def initialize(literal, case_sensitive = true)
408
- @parser = lambda do |input|
409
- Tokenize.new(Yaparc::String.new(literal, case_sensitive))
410
- end
411
- end
412
- end
413
-
414
- # class Tokenizer
415
- # include Parsable
416
- # attr_accessor :prefix, :postfix
417
-
418
- # def initialize(args = {})
419
- # @parser = lambda do |input|
420
- # @prefix = args[:prefix] ? args[:prefix] : WhiteSpace.new
421
- # @postfix = args[:postfix] ? args[:postfix] : WhiteSpace.new
422
- # end
423
- # end
424
-
425
- # def tokenize(&block)
426
- # parser = yield
427
-
428
- # Seq.new(@prefix, parser, @postfix) do |_, vs, _|
429
- # vs
430
- # end
431
- # end
432
- # end
433
-
434
- # class Literalizer
435
- # include Parsable
436
-
437
- # def initialize(literal, options = {})
438
- # unless case_sensitive = options[:case_sensitive]
439
- # true
440
- # end
441
-
442
- # unless tokenizer = options[:tokenizer]
443
- # tokenizer = Tokenizer.new
444
- # end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'yaparc/alt'
4
+ require_relative 'yaparc/apply'
5
+ require_relative 'yaparc/char'
6
+ require_relative 'yaparc/cr'
7
+ require_relative 'yaparc/digit'
8
+ require_relative 'yaparc/fail_parser'
9
+ require_relative 'yaparc/ident'
10
+ require_relative 'yaparc/identifier'
11
+ require_relative 'yaparc/item'
12
+ require_relative 'yaparc/literal'
13
+ require_relative 'yaparc/many'
14
+ require_relative 'yaparc/many_one'
15
+ require_relative 'yaparc/nat'
16
+ require_relative 'yaparc/natural'
17
+ require_relative 'yaparc/no_fail'
18
+ require_relative 'yaparc/parsable'
19
+ require_relative 'yaparc/regex'
20
+ require_relative 'yaparc/satisfy'
21
+ require_relative 'yaparc/seq'
22
+ require_relative 'yaparc/space'
23
+ require_relative 'yaparc/string'
24
+ require_relative 'yaparc/succeed'
25
+ require_relative 'yaparc/symbol'
26
+ require_relative 'yaparc/tokenize'
27
+ require_relative 'yaparc/white_space'
28
+ require_relative 'yaparc/zero_one'
445
29
 
446
- # @parser = lambda do |input|
447
- # tokenizer.tokenize do
448
- # Yaparc::String.new(literal, case_sensitive)
449
- # end
450
- # end
451
- # end
452
- # end
453
-
454
- # Refer to http://www.cs.nott.ac.uk/~gmh/monparsing.pdf, p.23
455
- class Identifier
456
- include Yaparc::Parsable
457
- @@identifier_regex = /\A[a-zA-Z_]+[a-zA-Z0-9_]*/
458
-
459
- def initialize(options = {})
460
- identifier_regex = if regex = options[:regex]
461
- ::Yaparc::Regex.new(regex)
462
- else
463
- ::Yaparc::Regex.new(@@identifier_regex)
464
- end
465
-
466
- tokenizer = Tokenize.new(identifier_regex)
467
-
468
- if exclude = options[:exclude]
469
- @parser = lambda do |input|
470
- keyword_parsers = exclude.map {|keyword| Yaparc::String.new(keyword)}
471
-
472
- case result = Yaparc::Alt.new(*keyword_parsers).parse(input)
473
- when Yaparc::Result::OK
474
- Yaparc::Fail.new
475
- else # Result::Fail or Result::Error
476
- tokenizer
477
- end
478
- end
479
- else
480
- @parser = lambda do |input|
481
- tokenizer
482
- end
483
- end
484
- end
485
- end
486
-
487
- # class Identifier
488
- # include Yaparc::Parsable
489
- # @@identifier_regex = ::Yaparc::Regex.new(/\A[a-zA-Z_]+[a-zA-Z0-9_]*/)
490
-
491
- # def initialize(*keywords)
492
- # # def initialize(*keywords, &block)
493
- # if keywords == []
494
- # @parser = lambda do |input|
495
- # Tokenize.new(@@identifier_regex)
496
- # # if block_given?
497
- # # tokenize = Tokenize.new(@@identifier_regex)
498
- # # yield tokenize
499
- # # tokenize
500
- # # else
501
- # # Tokenize.new(@@identifier_regex)
502
- # # end
503
- # end
504
- # else
505
- # @parser = lambda do |input|
506
- # keyword_parsers = keywords.map {|keyword| Yaparc::String.new(keyword)}
507
-
508
- # case result = Yaparc::Alt.new(*keyword_parsers).parse(input)
509
- # when Yaparc::Result::OK
510
- # Yaparc::Fail.new
511
- # else # Result::Fail or Result::Error
512
- # Tokenize.new(@@identifier_regex)
513
- # end
514
- # end
515
- # end
516
- # end
517
- # end
518
-
519
- class Char
520
- include Parsable
521
-
522
- def initialize(char, case_sensitive = true)
523
- raise unless char.length == 1
524
- if case_sensitive
525
- equal_char = lambda {|i| i == char}
526
- else # in case of case-insentive
527
- equal_char = lambda {|i| i.casecmp(char) == 0}
528
- end
529
- @parser = lambda do |input|
530
- Satisfy.new(equal_char)
531
- end
532
- end
533
- end
534
-
535
- class Ident
536
- include Parsable
537
- def initialize
538
- @parser = lambda do |input|
539
- Seq.new(
540
- Satisfy.new(IS_LOWER),
541
- Many.new(Satisfy.new(IS_ALPHANUM),"")
542
- ) do |head, tail|
543
- head + tail
544
- end
545
- end
546
- end
547
- end
548
-
549
- class Digit
550
- include Parsable
551
- def initialize
552
- @parser = lambda do |input|
553
- Satisfy.new(IS_DIGIT)
554
- end
555
- end
556
- end
557
-
558
- class Nat
559
- include Parsable
560
- def initialize
561
- @parser = lambda do |input|
562
- Seq.new(ManyOne.new(Digit.new,'')) do |vs|
563
- if vs == ""
564
- 0 # vs
565
- else
566
- vs.to_i
567
- end
568
- end
569
- end
570
- end
571
- end
30
+ module Yaparc
31
+ VERSION = '0.4.0'
572
32
 
33
+ begin
34
+ base = Class.new do
35
+ attr :input, :value
573
36
 
574
- class Natural
575
- include Parsable
576
- def initialize(args = {})
577
- @parser = lambda do |input|
578
- Tokenize.new(Nat.new, args)
37
+ def initialize(input:, value: nil)
38
+ @input = input
39
+ @value = value
579
40
  end
580
41
  end
581
- end
582
42
 
583
- class Symbol
584
- include Parsable
585
- def initialize(literal, args = {})
586
- @parser = lambda do |input|
587
- Literal.new(literal)
588
- end
589
- end
590
- end
591
-
592
- class AbstractParser
593
- include Parsable
594
-
595
- # def parse(input, &block)
596
- # tree = @parser.call.parse(input)
597
- # if block_given?
598
- # yield tree
599
- # else
600
- # tree
601
- # end
602
- # end
603
- def parse(input, &block)
604
- tree = @parser.call.parse(input)
605
- if block_given?
606
- @tree = yield tree
607
- else
608
- @tree = tree
609
- end
610
- end
43
+ OK = Class.new(base)
44
+ Fail = Class.new(base)
45
+ Error = Class.new(base)
611
46
  end
612
- end # of Yaparc
47
+ end