rparsec-ruby19 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ require 'import'
2
+ import :parsers, :functors, :expressions
3
+ require 'parser_test'
4
+
5
+ class SExpressionTestCase < ParserTestCase
6
+ def delim
7
+ whitespace.many_
8
+ end
9
+ def ignore parser
10
+ parser << delim
11
+ end
12
+ def lparen
13
+ ignore(char('('))
14
+ end
15
+ def rparen
16
+ ignore(char(')'))
17
+ end
18
+ def parser
19
+ expr = nil
20
+ lazy_expr = lazy{expr}
21
+ term = number.map(&To_f) | lparen >> lazy_expr << rparen
22
+ binop = char('+') >> Plus | char('-') >> Minus | char('*') >> Mul | char('/') >> Div
23
+ binop = ignore binop
24
+ term = ignore term
25
+ binary = sequence(binop, lazy_expr, lazy_expr) do |op, e1, e2|
26
+ op.call(e1, e2)
27
+ end
28
+ expr = delim >> (term | binary)
29
+ end
30
+ def test1
31
+ assertParser('- (+ 1 * 2 2.0) (1)', 4, parser)
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ require 'benchmark'
2
+ require 'strscan'
3
+
4
+ puts __FILE__
5
+ str = ''
6
+ N = 10
7
+ N.times{str << 'abc'}
8
+
9
+ def scanner
10
+ StringScanner.new(str)
11
+ end
12
+
13
+ ptn1 = /bc/
14
+ ptn2 = /^bc/
15
+
16
+ Benchmark.bm do |x|
17
+ x.report("check with anchor") {N.times{StringScanner.new(str).scan(ptn2)}}
18
+ x.report("check without anchor") {N.times{StringScanner.new(str).scan(ptn1)}}
19
+ x.report("check_until with anchor") {N.times{StringScanner.new(str).check_until(ptn2)}}
20
+ x.report("check_until without anchor") {N.times{StringScanner.new(str).check_until(ptn1)}}
21
+ x.report("=~ with anchor") {N.times{ptn2 =~ str}}
22
+ x.report("=~ without anchor") {N.times{ptn1 =~ str[N/2,N]}}
23
+ end
24
+
25
+ module X
26
+ def f1
27
+ 'x1'
28
+ end
29
+ def method_missing n
30
+ puts "missing #{n}"
31
+ end
32
+ F2 = 'F2'
33
+ extend self
34
+ end
35
+ puts X::F2
36
+ #puts X::f1
37
+ #puts X.f1
38
+ puts X::F2
39
+ include X
40
+ puts F2
41
+ puts X.F2
@@ -0,0 +1,22 @@
1
+ require 'import'
2
+ require 'runit/testcase'
3
+ import :id_monad, :monad
4
+
5
+ include RParsec
6
+ class Idm
7
+ include Monad
8
+ MyMonad = IdMonad.new
9
+ def initialize(v)
10
+ initMonad(MyMonad, v);
11
+ end
12
+ def to_s
13
+ @obj.to_s
14
+ end
15
+ end
16
+
17
+ class SimpleMonadTest < RUNIT::TestCase
18
+ def test1
19
+ assert 20, Idm.new(10).map{|i|i*2}
20
+ assert 10, Idm.new(10).plus(Idm.new(20))
21
+ end
22
+ end
@@ -0,0 +1,423 @@
1
+ require 'import'
2
+ import :parsers
3
+ require 'parser_test'
4
+
5
+ class SimpleParserTest < ParserTestCase
6
+ def testValue
7
+ assertParser('', 1, value(1))
8
+ end
9
+ def testFail
10
+ assertError('', 'wrong', failure('wrong'))
11
+ end
12
+ def testGoodPlusGoodReturnFirst
13
+ assertParser('', 1, value(1)|value(2))
14
+ end
15
+ def testFailPlusGoodReturnGood
16
+ assertParser('', 2, failure('wrong')|value(2))
17
+ end
18
+ def testFailPlusFailFailsWithFirstError
19
+ assertError('', 'wrong', failure('wrong') | failure('wrong too'))
20
+ end
21
+ def testFailBreaksSeq
22
+ assertError('', 'wrong', failure('wrong') >> value(2))
23
+ end
24
+ def testGoodSeqGoodReturnsSecond
25
+ assertParser('', 2, value(1).seq(value(2)))
26
+ end
27
+ def testGoodSeqFailFails
28
+ assertError('', 'wrong', value(1) >> failure('wrong'))
29
+ end
30
+ def testFailSeqFailFails
31
+ assertError('', 'wrong', failure('wrong') >> failure('wrong too'))
32
+ end
33
+ def testMap
34
+ assertParser('', 2, value(1).map{|x|x*2})
35
+ relative = Proc.new{|x|x-?a}
36
+ assertParser('b', 1, char('b').map(&relative))
37
+ end
38
+ def testMapOnFailFails
39
+ assertError('', 'wrong', failure('wrong').map{|x|x*2})
40
+ end
41
+ def testBinds
42
+ assertParser('', 3, value(1).bind do |a|
43
+ value(2).bind{|b|value(a+b)}
44
+ end)
45
+ assertParser('', 2, value(1).repeat(2).bindn do |a,b|
46
+ value(a+b)
47
+ end)
48
+ end
49
+ def testSum
50
+ assertParser('', 1, sum(value(1), value(2), value(3)))
51
+ end
52
+ def testNestedErrorRecoveredShouldNotAppearInFinalError
53
+ assertError('', 'wrong too', (failure('wrong') | value(1)) >> failure('wrong too'))
54
+ end
55
+ def testSatisfies
56
+ assertParser('abc', ?a, Parsers.satisfies('a expected'){|c|c==(?a)})
57
+ assertError('abc', 'b expected', Parsers.satisfies('b expected'){|c|c==(?b)})
58
+ end
59
+ def testIs
60
+ assertParser('abc', ?a, is(?a))
61
+ assertError('abc', '98 expected', is(?b))
62
+ end
63
+ def testIsnt
64
+ assertParser('abc', ?a, isnt(?b))
65
+ assertError('abc', '97 unexpected', isnt(?a))
66
+ assertError('abc', "'b' unexpected", not_char(?b) >> not_char('b'), 1)
67
+ end
68
+ def testCharAndEof
69
+ assertParser('abc', ?c, char('a') >> char('b') >> char('c') >> eof())
70
+ end
71
+ def testAre
72
+ assertParser('abc', 'ab', string('ab'))
73
+ assertError('abc', '"ab" expected', char('a') >> str('ab'), 1)
74
+ end
75
+ def testSequence
76
+ assertParser('abc', ?c, sequence(char(?a),char('b'),char('c')))
77
+ a = ?a
78
+ relative = proc {|c|c-a}
79
+ parser = sequence(
80
+ char('c').map(&relative),
81
+ char('b').map(&relative),
82
+ char('a').map(&relative)
83
+ ){|x,y,z| x+y+z}
84
+ assertParser('cba', 3, parser)
85
+ end
86
+ def testPlusAutomaticallyRecoverInputConsumption
87
+ assertError('abc', '"bcd" expected', char('a') >> str('bcd').plus(str('abc')), 1)
88
+ assertParser('abc', 'abc', char('a') >> str('bcd') | str('abc'))
89
+ assertError('abc', "'d' expected", char('a') >> char(?b) >> char(?d) | char(?a) >> char(?c) | str('abd'), 2)
90
+ end
91
+ def testLookaheadRecoversInputConsumption
92
+ assertParser('abc', 'abc', (char('x') | char('a') >> str('bcd') | str('abc') | char('x')).lookahead(2))
93
+ end
94
+ def testLocator
95
+ line, col = CodeLocator.new("abc").locate(2)
96
+ assert_equal([1,3],[line,col])
97
+ end
98
+ def testInputConsumptionBiggerThanLookaheadShouldFail
99
+ assertError('abc', "'d' expected", sum(str('ab')>>char('d'), str('abc')).lookahead(2), 2)
100
+ end
101
+
102
+ def testInputConsumptionDoesNotFailForAlt
103
+ assertParser('abc', 'abc', alt(str('ab')>>char('d'), str('abc')))
104
+ end
105
+ def testAtomParserIsAlwaysRecoverable
106
+ assertParser('abc', 'abc', (str('ab')>>char('d')).atomize | str('abc'))
107
+ end
108
+ def testSimpleNot
109
+ assertParser('abc', nil, str('abd').not)
110
+ assertError('abc', 'abc unexpected', str('abc').not)
111
+ end
112
+ def testNotDoesntConsume
113
+ assertParser('abc', 'abc', ~str('abc') | str('abc'))
114
+ end
115
+ def testNotDoesntRecoverAlreadyConsumedInputWhenFailingUnlessUsingLookahead
116
+ parser = (char('a') >> str('abc')).not
117
+ assertError('abc', '"abc" expected', parser, 1)
118
+ parser = parser.lookahead(2)
119
+ assertParser('abc', nil, parser)
120
+ end
121
+ def testLookeaheadUsedInPlusCanBeUsedByNot
122
+ parser = (char('a') >> str('abc') | char('a') >> str('bcd')).lookahead(2)
123
+ # assertError('abc', '"abc" expected or "bcd" expected', parser, 1)
124
+ assertError('abc', '"abc" expected', parser, 1)
125
+ assertParser('abc', nil, parser.not)
126
+ end
127
+ def testNotString
128
+ assertParser('abc', ?a, not_string('abcd'))
129
+ assertError('abc', '"abc" unexpected', not_string('abc'))
130
+ assertError('aabcd', '"abc" unexpected', not_string('abc')*2, 1)
131
+ end
132
+ def testArent
133
+ assertError('abc', 'abc unexpected', arent('abc'))
134
+ assertParser('abc', ?a, arent('abcd'))
135
+ end
136
+ def testAmong
137
+ assertParser('abc', ?a, among(?b, ?a))
138
+ assertParser('abc', ?a, among('ba'))
139
+ assertError('abc', "one of [98, 99] expected", among(?b,?c))
140
+ end
141
+ def testNotAmong
142
+ assertError('abc', "one of [98, 97] unexpected", not_among(?b, ?a))
143
+ assertParser('abc', ?a, not_among(?b,?c))
144
+ end
145
+ def testGetIndex
146
+ assertParser('abc', 1, char('a') >> get_index)
147
+ end
148
+ def testMultilineErrorMessage
149
+ assertError("ab\nc", "'d' expected", str("ab\nc") >> char(?d), 4, 2, 2)
150
+ end
151
+ def testExpect
152
+ assertError("abc", 'word expected', str("abcd").expect("word expected"))
153
+ end
154
+ def testExpectDoesntRecover
155
+ assertError('abc', '"bcd" expected', (char(?a) >> str('bcd')).expect('word expected'), 1)
156
+ end
157
+ def testLonger
158
+ assertParser('abc', 'abc', longer(char('a')>>char('b'), str('abc')))
159
+ end
160
+ def testShorter
161
+ assertParser('abc', ?b, shorter(char('a')>>char('b')>>char('c'), char(?a) >> char(?c), char('a')>>char('b')))
162
+ end
163
+ def testLongerReportsDeepestError
164
+ assertError('abc', "'d' expected",
165
+ longer(char('a')>>char('b')>>char('d'), char('a')>>char('c')), 2)
166
+ end
167
+ def testShorterReportsDeepestError
168
+ assertError('abc', "'d' expected",
169
+ shorter(char('a')>>char('b')>>char('d'), char('a')>>char('c')), 2)
170
+ end
171
+ def testFollowed
172
+ assertParser('abc', ?a, char(?a)<<char(?b))
173
+ end
174
+ def testEof
175
+ assertParser('abc', 'abc', str('abc') << eof)
176
+ assertError('abc', 'EOF expected', str('ab') << eof, 2)
177
+ end
178
+ def testAny
179
+ assertParser('abc', ?a, any)
180
+ assertError('abc', '', str('abc')<<any, 3)
181
+ end
182
+ def testRepeat_
183
+ assertParser('abc', ?c, any*3)
184
+ assertError('abc', '', any.repeat_(4), 3)
185
+ assertError('abc', "'d' expected", any*3 >> char(?d), 3)
186
+ end
187
+ def testMany_
188
+ assertParser('abc', ?c, any.many_)
189
+ assertParser('abc', ?c, any.many_(3))
190
+ assertError('abc', "a..b expected", range(?a, ?b).many_(3), 2)
191
+ assertParser('abc', ?b, range(?a, ?b).many_())
192
+ assertParser('abc', 1, value(1).many_())
193
+ assertError('abc', "'b' expected", value(1).many_ >> char(?b))
194
+ end
195
+ def testNonDeterministicRepeat_
196
+ assertParser('abc', ?c, any.repeat_(3,4))
197
+ assertParser('abc', ?b, any.some_(2))
198
+ assertError('abc', "min=4, max=3", range(?a, ?b).repeat_(4,3))
199
+ assertParser('abc', ?b, range(?a, ?b).some_(10))
200
+ # should we break for infinite loop? they are not really infinite for some.
201
+ assertError('abc', "'b' expected", value(1).some_(2) >> char(?b))
202
+ assertParser('abc', nil, any.some_(0))
203
+ end
204
+ def testRange
205
+ assertParser('abc', ?a, range(?a, ?c))
206
+ assertError('abc', 'd..e expected', range(?d, 'e'))
207
+ assertError('abc', 'c expected', range(?c, ?b, 'c expected'))
208
+ end
209
+ def testBetween
210
+ assertParser('abc', ?b, char(?a) >> char('b') << char(?c))
211
+ end
212
+ def testRepeat
213
+ assertParser('abc', [?a, ?b, ?c], any.repeat(3))
214
+ assertParser('abc', [?a, ?b], any.repeat(2))
215
+ assertParser('abc', [], any.repeat(0))
216
+ assertError('abc', '', any.repeat(4), 3)
217
+ assertError('abc', "a..b expected", range(?a, ?b).repeat(3), 2)
218
+ end
219
+ def testMany
220
+ assertParser('abc', [?a, ?b, ?c], any.many)
221
+ assertParser('abc', [?a, ?b], range(?a, ?b).many)
222
+ assertError('abc', '', any.many(4), 3)
223
+ end
224
+ def testSome
225
+ assertParser('abc', [?a, ?b, ?c], any.some(3))
226
+ assertParser('abc', [?a, ?b], any.some(2))
227
+ assertError('abc', "a..b expected", range(?a,?b).repeat(3,4), 2)
228
+ assertParser('abc', ?c, any.some(2) >> any)
229
+ end
230
+ def testSeparated1
231
+ assertParser('a,b,c', [?a,?b,?c], any.separated1(char(',')))
232
+ assertParser('abc', [?a], any.separated1(char(',')))
233
+ assertError('a,', "'a' expected", char('a').separated1(char(',')), 2)
234
+ assertError('', '', any.separated1(char(',')))
235
+ end
236
+ def testSeparated
237
+ assertParser('a,b,c', [?a,?b,?c], any.separated(char(',')))
238
+ assertParser('abc', [?a], any.separated(char(',')))
239
+ assertError('a,', "'a' expected", char('a').separated(char(',')), 2)
240
+ assertParser('', [], any.separated(char(',')))
241
+ end
242
+ def testValueCalledImplicitlyForOverloadedOrOperator
243
+ assertParser('abc', 1, char(',')|1)
244
+ end
245
+ def testOptional
246
+ assertParser('abc', nil, char(?,).optional)
247
+ assertParser('abc', 'xyz', char(?,).optional('xyz'))
248
+ assertError('abc', "'.' expected", (any.some_(2) >> char(?.)).optional, 2)
249
+ # assertParser('abc', nil, (any.some_(2) >> char(?.)).optional)
250
+ end
251
+ def testThrowCatch
252
+ assertParser('abc', :hello, (char('a')>>throwp(:hello)).catchp(:hello))
253
+ assertParser('abc', ?a, char(?a).catchp(:hello))
254
+ end
255
+ def testDelimited1
256
+ assertParser('a,b,c', [?a,?b,?c], any.delimited1(char(',')))
257
+ assertParser('abc', [?a], any.delimited1(char(',')))
258
+ assertParser('a,', [?a], char('a').delimited1(char(',')))
259
+ assertError('', '', any.delimited1(char(',')))
260
+ assertParser('a,b', ?b, char(?a).delimited1(char(',')) >> char(?b))
261
+ end
262
+ def testDelimited
263
+ assertParser('a,b,c', [?a,?b,?c], any.delimited(char(',')))
264
+ assertParser('abc', [?a], any.delimited(char(',')))
265
+ assertParser('a,b,', [?a,?b], range('a', 'b').delimited(char(',')))
266
+ assertParser('', [], any.delimited(char(',')))
267
+ assertParser('a,b', ?b, char(?a).delimited(char(',')) >> char(?b))
268
+ end
269
+ def testRegexp
270
+ assertParser('abc', 'ab', regexp('(a|b)+', 'a or b expected'))
271
+ assertError('abc', 'x or y expected', char('a') >> regexp('(x|y)+', 'x or y expected'), 1)
272
+ end
273
+ def testWord
274
+ assertParser('abc123', 'abc123', word)
275
+ assertError('1abc123', 'word expected', word)
276
+ assertParser('abc a123', 'a123', word >> char(' ') >> word)
277
+ end
278
+ def testInteger
279
+ assertParser('123', '123', integer)
280
+ assertError('a123', 'integer expected', integer)
281
+ assertError('123a', 'integer expected', integer)
282
+ end
283
+ def testNumber
284
+ assertParser('123.456', '123.456', number)
285
+ assertParser('0123', '0123', number)
286
+ assertParser('123.2.5', '5', number >> char('.') >> number)
287
+ assertError('a123', 'number expected', number)
288
+ end
289
+ def testStringCaseInsensitive
290
+ assertParser('abc', 'abc', string_nocase('ABc'))
291
+ assertError('abc', "'ABc' expected", string_nocase('A') >> string_nocase('ABc'), 1)
292
+ end
293
+ def testFragment
294
+ assertParser('abc', 'bc', any >> (any*2).fragment)
295
+ assertError('abc', "'b' expected", any >> (char('b')*2).fragment, 2)
296
+ end
297
+ def testToken
298
+ assertGrammar('abc', 'abcabc', word.token(:word).many, token(:word){|x|x+x})
299
+ assertGrammar('abc defg', 1, word.token(:word).delimited(char(' ')), token(:word) >> token(:word) >> value(1))
300
+ assertGrammarError('abc defg', 'integer expected', 'defg', word.token(:word).delimited(char(' ')),
301
+ token(:word) >> token(:integer), 4)
302
+ end
303
+ def testGetIndexFromGrammar
304
+ assertGrammar('abc cdef', 1, word.token(:word).many, token(:word) >> get_index)
305
+ end
306
+ def testWhitespace
307
+ assertParser(' ', ?\s, whitespace)
308
+ assertParser("\t", ?\t, whitespace)
309
+ assertParser("\n", ?\n, whitespace)
310
+ assertError('abc', 'whitespace expected', whitespace)
311
+ end
312
+ def testWhitespaces
313
+ assertParser(' ', ?\s, whitespaces)
314
+ assertParser("\n\t", ?\t, whitespaces)
315
+ assertError("\n \tabc ", "whitespace(s) expected, 'a' at line 2, col 3.", whitespaces >> whitespaces, 3)
316
+ end
317
+ def testCommentLineWithLexeme
318
+ assertParser('#abc', nil, comment_line('#'))
319
+ code = <<-HERE
320
+ //HELLO
321
+ 123
322
+ HERE
323
+ delim = (comment_line('//')|whitespaces)
324
+ assertParser(code, ["123"], integer.lexeme(delim) >> eof)
325
+ assertParser('//', nil, comment_line('//'))
326
+ code = '123'
327
+ assertParser(code, ["123"], integer.lexeme(delim) >> eof)
328
+
329
+ end
330
+ def testBlockComment
331
+ cmt =comment_block('/*', '*/')
332
+ assertParser('/*abc*/', nil, cmt)
333
+ assertError('/*abcd ', '"*/" expected', cmt, 7)
334
+ end
335
+ def testLazy
336
+ expr = nil
337
+ lazy_expr = lazy{expr}
338
+ expr = integer.map(&To_i) | char('(') >> lazy_expr << char(')')
339
+ assertParser('123', 123, expr)
340
+ assertParser('((123))', 123, expr)
341
+ end
342
+ def testPeek
343
+ assertParser('abc', ?a, char('a').peek)
344
+ assertParser('abc', ?a, char('a').peek.repeat_(2))
345
+ assertError('abc', "'b' expected", char('a').peek >> char('b'))
346
+ end
347
+ def testParserTypeCheck
348
+ verifyTypeMismatch(:plus, '1st', Parser, String) do
349
+ char('a').plus('a')
350
+ end
351
+ verifyTypeMismatch(:seq, '1st', Parser, String) do
352
+ char('a').seq('a')
353
+ end
354
+ verifyTypeMismatch(:followed, '1st', Parser, String) do
355
+ char('a') << 'a'
356
+ end
357
+ verifyTypeMismatch(:sequence, '2nd', Parser, Fixnum) do
358
+ sequence(char('a'), 1, 2)
359
+ end
360
+ verifyTypeMismatch(:sum, '2nd', Parser, Fixnum) do
361
+ sum(char('a'), 1, 2)
362
+ end
363
+ verifyTypeMismatch(:longest, '2nd', Parser, Fixnum) do
364
+ longest(char('a'), 1, 2)
365
+ end
366
+ verifyTypeMismatch(:shortest, '2nd', Parser, Fixnum) do
367
+ shortest(char('a'), 1, 2)
368
+ end
369
+ end
370
+ def testSetIndex
371
+ parser = get_index.bind do |ind|
372
+ char('a') << set_index(ind)
373
+ end
374
+ assertParser('abc', [?a,?a,?a], parser.repeat(3))
375
+ end
376
+ def testMapn
377
+ assertParser('abc', ?b, any.repeat(3).mapn{|a,b,c|c-b+a})
378
+ end
379
+ def testWatch
380
+ i = nil
381
+ assertParser('abc', ?b, any.repeat_(2) >> watch{i=1});
382
+ assert_equal(1, i)
383
+ assertParser('abc', ?b, any.repeat_(2) >>
384
+ watch{|x|assert_equal(?b, x)}
385
+ )
386
+ assertParser('abc', [?a,?b], any.repeat(2) >>
387
+ watchn do |x,y|
388
+ assert_equal(?a, x)
389
+ assert_equal(?b, y)
390
+ end
391
+ )
392
+ assertParser('abc', ?b, any.repeat_(2) >> watch);
393
+ end
394
+ def testMapCurrent
395
+ assertParser('abc', ?b, any >> map{|x|x+1})
396
+ assertParser('abc', ?a, any >> map)
397
+ assertParser('abc', ?a, any.map)
398
+ assertParser('abc', ?a, any.mapn)
399
+ end
400
+ def testMapnCurrent
401
+ assertParser('abc', ?a, any.repeat(2) >> mapn{|a,_|a})
402
+ assertParser('abc', ?c, any.repeat_(2) >> mapn(&Inc))
403
+ assertParser('abc', [?a,?b], any.repeat(2) >> mapn)
404
+ end
405
+ def verifyTypeMismatch(mtd, n, expected, actual)
406
+ begin
407
+ yield
408
+ assert_fail('should have failed with type mismatch')
409
+ rescue ArgumentError => e
410
+ assert_equal("#{actual} assigned to #{expected} for the #{n} argument of #{mtd}.",
411
+ e.message)
412
+ end
413
+ end
414
+ def verifyArrayTypeMismatch(mtd, n_arg, n_elem, expected, actual)
415
+ begin
416
+ yield
417
+ assert_fail('should have failed with type mismatch')
418
+ rescue ArgumentError => e
419
+ assert_equal("#{actual} assigned to #{expected} for the #{n_elem} element of the #{n_arg} argument of #{mtd}.",
420
+ e.message)
421
+ end
422
+ end
423
+ end