1
+ abstract class Reader [+ T ] {
2
+ def first : T
3
+
4
+ def rest : Reader [T ]
5
+
6
+ def atEnd : Boolean
7
+ }
8
+
9
+ trait Parsers {
10
+ type Elem
11
+ type Input = Reader [Elem ]
12
+
13
+ sealed abstract class ParseResult [+ T ] {
14
+ val successful : Boolean
15
+
16
+ def map [U ](f : T => U ): ParseResult [U ]
17
+
18
+ def flatMapWithNext [U ](f : T => Input => ParseResult [U ]): ParseResult [U ]
19
+ }
20
+
21
+ sealed abstract class NoSuccess (val msg : String ) extends ParseResult [Nothing ] { // when we don't care about the difference between Failure and Error
22
+ val successful = false
23
+
24
+ def map [U ](f : Nothing => U ) = this
25
+
26
+ def flatMapWithNext [U ](f : Nothing => Input => ParseResult [U ]): ParseResult [U ]
27
+ = this
28
+ }
29
+
30
+ case class Failure (override val msg : String ) extends NoSuccess (msg)
31
+
32
+ case class Error (override val msg : String ) extends NoSuccess (msg)
33
+
34
+ case class Success [+ T ](result : T , val next : Input ) extends ParseResult [T ] {
35
+ val successful = true
36
+
37
+ def map [U ](f : T => U ) = Success (f(result), next)
38
+
39
+ def flatMapWithNext [U ](f : T => Input => ParseResult [U ]): ParseResult [U ] = f(result)(next) match {
40
+ case s @ Success (result, rest) => Success (result, rest)
41
+ case f : Failure => f
42
+ case e : Error => e
43
+ }
44
+ }
45
+
46
+ case class ~ [+ a, + b](_1 : a, _2 : b) {
47
+ override def toString = s " ( ${_1}~ ${_2}) "
48
+ }
49
+
50
+ abstract class Parser [+ T ] extends (Input => ParseResult [T ]) {
51
+ def apply (in : Input ): ParseResult [T ]
52
+
53
+ def ~ [U ](q : => Parser [U ]): Parser [~ [T , U ]] = {
54
+ (for (a <- this ; b <- q) yield new ~ (a,b))
55
+ }
56
+
57
+ def flatMap [U ](f : T => Parser [U ]): Parser [U ]
58
+ = Parser { in => this (in) flatMapWithNext(f)}
59
+
60
+ def map [U ](f : T => U ): Parser [U ] // = flatMap{x => success(f(x))}
61
+ = Parser { in => this (in) map(f)}
62
+
63
+ def ^^ [U ](f : T => U ): Parser [U ] = map(f)
64
+ }
65
+
66
+ def Parser [T ](f : Input => ParseResult [T ]): Parser [T ]
67
+ = new Parser [T ]{ def apply (in : Input ) = f(in) }
68
+
69
+ def accept (e : Elem ): Parser [Elem ] = acceptIf(_ == e)(" '" + e+ " ' expected but " + _ + " found" )
70
+
71
+ def acceptIf (p : Elem => Boolean )(err : Elem => String ): Parser [Elem ] = Parser { in =>
72
+ if (in.atEnd) Failure (" end of input" )
73
+ else if (p(in.first)) Success (in.first, in.rest)
74
+ else Failure (err(in.first))
75
+ }
76
+ }
77
+
78
+
79
+ object grammars3 extends Parsers {
80
+ type Elem = String
81
+
82
+ val a : Parser [String ] = accept(" a" )
83
+ val b : Parser [String ] = accept(" b" )
84
+
85
+ val AnBnCn : Parser [List [String ]] = {
86
+ repMany(a,b)
87
+ }
88
+
89
+ def repMany [T ](p : => Parser [T ], q : => Parser [T ]): Parser [List [T ]] =
90
+ p~ repMany(p,q)~ q ^^ {case x~ xs~ y => x:: xs::: (y:: Nil )}
91
+ }
0 commit comments