yaparc 0.0.3 → 0.0.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.
data/README CHANGED
@@ -15,7 +15,6 @@ This is a yet another simple combinator parser library in ruby.
15
15
  require 'rubygems'
16
16
  require_gem 'yaparc'
17
17
 
18
-
19
18
 
20
19
  Please look at unit test files.
21
20
 
data/lib/yaparc.rb CHANGED
@@ -1,10 +1,16 @@
1
+ def assert_at(file,line, message = "")
2
+ unless yield
3
+ raise "Assertion failed !: #{file}, #{line}: #{message}"
4
+ end
5
+ end
6
+
1
7
 
2
8
  module Yaparc
3
9
  module Parsable
4
10
  include Yaparc
5
-
11
+
6
12
  attr_accessor :tree
7
-
13
+
8
14
  IS_LOWER = lambda {|c| c >= 'a' and c <= 'z'}
9
15
  IS_ALPHANUM = lambda {|c| (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9')}
10
16
  IS_DIGIT = lambda {|i| i > '0' and i < '9'}
@@ -28,24 +34,34 @@ module Yaparc
28
34
  tree = parse(input)
29
35
  end
30
36
 
31
- def define_parser
32
- raise
33
- end
34
37
 
35
38
  module ClassMethods
36
39
  def included(mod)
37
40
  end
38
41
 
39
- # def self.initialize
40
- # @parser = @@parser
41
- # end
42
-
43
42
  def define_parser(&block)
44
43
  @@parser = lambda do |input|
45
- parser = yield
44
+ parser = yield
46
45
  parser.parse(input)
47
46
  end
48
47
  end
48
+
49
+ def parser
50
+ @@parser
51
+ end
52
+
53
+ def parse(input, &block)
54
+ tree = @@parser.call(input)
55
+ if block_given?
56
+ @@tree = yield tree
57
+ else
58
+ @@tree = tree
59
+ end
60
+ end
61
+ # def self.initialize
62
+ # @parser = @@parser
63
+ # end
64
+
49
65
  end
50
66
  end # of Parsable
51
67
 
@@ -79,6 +95,8 @@ module Yaparc
79
95
  class SatisfyParser
80
96
  include Parsable
81
97
  def initialize(predicate)
98
+ assert_at(__FILE__,__LINE__){predicate.instance_of?(Proc)}
99
+
82
100
  @parser = lambda do |input|
83
101
  item = ItemParser.new.parse(input)
84
102
  if item == []
@@ -179,20 +197,21 @@ module Yaparc
179
197
 
180
198
  class ManyParser
181
199
  include Parsable
182
- def initialize(predicate)
200
+ def initialize(parser)
183
201
  @parser = lambda do |input|
184
- AltParser.new(ManyOneParser.new(predicate), SucceedParser.new([])).parse(input)
202
+ AltParser.new(ManyOneParser.new(parser), SucceedParser.new([])).parse(input)
185
203
  end
186
204
  end
187
205
  end
188
206
 
189
207
  class ManyOneParser
190
208
  include Parsable
191
- def initialize(predicate)
209
+ def initialize(parser)
192
210
  @parser = lambda do |input|
193
211
  SeqParser.new(
194
- SatisfyParser.new(predicate),
195
- ManyParser.new(predicate)
212
+ # SatisfyParser.new(parser),
213
+ parser,
214
+ ManyParser.new(parser)
196
215
  ) do |v, vs|
197
216
  if vs == []
198
217
  v
@@ -220,7 +239,8 @@ module Yaparc
220
239
  @parser = lambda do |input|
221
240
  SeqParser.new(
222
241
  SatisfyParser.new(IS_LOWER),
223
- ManyParser.new(IS_ALPHANUM)
242
+ # ManyParser.new(IS_ALPHANUM)
243
+ ManyParser.new(SatisfyParser.new(IS_ALPHANUM))
224
244
  ) do |v, vs|
225
245
  if vs == []
226
246
  v
@@ -236,7 +256,8 @@ module Yaparc
236
256
  include Parsable
237
257
  def initialize
238
258
  @parser = lambda do |input|
239
- SeqParser.new(ManyOneParser.new(IS_DIGIT)) do |vs|
259
+ # SeqParser.new(ManyOneParser.new(IS_DIGIT)) do |vs|
260
+ SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT))) do |vs|
240
261
  if vs == []
