3 |
3 |
4 /* Note, in the lectures I did not show the type consraint |
4 /* Note, in the lectures I did not show the type consraint |
5 * I <% Seq[_] , which means that the input type I can be |
5 * I <% Seq[_] , which means that the input type I can be |
6 * treated, or seen, as a sequence. */ |
6 * treated, or seen, as a sequence. */ |
7 |
7 |
8 abstract class Parser[I <% Seq[_], T] { |
8 trait Input { |
9 def parse(ts: I): Set[(T, I)] |
9 def isEmpty: Boolean |
|
10 } |
10 |
11 |
11 def parse_all(ts: I) : Set[T] = |
12 |
|
13 abstract class Parser[T] { |
|
14 |
|
15 def parse(ts: Input): Set[(T, Input)] |
|
16 |
|
17 def parse_all(ts: Input) : Set[T] = |
12 for ((head, tail) <- parse(ts); |
18 for ((head, tail) <- parse(ts); |
13 if (tail.isEmpty)) yield head |
19 if (tail.isEmpty)) yield head |
14 } |
20 } |
15 |
21 |
16 class SeqParser[I <% Seq[_], T, S](p: => Parser[I, T], |
22 class SeqParser[T, S](p: => Parser[T], |
17 q: => Parser[I, S]) extends Parser[I, (T, S)] { |
23 q: => Parser[S]) extends Parser[(T, S)] { |
18 def parse(sb: I) = |
24 def parse(sb: Input) = |
19 for ((head1, tail1) <- p.parse(sb); |
25 for ((head1, tail1) <- p.parse(sb); |
20 (head2, tail2) <- q.parse(tail1)) yield ((head1, head2), tail2) |
26 (head2, tail2) <- q.parse(tail1)) yield ((head1, head2), tail2) |
21 } |
27 } |
22 |
28 |
23 class AltParser[I <% Seq[_], T](p: => Parser[I, T], |
29 class AltParser[T](p: => Parser[T], |
24 q: => Parser[I, T]) extends Parser[I, T] { |
30 q: => Parser[T]) extends Parser[T] { |
25 def parse(sb: I) = p.parse(sb) ++ q.parse(sb) |
31 def parse(sb: Input) = p.parse(sb) ++ q.parse(sb) |
26 } |
32 } |
27 |
33 |
28 class FunParser[I <% Seq[_], T, S](p: => Parser[I, T], |
34 class FunParser[T, S](p: => Parser[T], |
29 f: T => S) extends Parser[I, S] { |
35 f: T => S) extends Parser[S] { |
30 def parse(sb: I) = |
36 def parse(sb: Input) = |
31 for ((head, tail) <- p.parse(sb)) yield (f(head), tail) |
37 for ((head, tail) <- p.parse(sb)) yield (f(head), tail) |
32 } |
38 } |
33 |
39 |
34 // atomic parsers |
40 // atomic parsers |
35 case class CharParser(c: Char) extends Parser[String, Char] { |
41 case class CharParser(c: Char) extends Parser[Char] { |
|
42 type Input = String |
|
43 |
36 def parse(sb: String) = |
44 def parse(sb: String) = |
37 if (sb.head == c) Set((c, sb.tail)) else Set() |
45 if (sb.head == c) Set((c, sb.tail)) else Set() |
38 } |
46 } |
39 |
47 |
40 case class StringParser(s: String) extends Parser[String, String] { |
48 case class StringParser(s: String) extends Parser[String, String] { |