yaparc 0.1.6 → 0.2.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.
- data/README +36 -36
- data/lib/yaparc.rb +121 -199
- data/tests/test_abc.rb +40 -41
- data/tests/test_calc.rb +24 -29
- data/tests/test_owl.rb +986 -15
- data/tests/test_parser.rb +94 -45
- data/tests/test_sql.rb +98 -106
- data/tests/test_uri.rb +100 -100
- metadata +2 -2
data/README
CHANGED
@@ -19,39 +19,39 @@ All parsers has 'parse' method, each of which takes input string as its argument
|
|
19
19
|
|
20
20
|
== Primitive Parsers
|
21
21
|
|
22
|
-
*
|
23
|
-
*
|
24
|
-
*
|
25
|
-
*
|
22
|
+
* Succeed
|
23
|
+
* Fail
|
24
|
+
* Item
|
25
|
+
* Satisfy
|
26
26
|
|
27
|
-
===
|
27
|
+
=== Succeed class
|
28
28
|
|
29
|
-
The parser
|
30
|
-
In the following example,
|
29
|
+
The parser Succeed always succeeds with the result value, without consuming any of the input string.
|
30
|
+
In the following example, Succeed#parse takes an input string "blah, blah, blah" and returns the singleton array [[1, "blah, blah, blah"]].
|
31
31
|
|
32
|
-
parser = Yaparc::
|
32
|
+
parser = Yaparc::Succeed.new(1)
|
33
33
|
parser.parse("blah, blah, blah")
|
34
34
|
=> #<Yaparc::Result::OK:0xb7aaaf5c @input="blah, blah, blah", @value=1>
|
35
35
|
|
36
|
-
===
|
36
|
+
=== Fail class
|
37
37
|
|
38
|
-
The parser
|
38
|
+
The parser Fail always fails, regardless of the contents of the input string.
|
39
39
|
|
40
|
-
parser = Yaparc::
|
40
|
+
parser = Yaparc::Fail.new
|
41
41
|
parser.parse("abc")
|
42
42
|
=> #<Yaparc::Result::Fail:0xb7aa56b0 @value=nil>
|
43
43
|
|
44
|
-
===
|
44
|
+
=== Item class
|
45
45
|
|
46
|
-
The parser
|
46
|
+
The parser Item fails if the input string is empty, and succeeds with the first character as the result value otherwise.
|
47
47
|
|
48
|
-
parser = Yaparc::
|
48
|
+
parser = Yaparc::Item.new
|
49
49
|
parser.parse("abc")
|
50
50
|
=> #<Yaparc::Result::OK:0xb7a9fdb4 @input="bc", @value="a">
|
51
51
|
|
52
|
-
===
|
52
|
+
=== Satisfy class
|
53
53
|
|
54
|
-
The parser
|
54
|
+
The parser Satisfy recognizes a single input via predicate which determines if an arbitrary input is suitable for the predicate.
|
55
55
|
|
56
56
|
is_integer = lambda do |i|
|
57
57
|
begin
|
@@ -61,31 +61,31 @@ The parser SatisfyParser recognizes a single input via predicate which determine
|
|
61
61
|
false
|
62
62
|
end
|
63
63
|
end
|
64
|
-
parser = Yaparc::
|
64
|
+
parser = Yaparc::Satisfy.new(is_integer)
|
65
65
|
parser.parse("123")
|
66
66
|
=> #<Yaparc::Result::OK:0xb7a8f284 @input="23", @value="1">
|
67
67
|
|
68
68
|
|
69
69
|
== Combining Parsers
|
70
70
|
|
71
|
-
*
|
72
|
-
*
|
73
|
-
*
|
74
|
-
*
|
71
|
+
* Alt
|
72
|
+
* Seq
|
73
|
+
* Many
|
74
|
+
* ManyOne
|
75
75
|
|
76
76
|
|
77
77
|
|
78
78
|
=== Sequencing parser
|
79
79
|
|
80
|
-
The
|
80
|
+
The Seq corresponds to sequencing in BNF. The following parser recognizes anything that Symbol.new('+') or Natural.new would if placed in succession.
|
81
81
|
|
82
|
-
parser =
|
82
|
+
parser = Seq.new(Symbol.new('+'), Natural.new)
|
83
83
|
parser.parse("+321")
|
84
84
|
=> #<Yaparc::Result::OK:0xb7a81ae4 @input="", @value=321>
|
85
85
|
|
86
|
-
if a block given to
|
86
|
+
if a block given to Seq, it analyses input string to construct its logical structure.
|
87
87
|
|
88
|
-
parser = Yaparc::
|
88
|
+
parser = Yaparc::Seq.new(Yaparc::Symbol.new('+'), Yaparc::Natural.new) do | plus, nat|
|
89
89
|
nat
|
90
90
|
end
|
91
91
|
parser.parse("+1234")
|
@@ -95,11 +95,11 @@ It produces a parse tree which expounds the semantic structure of the program.
|
|
95
95
|
|
96
96
|
=== Alternation parser
|
97
97
|
|
98
|
-
The parser
|
98
|
+
The parser Alt class is an alternation parser, which returns the result of the first parser to succeed, and failure if neither does.
|
99
99
|
|
100
100
|
|
101
|
-
parser = Yaparc::
|
102
|
-
Yaparc::
|
101
|
+
parser = Yaparc::Alt.new(
|
102
|
+
Yaparc::Seq.new(Yaparc::Symbol.new('+'), Yaparc::Natural.new) do | _, nat|
|
103
103
|
nat
|
104
104
|
end,
|
105
105
|
Yaparc::Natural.new
|
@@ -110,17 +110,17 @@ The parser AltParser class is an alternation parser, which returns the result of
|
|
110
110
|
=> #<Yaparc::Result::Fail:0xb7a57ba4 @value=nil>
|
111
111
|
|
112
112
|
|
113
|
-
===
|
113
|
+
=== Many
|
114
114
|
|
115
|
-
In
|
115
|
+
In Many, zero or more applications of parser are admissible.
|
116
116
|
|
117
|
-
parser = Yaparc::
|
117
|
+
parser = Yaparc::Many.new(Yaparc::Satisfy.new(lambda {|i| i > '0' and i < '9'}))
|
118
118
|
parser.parse("123abc")
|
119
119
|
=> #<Yaparc::Result::OK:0xb7a49dc4 @input="abc", @value="123">
|
120
120
|
|
121
|
-
===
|
121
|
+
=== ManyOne
|
122
122
|
|
123
|
-
The
|
123
|
+
The ManyOne requires at least one successfull application of parser.
|
124
124
|
|
125
125
|
|
126
126
|
== Tokenized parser
|
@@ -143,7 +143,7 @@ In order to construct parsers, you make parser class to be inherited from Yaparc
|
|
143
143
|
class Identifier < Yaparc::AbstractParser
|
144
144
|
def initialize
|
145
145
|
@parser = lambda do
|
146
|
-
Yaparc::
|
146
|
+
Yaparc::Tokenize.new(Yaparc::Ident.new)
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
@@ -154,8 +154,8 @@ In the following example, note that Expr class is instantiated inside Expr#initi
|
|
154
154
|
class Expr < Yaparc::AbstractParser
|
155
155
|
def initialize
|
156
156
|
@parser = lambda do
|
157
|
-
Yaparc::
|
158
|
-
Yaparc::
|
157
|
+
Yaparc::Alt.new(
|
158
|
+
Yaparc::Seq.new(Term.new,
|
159
159
|
Yaparc::Symbol.new('+'),
|
160
160
|
Expr.new) do |term, _, expr|
|
161
161
|
['+', term,expr]
|
data/lib/yaparc.rb
CHANGED
@@ -56,18 +56,13 @@ module Yaparc
|
|
56
56
|
module ClassMethods
|
57
57
|
def included(mod)
|
58
58
|
end
|
59
|
-
|
60
|
-
# def define_parser(&block)
|
61
|
-
# @@cparser = lambda do
|
62
|
-
# yield
|
63
|
-
# end
|
64
|
-
# end
|
65
59
|
end
|
66
60
|
end # of Module Parsable
|
67
61
|
|
68
62
|
|
69
63
|
|
70
|
-
class SucceedParser
|
64
|
+
# class SucceedParser
|
65
|
+
class Succeed
|
71
66
|
include Parsable
|
72
67
|
attr_reader :remaining
|
73
68
|
def initialize(value, remaining = nil)
|
@@ -78,7 +73,8 @@ module Yaparc
|
|
78
73
|
end
|
79
74
|
end
|
80
75
|
|
81
|
-
class FailParser
|
76
|
+
# class FailParser
|
77
|
+
class Fail
|
82
78
|
include Parsable
|
83
79
|
def initialize
|
84
80
|
@parser = lambda do |input|
|
@@ -89,7 +85,8 @@ module Yaparc
|
|
89
85
|
|
90
86
|
|
91
87
|
|
92
|
-
class ItemParser
|
88
|
+
# class ItemParser
|
89
|
+
class Item
|
93
90
|
include Parsable
|
94
91
|
def initialize
|
95
92
|
@parser = lambda do |input|
|
@@ -102,13 +99,15 @@ module Yaparc
|
|
102
99
|
end
|
103
100
|
end
|
104
101
|
|
105
|
-
class ZeroOneParser
|
102
|
+
# class ZeroOneParser
|
103
|
+
class ZeroOne
|
106
104
|
include Parsable
|
107
105
|
def initialize(parser, identity = [])
|
108
106
|
@parser = lambda do |input|
|
109
107
|
case result = parser.parse(input)
|
110
108
|
when Result::Fail
|
111
|
-
|
109
|
+
Result::OK.new(:value => identity, :input => input)
|
110
|
+
# Succeed.new(identity)
|
112
111
|
when Result::Error
|
113
112
|
Result::Error.new(:value => result.value, :input => result.input)
|
114
113
|
when Result::OK
|
@@ -117,8 +116,8 @@ module Yaparc
|
|
117
116
|
raise
|
118
117
|
end
|
119
118
|
|
120
|
-
# AltParser.new(parser,
|
121
|
-
# case result = AltParser.new(parser,
|
119
|
+
# AltParser.new(parser, Succeed.new(identity))
|
120
|
+
# case result = AltParser.new(parser, Succeed.new(identity)).parse(input)
|
122
121
|
# if input.nil? or input.empty?
|
123
122
|
# Result::Fail.new(:input => input)
|
124
123
|
# else
|
@@ -129,30 +128,31 @@ module Yaparc
|
|
129
128
|
end
|
130
129
|
end
|
131
130
|
|
132
|
-
class SatisfyParser
|
131
|
+
# class SatisfyParser
|
132
|
+
class Satisfy
|
133
133
|
include Parsable
|
134
134
|
def initialize(predicate)
|
135
135
|
raise unless predicate.instance_of?(Proc)
|
136
136
|
|
137
137
|
@parser = lambda do |input|
|
138
|
-
case result =
|
138
|
+
case result = Item.new.parse(input)
|
139
139
|
when Result::OK
|
140
140
|
parser = if predicate.call(result.value)
|
141
|
-
|
141
|
+
Succeed.new(result.value, result.input)
|
142
142
|
else
|
143
|
-
|
143
|
+
Fail.new
|
144
144
|
end
|
145
145
|
else # Result::Fail or Result::Error
|
146
|
-
|
146
|
+
Fail.new
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
151
|
def parse(input)
|
152
152
|
case parser = @parser.call(input)
|
153
|
-
when
|
153
|
+
when Succeed
|
154
154
|
parser.parse(parser.remaining)
|
155
|
-
when
|
155
|
+
when Fail
|
156
156
|
parser.parse(input)
|
157
157
|
else
|
158
158
|
raise
|
@@ -171,9 +171,9 @@ module Yaparc
|
|
171
171
|
when Result::Fail
|
172
172
|
Result::Error.new(:value => result.value, :input => result.input)
|
173
173
|
when Result::OK
|
174
|
-
|
174
|
+
Succeed.new(result.value)
|
175
175
|
else
|
176
|
-
|
176
|
+
Succeed.new(result.value)
|
177
177
|
# Result::OK.new(:value => result.value,:input => result.input)
|
178
178
|
end
|
179
179
|
end
|
@@ -181,7 +181,8 @@ module Yaparc
|
|
181
181
|
end # of NoFail
|
182
182
|
|
183
183
|
|
184
|
-
class SeqParser
|
184
|
+
# class SeqParser
|
185
|
+
class Seq
|
185
186
|
include Parsable
|
186
187
|
def initialize(*parsers, &block)
|
187
188
|
@parser = lambda do |input|
|
@@ -191,6 +192,8 @@ module Yaparc
|
|
191
192
|
case result = parser.parse(subsequent.input)
|
192
193
|
when Result::Fail
|
193
194
|
break Result::Fail.new(:input => subsequent.input)
|
195
|
+
# when Result::Error
|
196
|
+
# break Result::Error.new(:input => subsequent.input)
|
194
197
|
else
|
195
198
|
args << result.value
|
196
199
|
result
|
@@ -212,10 +215,11 @@ module Yaparc
|
|
212
215
|
end
|
213
216
|
end
|
214
217
|
end # of initialize
|
215
|
-
end # of
|
218
|
+
end # of Seq
|
216
219
|
|
217
220
|
|
218
|
-
class AltParser
|
221
|
+
# class AltParser
|
222
|
+
class Alt
|
219
223
|
include Parsable
|
220
224
|
def initialize(*parsers)
|
221
225
|
@parser = lambda do |input|
|
@@ -239,48 +243,48 @@ module Yaparc
|
|
239
243
|
end # of initialize
|
240
244
|
end
|
241
245
|
|
242
|
-
|
243
|
-
|
244
|
-
class ApplyParser
|
246
|
+
# class ApplyParser
|
247
|
+
class Apply
|
245
248
|
include Parsable
|
246
249
|
def initialize(parser, &block)
|
247
250
|
@parser = lambda do |input|
|
248
251
|
case result = parser.parse(input)
|
249
252
|
when Result::OK
|
250
|
-
|
253
|
+
Succeed.new(yield(result.value)).parse(result.input)
|
251
254
|
else
|
252
|
-
|
255
|
+
Fail.new.parse(input)
|
253
256
|
end
|
254
257
|
end
|
255
258
|
end # of initialize
|
256
|
-
end # of
|
259
|
+
end # of Apply
|
257
260
|
|
258
261
|
|
259
|
-
class
|
262
|
+
class String
|
260
263
|
include Parsable
|
261
264
|
def initialize(string)
|
262
265
|
@parser = lambda do |input|
|
263
|
-
case result =
|
266
|
+
case result = Item.new.parse(string)
|
264
267
|
when Result::OK
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
268
|
+
Seq.new(
|
269
|
+
Char.new(result.value),
|
270
|
+
Yaparc::String.new(result.input),
|
271
|
+
Succeed.new(result.value + result.input)
|
272
|
+
) do |char_result, string_result, succeed_result|
|
270
273
|
succeed_result
|
271
274
|
end
|
272
275
|
else
|
273
|
-
|
276
|
+
Succeed.new(result) # Is it OK?
|
274
277
|
end
|
275
278
|
end
|
276
279
|
end
|
277
280
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
+
# def parse(input)
|
282
|
+
# @parser.call(input).parse(input)
|
283
|
+
# end
|
281
284
|
end
|
282
285
|
|
283
|
-
class RegexParser
|
286
|
+
# class RegexParser
|
287
|
+
class Regex
|
284
288
|
include Parsable
|
285
289
|
|
286
290
|
def initialize(regex, &block)
|
@@ -288,7 +292,7 @@ module Yaparc
|
|
288
292
|
@parser = lambda do |input|
|
289
293
|
if match = Regexp.new(regex).match(input)
|
290
294
|
if block_given?
|
291
|
-
|
295
|
+
Succeed.new(yield(*match.to_a[1..match.to_a.length])).parse(match.post_match)
|
292
296
|
else
|
293
297
|
Result::OK.new(:value => match[0], :input => match.post_match)
|
294
298
|
end
|
@@ -310,89 +314,93 @@ module Yaparc
|
|
310
314
|
end
|
311
315
|
end
|
312
316
|
end
|
313
|
-
# class RegexParser
|
314
|
-
# include Parsable
|
315
|
-
|
316
|
-
# def initialize(regex)
|
317
|
-
# @parser = lambda do |input|
|
318
|
-
# if match = Regexp.new(regex).match(input)
|
319
|
-
# Result::OK.new(:value => match[0], :input => match.post_match)
|
320
|
-
# else
|
321
|
-
# Result::Fail.new(:input => input)
|
322
|
-
# end
|
323
|
-
# end
|
324
|
-
# end
|
325
|
-
# end
|
326
317
|
|
327
318
|
# permits zero or more applications of parser.
|
328
|
-
class ManyParser
|
319
|
+
# class ManyParser
|
320
|
+
class Many
|
329
321
|
include Parsable
|
330
322
|
def initialize(parser, identity = [])
|
331
323
|
@parser = lambda do |input|
|
332
|
-
|
324
|
+
Alt.new(ManyOne.new(parser, identity), Succeed.new(identity))
|
333
325
|
end
|
334
326
|
end
|
335
|
-
|
336
|
-
# def parse(input)
|
337
|
-
# @parser.call(input).parse(input)
|
338
|
-
# end
|
339
327
|
end
|
340
328
|
|
341
329
|
# requires at least one successfull application of parser.
|
342
|
-
class
|
330
|
+
# class ManyOne
|
331
|
+
class ManyOne
|
343
332
|
include Parsable
|
344
333
|
def initialize(parser, identity = [])
|
345
334
|
@parser = lambda do |input|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
335
|
+
Seq.new(parser, Many.new(parser, identity)) do |head, tail|
|
336
|
+
case head
|
337
|
+
when ::String
|
338
|
+
if tail.instance_of?(::String)
|
339
|
+
head + tail
|
340
|
+
else
|
341
|
+
raise "Incompatible type: head => #{head}, tail => #{tail}"
|
342
|
+
end
|
343
|
+
when ::Array
|
344
|
+
if tail.instance_of?(Array)
|
345
|
+
head + tail
|
346
|
+
else
|
347
|
+
raise "Incompatible type: head => #{head}, tail => #{tail}"
|
348
|
+
end
|
349
|
+
when ::Hash
|
350
|
+
if tail.instance_of?(Hash)
|
351
|
+
head.merge(tail)
|
352
|
+
else
|
353
|
+
raise "Incompatible type: head => #{head}, tail => #{tail}"
|
354
|
+
end
|
355
|
+
when ::Integer
|
356
|
+
if tail.kind_of?(Integer)
|
357
|
+
head + tail
|
358
|
+
else
|
359
|
+
raise "Incompatible type: head => #{head}, tail => #{tail}"
|
360
|
+
end
|
361
|
+
else
|
362
|
+
raise "Incompatible type: head => #{head}"
|
363
|
+
end
|
364
|
+
#head + tail
|
351
365
|
end
|
352
366
|
end
|
353
367
|
end
|
354
|
-
|
355
|
-
def parse(input)
|
356
|
-
@parser.call(input).parse(input)
|
357
|
-
end
|
358
368
|
end
|
359
369
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
class SpaceParser
|
370
|
+
# class SpaceParser
|
371
|
+
class Space
|
364
372
|
include Parsable
|
365
373
|
def initialize
|
366
374
|
@parser = lambda do |input|
|
367
|
-
|
375
|
+
Seq.new(Many.new(Satisfy.new(IS_SPACE),""))
|
368
376
|
end
|
369
377
|
end
|
370
378
|
end
|
371
379
|
|
372
|
-
class
|
380
|
+
class WhiteSpace
|
373
381
|
include Parsable
|
374
382
|
def initialize
|
375
383
|
@parser = lambda do |input|
|
376
|
-
|
384
|
+
Seq.new(Many.new(Satisfy.new(IS_WHITESPACE),''))
|
377
385
|
end
|
378
386
|
end
|
379
387
|
end
|
380
388
|
|
381
|
-
class
|
389
|
+
class Tokenize
|
382
390
|
include Parsable
|
383
391
|
attr_accessor :prefix, :postfix
|
384
392
|
|
385
393
|
def initialize(parser, args = { }, &block)
|
386
394
|
@parser = lambda do |input|
|
387
|
-
@prefix = args[:prefix] ? args[:prefix] :
|
388
|
-
@postfix = args[:postfix] ? args[:postfix] :
|
395
|
+
@prefix = args[:prefix] ? args[:prefix] : WhiteSpace.new
|
396
|
+
@postfix = args[:postfix] ? args[:postfix] : WhiteSpace.new
|
389
397
|
if block_given?
|
390
398
|
yield self
|
391
|
-
|
399
|
+
Seq.new(@prefix, parser, @postfix) do |_, vs, _|
|
392
400
|
vs
|
393
401
|
end
|
394
402
|
else
|
395
|
-
|
403
|
+
Seq.new(@prefix, parser, @postfix) do |_, vs, _|
|
396
404
|
vs
|
397
405
|
end
|
398
406
|
end
|
@@ -400,23 +408,12 @@ module Yaparc
|
|
400
408
|
end
|
401
409
|
end
|
402
410
|
|
403
|
-
#
|
404
|
-
|
405
|
-
|
406
|
-
# def initialize(parser, &block)
|
407
|
-
# @prefix, @postfix = WhiteSpace.new,WhiteSpace.new
|
408
|
-
# yield self
|
409
|
-
# @parser = SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
|
410
|
-
# vs
|
411
|
-
# end
|
412
|
-
# end
|
413
|
-
# end
|
414
|
-
|
415
|
-
class LiteralParser
|
411
|
+
# class LiteralParser
|
412
|
+
class Literal
|
416
413
|
include Parsable
|
417
414
|
def initialize(literal)
|
418
415
|
@parser = lambda do |input|
|
419
|
-
|
416
|
+
Tokenize.new(Yaparc::String.new(literal))
|
420
417
|
end
|
421
418
|
end
|
422
419
|
end
|
@@ -425,23 +422,21 @@ module Yaparc
|
|
425
422
|
|
426
423
|
class Identifier
|
427
424
|
include Yaparc::Parsable
|
428
|
-
@@identifier_regex = ::Yaparc::
|
425
|
+
@@identifier_regex = ::Yaparc::Regex.new(/\A[a-zA-Z_]+[a-zA-Z0-9_]*/)
|
429
426
|
|
430
427
|
def initialize(*keywords)
|
431
428
|
if keywords == []
|
432
429
|
@parser = lambda do |input|
|
433
|
-
|
434
|
-
# Yaparc::Token.new(@@identifier_regex)
|
430
|
+
Tokenize.new(@@identifier_regex)
|
435
431
|
end
|
436
432
|
else
|
437
433
|
@parser = lambda do |input|
|
438
|
-
keyword_parsers = keywords.map {|keyword| Yaparc::
|
439
|
-
case result = Yaparc::
|
434
|
+
keyword_parsers = keywords.map {|keyword| Yaparc::String.new(keyword)}
|
435
|
+
case result = Yaparc::Alt.new(*keyword_parsers).parse(input)
|
440
436
|
when Yaparc::Result::OK
|
441
|
-
Yaparc::
|
437
|
+
Yaparc::Fail.new
|
442
438
|
else # Result::Fail or Result::Error
|
443
|
-
|
444
|
-
# Yaparc::Token.new(@@identifier_regex)
|
439
|
+
Tokenize.new(@@identifier_regex)
|
445
440
|
end
|
446
441
|
end
|
447
442
|
end
|
@@ -452,69 +447,48 @@ module Yaparc
|
|
452
447
|
end
|
453
448
|
end
|
454
449
|
|
455
|
-
#
|
456
|
-
|
457
|
-
|
458
|
-
# def parse(input)
|
459
|
-
# @parser.parse(input)
|
460
|
-
# end
|
461
|
-
# end
|
462
|
-
|
463
|
-
class CharParser
|
450
|
+
# class Char
|
451
|
+
class Char
|
464
452
|
include Parsable
|
465
453
|
|
466
454
|
def initialize(char)
|
467
455
|
equal_char = lambda {|i| i == char}
|
468
456
|
@parser = lambda do |input|
|
469
|
-
|
457
|
+
Satisfy.new(equal_char)
|
470
458
|
end
|
471
459
|
end
|
472
460
|
end
|
473
|
-
# class CharParser < ParserBase
|
474
|
-
|
475
|
-
# def initialize(char)
|
476
|
-
# equal_char = lambda {|i| i == char}
|
477
|
-
# @parser = SatisfyParser.new(equal_char)
|
478
|
-
# end
|
479
|
-
# end
|
480
|
-
|
481
|
-
# class ZeroOneParser < ParserBase
|
482
|
-
# def initialize(parser, identity = [])
|
483
|
-
# @parser = AltParser.new(parser, SucceedParser.new(identity)) # Is it OK?
|
484
|
-
# end
|
485
|
-
# end
|
486
461
|
|
487
462
|
class Ident
|
488
463
|
include Parsable
|
489
464
|
def initialize
|
490
465
|
@parser = lambda do |input|
|
491
|
-
|
492
|
-
|
493
|
-
|
466
|
+
Seq.new(
|
467
|
+
Satisfy.new(IS_LOWER),
|
468
|
+
Many.new(Satisfy.new(IS_ALPHANUM),"")
|
494
469
|
) do |head, tail|
|
495
470
|
head + tail
|
496
471
|
end
|
497
472
|
end
|
498
473
|
end
|
499
474
|
end
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
# end
|
475
|
+
|
476
|
+
class Digit
|
477
|
+
include Parsable
|
478
|
+
def initialize
|
479
|
+
@parser = lambda do |input|
|
480
|
+
Satisfy.new(IS_DIGIT)
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
510
484
|
|
511
485
|
class Nat
|
512
486
|
include Parsable
|
513
487
|
def initialize
|
514
488
|
@parser = lambda do |input|
|
515
|
-
|
489
|
+
Seq.new(ManyOne.new(Digit.new,'')) do |vs|
|
516
490
|
if vs == ""
|
517
|
-
vs
|
491
|
+
0 # vs
|
518
492
|
else
|
519
493
|
vs.to_i
|
520
494
|
end
|
@@ -523,77 +497,25 @@ module Yaparc
|
|
523
497
|
end
|
524
498
|
end
|
525
499
|
|
526
|
-
# class Nat < ParserBase
|
527
|
-
# def initialize
|
528
|
-
# @parser = SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT),"")) do |vs|
|
529
|
-
# if vs == ""
|
530
|
-
# vs
|
531
|
-
# else
|
532
|
-
# vs.to_i
|
533
|
-
# end
|
534
|
-
# end
|
535
|
-
# end
|
536
|
-
# end
|
537
|
-
|
538
|
-
# class Space < ParserBase
|
539
|
-
# def initialize
|
540
|
-
# @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_SPACE),"")) do |vs|
|
541
|
-
# SucceedParser.new([])
|
542
|
-
# end
|
543
|
-
# end
|
544
|
-
# end
|
545
|
-
|
546
|
-
# class WhiteSpace < ParserBase
|
547
|
-
# def initialize
|
548
|
-
# @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_WHITESPACE),"")) do |vs|
|
549
|
-
# SucceedParser.new([])
|
550
|
-
# end
|
551
|
-
# end
|
552
|
-
# end
|
553
|
-
|
554
|
-
# class Token < ParserBase
|
555
|
-
# attr_accessor :prefix, :postfix
|
556
|
-
|
557
|
-
# def initialize(parser, prefix = WhiteSpace.new, postfix = WhiteSpace.new)
|
558
|
-
# @prefix, @postfix = prefix, postfix
|
559
|
-
# @parser = SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
|
560
|
-
# vs
|
561
|
-
# end
|
562
|
-
# end
|
563
|
-
# end
|
564
500
|
|
565
501
|
class Natural
|
566
502
|
include Parsable
|
567
503
|
def initialize(args = {})
|
568
504
|
@parser = lambda do |input|
|
569
|
-
|
505
|
+
Tokenize.new(Nat.new, args)
|
570
506
|
end
|
571
507
|
end
|
572
508
|
end
|
573
|
-
# class Natural < ParserBase
|
574
|
-
|
575
|
-
# def initialize
|
576
|
-
# @parser = Token.new(Nat.new)
|
577
|
-
# end
|
578
|
-
# end
|
579
|
-
|
580
509
|
|
581
510
|
class Symbol
|
582
511
|
include Parsable
|
583
512
|
def initialize(literal, args = {})
|
584
513
|
@parser = lambda do |input|
|
585
|
-
|
514
|
+
Literal.new(literal)
|
586
515
|
end
|
587
516
|
end
|
588
517
|
end
|
589
518
|
|
590
|
-
# class Symbol < ParserBase
|
591
|
-
|
592
|
-
# def initialize(literal)
|
593
|
-
# @parser = Token.new(StringParser.new(literal))
|
594
|
-
# end
|
595
|
-
# end
|
596
|
-
|
597
519
|
class AbstractParser
|
598
520
|
include Parsable
|
599
521
|
|