241
262
  vs
242
263
  else
@@ -251,7 +272,8 @@ module Yaparc
251
272
  include Parsable
252
273
  def initialize
253
274
  @parser = lambda do |input|
254
- SeqParser.new(ManyParser.new(IS_SPACE)) do |vs|
275
+ # SeqParser.new(ManyParser.new(IS_SPACE)) do |vs|
276
+ SeqParser.new(ManyParser.new(SatisfyParser.new(IS_SPACE))) do |vs|
255
277
  []
256
278
  end.parse(input)
257
279
  end
data/tests/test_calc.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'lib/parser.rb'
1
+ require 'lib/yaparc.rb'
2
2
  require 'test/unit'
3
3
  require 'pp'
4
4
 
@@ -7,16 +7,16 @@ require 'pp'
7
7
  class Expr
8
8
  include Yaparc::Parsable
9
9
 
10
- # define_parser do
11
- # AltParser.new(
12
- # SeqParser.new(Term.new,
13
- # Symbol.new('+'),
14
- # Expr.new) do |term, _, expr|
15
- # ['+', term,expr]
16
- # end,
17
- # Term.new
18
- # )
19
- # end
10
+ define_parser do
11
+ AltParser.new(
12
+ SeqParser.new(Term.new,
13
+ Symbol.new('+'),
14
+ Expr.new) do |term, _, expr|
15
+ ['+', term,expr]
16
+ end,
17
+ Term.new
18
+ )
19
+ end
20
20
 
21
21
  def initialize
22
22
  @parser = lambda do |input|
@@ -119,6 +119,7 @@ class YaparcCalcTest < Test::Unit::TestCase
119
119
 
120
120
  def setup
121
121
  end
122
+
122
123
  def test_expr
123
124
  parser = Expr.new
124
125
  result = parser.parse("1 + 2 ")
@@ -126,4 +127,12 @@ class YaparcCalcTest < Test::Unit::TestCase
126
127
  assert_equal 3, parser.eval("1 + 2 ")
127
128
  assert_equal 9, parser.eval("(1 + 2) * 3 ")
128
129
  end
130
+
131
+ def test_expr_define_parser
132
+ parser = Expr.new
133
+ result = Expr.parse("1 + 2 ")
134
+ assert_equal [[["+", 1, 2], ""]], result
135
+ assert_equal 3, parser.eval("1 + 2 ")
136
+ assert_equal 9, parser.eval("(1 + 2) * 3 ")
137
+ end
129
138
  end
data/tests/test_parser.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'lib/parser.rb'
1
+ require 'lib/yaparc.rb'
2
2
  require 'test/unit'
3
3
  require 'pp'
4
4
 
@@ -132,8 +132,8 @@ class YaparcTest < Test::Unit::TestCase
132
132
  end
133
133
 
134
134
  def test_many_parse
135
- is_digit = lambda {|i| i > '0' and i < '9'}
136
-
135
+ # is_digit = lambda {|i| i > '0' and i < '9'}
136
+ is_digit = SatisfyParser.new(lambda {|i| i > '0' and i < '9'})
137
137
  parser = ManyParser.new(is_digit)
138
138
  result = parser.parse("123abc")
139
139
  assert_equal [["123", "abc"]], result
@@ -163,6 +163,14 @@ class YaparcTest < Test::Unit::TestCase
163
163
  assert_equal [[123, " abc"]], result
164
164
  end
165
165
 
166
+ def test_nat_ident
167
+ parser = SeqParser.new(Nat.new, Ident.new) do |nat, ident|
168
+ [nat,ident]
169
+ end
170
+ result = parser.parse("123abc")
171
+ assert_equal [[[123, "abc"], ""]], result
172
+ end
173
+
166
174
  def test_space
