yaparc 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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