yaparc 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -19,4 +19,12 @@ This is a yet another simple combinator parser library in ruby.
19
19
  Please look at unit test files.
20
20
 
21
21
 
22
+ == Basic Parsers
23
+
24
+ == Combination Parsers
25
+
26
+ === Sequence Parser
27
+ === Alternate Parser
28
+
29
+
22
30
 
data/lib/yaparc.rb CHANGED
@@ -106,19 +106,16 @@ module Yaparc
106
106
  FailParser.new
107
107
  else
108
108
  parser = if predicate.call(item[0][0])
109
- # input = item[0][1]
110
109
  SucceedParser.new(item[0][0], item[0][1])
111
110
  else
112
111
  FailParser.new
113
112
  end
114
- # parser.parse(input)
115
113
  end
116
114
  end
117
115
  end
118
116
 
119
117
  def parse(input)
120
- parser = @parser.call(input)
121
- case parser
118
+ case parser = @parser.call(input)
122
119
  when SucceedParser
123
120
  parser.parse(parser.remaining)
124
121
  when FailParser
@@ -138,18 +135,22 @@ module Yaparc
138
135
  args = []
139
136
  remains = parsers.inject(input) do |accumulator, parser|
140
137
  result = parser.parse(accumulator)
141
- unless result == []
138
+ if result == []
139
+ break []
140
+ else
142
141
  args << result[0][0]
143
142
  result[0][1]
144
- else
145
- break []
146
143
  end
147
144
  end
148
- unless remains == []
149
- retval = yield(*args)
150
- [[retval, remains]]
151
- else
145
+ if remains == []
152
146
  []
147
+ else
148
+ retval = if block_given?
149
+ yield(*args)
150
+ else
151
+ args.last
152
+ end
153
+ [[retval, remains]]
153
154
  end
154
155
  end
155
156
  end # of initialize
@@ -173,36 +174,6 @@ module Yaparc
173
174
  end
174
175
 
175
176
 
176
- class ParserBase
177
- include Parsable
178
-
179
- def parse(input)
180
- @parser.parse(input)
181
- end
182
- end
183
-
184
- class AbstractParser
185
- include Parsable
186
-
187
- def parse(input, &block)
188
- tree = @parser.call.parse(input)
189
- if block_given?
190
- @tree = yield tree
191
- else
192
- @tree = tree
193
- end
194
-
195
- end
196
- end
197
-
198
- class CharParser < ParserBase
199
-
200
- def initialize(char)
201
- equal_char = lambda {|i| i == char}
202
- @parser = SatisfyParser.new(equal_char)
203
- end
204
- end
205
-
206
177
 
207
178
  class StringParser
208
179
  include Parsable
@@ -281,8 +252,24 @@ module Yaparc
281
252
  end
282
253
 
283
254
 
284
- class ZeroOneParser < ParserBase
255
+ class ParserBase
256
+ include Parsable
257
+
258
+ def parse(input)
259
+ @parser.parse(input)
260
+ end
261
+ end
285
262
 
263
+ class CharParser < ParserBase
264
+
265
+ def initialize(char)
266
+ equal_char = lambda {|i| i == char}
267
+ @parser = SatisfyParser.new(equal_char)
268
+ end
269
+ end
270
+
271
+
272
+ class ZeroOneParser < ParserBase
286
273
  def initialize(parser)
287
274
  @parser = AltParser.new(parser, SucceedParser.new([]))
288
275
  end
@@ -290,7 +277,6 @@ module Yaparc
290
277
 
291
278
 
292
279
  class Ident < ParserBase
293
-
294
280
  def initialize
