rparsec-ruby19 1.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.
@@ -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