167
175
  parser = Space.new
168
176
  result = parser.parse(" abc")
@@ -187,5 +195,11 @@ class YaparcTest < Test::Unit::TestCase
187
195
  assert_equal [["%", ""]], result
188
196
  end
189
197
 
198
+ def test_define_parser
199
+ parser = Symbol.new('%')
200
+ result = parser.parse(" % ")
201
+ assert_equal [["%", ""]], result
202
+ end
203
+
190
204
  end
191
205
 
metadata CHANGED
@@ -3,8 +3,8 @@ 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.3
7
- date: 2007-12-14 00:00:00 +09:00
6
+ version: 0.0.4
7
+ date: 2008-01-05 00:00:00 +09:00
8
8
  summary: Yet Another Combinator Parser Library
9
9
  require_paths:
10
10
  - lib
@@ -34,7 +34,6 @@ files:
34
34
  - tests/test_calc.rb
35
35
  - lib/parser_cps.rb
36
36
  - lib/yaparc.rb
37
- - lib/parser.rb
38
37
  - README
39
38
  test_files:
40
39
  - tests/test_parser_cps.rb
data/lib/parser.rb DELETED
@@ -1,299 +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
-
18
- def parse(input, &block)
19
- tree = @parser.call(input)
20
- if block_given?
21
- @tree = yield tree
22
- else
23
- @tree = tree
24
- end
25
- end
26
-
27
- def eval
28
- tree = parse(input)
29
- end
30
-
31
- def define_parser
32
- raise
33
- end
34
-
35
- module ClassMethods
36
- def included(mod)
37
- end
38
-
39
- # def self.initialize
40
- # @parser = @@parser
41
- # end
42
-
43
- def define_parser(&block)
44
- @@parser = lambda do |input|
45
- parser = yield
46
- parser.parse(input)
47
- end
48
- end
49
- end
50
- end # of Parsable
51
-
52
- class SucceedParser
53
- include Parsable
54
- def initialize(value)
55
- @parser = lambda {|input| [[value, input]]}
56
- end
57
- end
58
-
59
- class FailParser
60
- include Parsable
61
- def initialize
62
- @parser = lambda {|input| []}
63
- end
64
- end
65
-
66
- class ItemParser
67
- include Parsable
68
- def initialize
69
- @parser = lambda do |input|
70
- if input.nil? or input.empty?
71
- []
72
- else
73
- [[input[0..0],input[1..input.length]]]
74
- end
75
- end
76
- end
77
- end
78
-
79
- class SatisfyParser
80
- include Parsable
81
- def initialize(predicate)
82
- @parser = lambda do |input|
83
- item = ItemParser.new.parse(input)
84
- if item == []
85
- FailParser.new.parse(input)
86
- else
87
- if predicate.call(item[0][0])
88
- SucceedParser.new(item[0][0]).parse(item[0][1])
89
- else
90
- FailParser.new.parse(input)
91
- end
92
- end
93
- end
94
- end
95
- end
96
-
97
- class SeqParser
98
- include Parsable
99
- def initialize(*parsers, &block)
100
- @parser = lambda do |input|
101
- args = []
102
- remains = parsers.inject(input) do |accumulator, parser|
103
- result = parser.parse(accumulator)
104
- unless result == []
105
- args << result[0][0]
106
- result[0][1]
107
- else
108
- break []
109
- end
110
- end
111
- unless remains == []
112
- retval = yield(*args)
113
- [[retval, remains]]
114
- else
115
- []
116
- end
117
- end
118
- end # of initialize
119
- end # of SeqParser
120
-
121
- class AltParser
122
- include Parsable
123
- def initialize(*parsers)
124
- @parser = lambda do |input|
125
- parsers.inject([]) do |accum, parser|
126
- result = parser.parse(input)
127
- if result == []
128
- result
129
- else
130
- break [result[0]]
131
- end
132
- end
133
- end
134
- end # of initialize
135
- end
136
-
137
- class CharParser
138
- include Parsable
139
- def initialize(char)
140
- equal_char = lambda {|i| i == char}
141
- @parser = lambda do |input|
142
- SatisfyParser.new(equal_char).parse(input)
143
- end
144
- end
145
- end
146
-
147
- class StringParser
148
- include Parsable
149
- def initialize(string)
150
- @parser = lambda do |input|
151
- result = ItemParser.new.parse(string)
152
- if result == []
153
- SucceedParser.new(result).parse(input) # FailParser.new.parse(input)
154
- else
155
- SeqParser.new(
156
- CharParser.new(result[0][0]),
157
- StringParser.new(result[0][1]),
158
- SucceedParser.new(result[0][0] + result[0][1])
159
- ) do |char_result, string_result, succeed_result|
160
- succeed_result
161
- end.parse(input)
162
- end
163
- end
164
- end
165
- end
166
-
167
- class RegexParser
168
- include Parsable
169
- def initialize(regex)
170
- @parser = lambda do |input|
171
- if match = Regexp.new(regex).match(input)
172
- [[match[0],match.post_match]]
173
- else
174
- []
175
- end
176
- end
177
- end
178
- end
179
-
180
- class ManyParser
181
- include Parsable
182
- def initialize(predicate)
183
- @parser = lambda do |input|
184
- AltParser.new(ManyOneParser.new(predicate), SucceedParser.new([])).parse(input)
185
- end
186
- end
187
- end
188
-
189
- class ManyOneParser
190
- include Parsable
191
- def initialize(predicate)
192
- @parser = lambda do |input|
193
- SeqParser.new(
194
- SatisfyParser.new(predicate),
195
- ManyParser.new(predicate)
196
- ) do |v, vs|
197
- if vs == []
198
- v
199
- else
200
- v + vs.to_s
201
- end
202
- end.parse(input)
203
- end
204
- end
205
- end
206
-
207
- class ZeroOneParser
208
- include Parsable
209
- def initialize(parser)
210
- @parser = lambda do |input|
211
- AltParser.new(parser,
212
- SucceedParser.new([])).parse(input)
213
- end
214
- end
215
- end
216
-
217
- class Ident
218
- include Parsable
219
- def initialize
220
- @parser = lambda do |input|
221
- SeqParser.new(
222
- SatisfyParser.new(IS_LOWER),
223
- ManyParser.new(IS_ALPHANUM)
224
- ) do |v, vs|
225
- if vs == []
226
- v
227
- else
228
- v + vs.to_s
229
- end
230
- end.parse(input)
231
- end
232
- end
233
- end
234
-
235
- class Nat
236
- include Parsable
237
- def initialize
238
- @parser = lambda do |input|
239
- SeqParser.new(ManyOneParser.new(IS_DIGIT)) do |vs|
240
- if vs == []
241
- vs
242
- else
243
- vs.to_i
244
- end
245
- end.parse(input)
246
- end
247
- end
248
- end
249
-
250
- class Space
251
- include Parsable
252
- def initialize
253
- @parser = lambda do |input|
254
- SeqParser.new(ManyParser.new(IS_SPACE)) do |vs|
255
- []
256
- end.parse(input)
257
- end
258
- end
259
- end
260
-
261
- class Token
262
- include Parsable
263
- def initialize(parser)
264
- @parser = lambda do |input|
265
- SeqParser.new(Space.new, parser, Space.new) do |_, vs, _|
266
- vs
267
- end.parse(input)
268
- end
269
- end
270
- end
271
-
272
- class Identifier
273
- include Parsable
274
- def initialize
275
- @parser = lambda do |input|
276
- Token.new(Ident.new).parse(input)
277
- end
278
- end
279
- end
280
-
281
- class Natural
282
- include Parsable
283
- def initialize
284
- @parser = lambda do |input|
285
- Token.new(Nat.new).parse(input)
286
- end
287
- end
288
- end
289
-
290
- class Symbol
291
- include Parsable
292
- def initialize(literal)
293
- @parser = lambda do |input|
294
- Token.new(StringParser.new(literal)).parse(input)
295
- end
296
- end
297
- end
298
-
299
- end