295
281
  @parser = SeqParser.new(
296
282
  SatisfyParser.new(IS_LOWER),
@@ -328,7 +314,6 @@ module Yaparc
328
314
  end
329
315
  end
330
316
 
331
-
332
317
  class Token < ParserBase
333
318
 
334
319
  def initialize(parser)
@@ -338,7 +323,6 @@ module Yaparc
338
323
  end
339
324
  end
340
325
 
341
-
342
326
  class Identifier < ParserBase
343
327
 
344
328
  def initialize
@@ -346,7 +330,6 @@ module Yaparc
346
330
  end
347
331
  end
348
332
 
349
-
350
333
  class Natural < ParserBase
351
334
 
352
335
  def initialize
@@ -354,7 +337,6 @@ module Yaparc
354
337
  end
355
338
  end
356
339
 
357
-
358
340
  class Symbol < ParserBase
359
341
 
360
342
  def initialize(literal)
@@ -362,4 +344,18 @@ module Yaparc
362
344
  end
363
345
  end
364
346
 
347
+ class AbstractParser
348
+ include Parsable
349
+
350
+ def parse(input, &block)
351
+ tree = @parser.call.parse(input)
352
+ if block_given?
353
+ @tree = yield tree
354
+ else
355
+ @tree = tree
356
+ end
357
+
358
+ end
359
+ end
360
+
365
361
  end # of Yaparc
data/tests/test_parser.rb CHANGED
@@ -87,6 +87,12 @@ class YaparcTest < Test::Unit::TestCase
87
87
  assert_equal [[["B"], "DEF"]], result
88
88
  end
89
89
 
90
+ def test_seq_parse_without_block
91
+ parser = SeqParser.new(ItemParser.new, ItemParser.new)
92
+ result = parser.parse("abcdef")
93
+ assert_equal [["b", "cdef"]], result
94
+ end
95
+
90
96
  def test_alt_parse
91
97
  parser = AltParser.new(ItemParser.new, SucceedParser.new('d'))
92
98
  result = parser.parse("abc")
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.3
3
3
  specification_version: 1
4
4
  name: yaparc
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.6
6
+ version: 0.0.7
7
7
  date: 2008-01-07 00:00:00 +09:00
8
8
  summary: Yet Another Combinator Parser Library
9
9
  require_paths:
@@ -29,14 +29,11 @@ post_install_message:
29
29
  authors:
30
30
  - Akimichi Tatsukawa
31
31
  files:
32
- - tests/test_parser_cps.rb
33
32
  - tests/test_parser.rb
34
33
  - tests/test_calc.rb
35
- - lib/parser_cps.rb
36
34
  - lib/yaparc.rb
37
35
  - README
38
36
  test_files:
39
- - tests/test_parser_cps.rb
40
37
  - tests/test_parser.rb
41
38
  - tests/test_calc.rb
42
39
  rdoc_options: []
data/lib/parser_cps.rb DELETED
@@ -1,319 +0,0 @@
1
-
2
- module Yaparc
3
- module Parsable
4
- include Yaparc
5
-
6
- attr_accessor :tree
7
-
8
- IS_LOWER = lambda {|c| c >= 'a' and c <= 'z'}
9
- IS_ALPHANUM = lambda {|c| (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9')}
10
- IS_DIGIT = lambda {|i| i > '0' and i < '9'}
11
- IS_SPACE = lambda {|i| i == ' '}
12
-
13
- # def self.included(mod)
14
- # mod.extend ClassMethods
15
- # end
16
-
17
- def parse(input, cont, &block)
18
- tree = @parser.call(input, cont)
19
- if block_given?
20
- @tree = yield tree
21
- else
22
- @tree = tree
23
- end
24
- cont.apply(input)
25
- end
26
- end # of Parsable
27
-
28
- module Continuation
29
- class Base
30
- def apply(input)
31
- @proc.call(input)
32
- end
33
- # def apply(arg, input = '')
34
- # @proc.call(input,val)
35
- # end
36
- end
37
-
38
- class StopCont < Base
39
- def initialize
40
- # @proc = lambda do |input|
41
- # lambda{|input, val|
42
- # [[val,input]]
43
- # }
44
- # end
45
- @proc = lambda do |val, input|
46
- [[val,input]]
47
- end
48
- end
49
- end
50
-
51
-
52
-
53
- class ItemHeadCont < Base
54
- def initialize(input, cont)
55
- @proc = lambda do |val, input|
56
- [[val,input]]
57
- end
58
- end
59
- end
60
-
61
- class ItemTailCont < Base
62
- def initialize(cont)
63
- @proc = lambda do |val, input|
64
- [[val,input]]
65
- end
66
- end
67
- end
68
- end # of Continuation
69
-
70
- module Parser
71
- class SucceedParser
72
- include Parsable
73
- def initialize(val)
74
- @parser = lambda do |input, cont|
75
- cont.apply(val)
76
- end
77
- end
78
- end
79
-
80
- class FailParser
81
- include Parsable
82
- def initialize
83
- @parser = lambda do |input|
84
- []
85
- end
86
- end
87
- end
88
-
89
- class ItemParser
90
- include Parsable
91
- def initialize(cont)
92
- @parser = lambda do |input|
93
- if input.nil? or input.empty?
94
- FailParser.new(StopCont.new)
95
- else
96
- # head = input[0..0]
97
- # tail = input[1..input.length]
98
- ItemHeadCont.new(input,ItemTailCont.new(cont)).apply(input)
99
- end
100
- end
101
- end
102
- end
103
-
104
- class SatisfyParser
105
- include Parsable
106
- def initialize(predicate)
107
- @parser = lambda do |input|
108
- item = ItemParser.new.parse(input)
109
- if item == []
110
- FailParser.new.parse(input)
111
- else
112
- if predicate.call(item[0][0])
113
- SucceedParser.new(item[0][0]).parse(item[0][1])
114
- else
115
- FailParser.new.parse(input)
116
- end
117
- end
118
- end
119
- end
120
- end
121
-
122
- class SeqParser
123
- include Parsable
124
- def initialize(first, second, &block)
125
- @parser = lambda do |input, cont|
126
- SeqCont.new(first, second, cont).apply(input)
127
- end
128
- end # of initialize
129
-
130
- class SeqCont < Continuation::Base
131
- def initialize(first, second, cont)
132
- @proc = lambda do |input|
133
- first.parse(input, second.parse(input, cont))
134
- end
135
- end
136
- end
137
- end # of SeqParser
138
-
139
-
140
-
141
- class AltParser
142
- include Parsable
143
- def initialize(left, right)
144
- @parser = lambda do |input, cont|
145
- AltCont.new(left, right, cont).apply(input)
146
- end
147
- end
148
- class AltCont < Continuation::Base
149
- def initialize(left, right, cont)
150
- @proc = lambda do |input|
151
- left.parse(input, cont) or right.parse(input, cont)
152
- end
153
- end
154
- end
155
- end # of AltParser
156
-
157
- class CharParser
158
- include Parsable
159
- def initialize(char)
160
- equal_char = lambda {|i| i == char}
161
- @parser = lambda do |input|
162
- SatisfyParser.new(equal_char).parse(input)
163
- end
164
- end
165
- end
166
-
167
- class StringParser
168
- include Parsable
169
- def initialize(string)
170
- @parser = lambda do |input|
171
- result = ItemParser.new.parse(string)
172
- if result == []
173
- SucceedParser.new(result).parse(input) # FailParser.new.parse(input)
174
- else
175
- SeqParser.new(
176
- CharParser.new(result[0][0]),
177
- StringParser.new(result[0][1]),
178
- SucceedParser.new(result[0][0] + result[0][1])
179
- ) do |char_result, string_result, succeed_result|
180
- succeed_result
181
- end.parse(input)
182
- end
183
- end
184
- end
185
- end
186
-
187
- class RegexParser
188
- include Parsable
189
- def initialize(regex)
190
- @parser = lambda do |input|
191
- if match = Regexp.new(regex).match(input)
192
- [[match[0],match.post_match]]
193
- else
194
- []
195
- end
196
- end
197
- end
198
- end
199
-
200
- class ManyParser
201
- include Parsable
202
- def initialize(predicate)
203
- @parser = lambda do |input|
204
- AltParser.new(ManyOneParser.new(predicate), SucceedParser.new([])).parse(input)
205
- end
206
- end
207
- end
208
-
209
- class ManyOneParser
210
- include Parsable
211
- def initialize(predicate)
212
- @parser = lambda do |input|
213
- SeqParser.new(
214
- SatisfyParser.new(predicate),
215
- ManyParser.new(predicate)
216
- ) do |v, vs|
217
- if vs == []
218
- v
219
- else
220
- v + vs.to_s
221
- end
222
- end.parse(input)
223
- end
224
- end
225
- end
226
-
227
- class ZeroOneParser
228
- include Parsable
229
- def initialize(parser)
230
- @parser = lambda do |input|
231
- AltParser.new(parser,
232
- SucceedParser.new([])).parse(input)
233
- end
234
- end
235
- end
236
-
237
- class Ident
238
- include Parsable
239
- def initialize
240
- @parser = lambda do |input|
241
- SeqParser.new(
242
- SatisfyParser.new(IS_LOWER),
243
- ManyParser.new(IS_ALPHANUM)
244
- ) do |v, vs|
245
- if vs == []
246
- v
247
- else
248
- v + vs.to_s
249
- end
250
- end.parse(input)
251
- end
252
- end
253
- end
254
-
255
- class Nat
256
- include Parsable
257
- def initialize
258
- @parser = lambda do |input|
259
- SeqParser.new(ManyOneParser.new(IS_DIGIT)) do |vs|
260
- if vs == []
261
- vs
262
- else
263
- vs.to_i
264
- end
265
- end.parse(input)
266
- end
267
- end
268
- end
269
-
270
- class Space
271
- include Parsable
272
- def initialize
273
- @parser = lambda do |input|
274
- SeqParser.new(ManyParser.new(IS_SPACE)) do |vs|
275
- []
276
- end.parse(input)
277
- end
278
- end
279
- end
280
-
281
- class Token
282
- include Parsable
283
- def initialize(parser)
284
- @parser = lambda do |input|
285
- SeqParser.new(Space.new, parser, Space.new) do |_, vs, _|
286
- vs
287
- end.parse(input)
288
- end
289
- end
290
- end
291
-
292
- class Identifier
293
- include Parsable
294
- def initialize
295
- @parser = lambda do |input|
296
- Token.new(Ident.new).parse(input)
297
- end
298
- end
299
- end
300
-
301
- class Natural
302
- include Parsable
303
- def initialize
304
- @parser = lambda do |input|
305
- Token.new(Nat.new).parse(input)
306
- end
307
- end
308
- end
309
-
310
- class Symbol
311
- include Parsable
312
- def initialize(literal)
313
- @parser = lambda do |input|
314
- Token.new(StringParser.new(literal)).parse(input)
315
- end
316
- end
317
- end
318
- end # of Parser
319
- end # Yaparc
@@ -1,38 +0,0 @@
1
- require 'lib/parser_cps.rb'
2
- require 'test/unit'
3
- require 'pp'
4
-
5
- class YaparcTest < Test::Unit::TestCase
6
- include ::Yaparc
7
-
8
-
9
- def setup
10
- @stop = Continuation::StopCont.new
11
- end
12
-
13
-
14
- def test_succeed_parse
15
- parser = ::Yaparc::Parser::SucceedParser.new(1)
16
- assert_equal [[1, "abs"]], parser.parse("abs", @stop)
17
- # assert_equal [[1, "abs"]], parser.tree
18
- # result = parser.parse("abs") do |result|
19
- # result[0][0]
20
- # end
21
- # assert_equal 1, result
22
- end
23
-
24
- # def test_fail_parse
25
- # parser = ::Yaparc::Parser::FailParser.new(@stop)
26
- # result = parser.parse("abc")
27
- # assert_equal [], result
28
- # end
29
-
30
- # def test_item_parse
31
- # parser = ::Yaparc::Parser::ItemParser.new(@stop)
32
- # result = parser.parse("")
33
- # assert_equal [], result
34
- # result = parser.parse("abc")
35
- # assert_equal [["a", "bc"]], result
36
- # end
37
- end
38
-