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