19 for ((hd, tl) <- parse(in); |
19 for ((hd, tl) <- parse(in); |
20 if is(tl).isEmpty) yield hd |
20 if is(tl).isEmpty) yield hd |
21 } |
21 } |
22 |
22 |
23 // parser combinators |
23 // parser combinators |
24 |
|
25 |
24 |
26 |
25 |
27 // alternative parser |
26 // alternative parser |
28 class AltParser[I : IsSeq, T](p: => Parser[I, T], |
27 class AltParser[I : IsSeq, T](p: => Parser[I, T], |
29 q: => Parser[I, T]) extends Parser[I, T] { |
28 q: => Parser[I, T]) extends Parser[I, T] { |
94 def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |
93 def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |
95 def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |
94 def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |
96 def map[S](f: => T => S) = new MapParser[I, T, S](p, f) |
95 def map[S](f: => T => S) = new MapParser[I, T, S](p, f) |
97 } |
96 } |
98 |
97 |
|
98 // simple example of transforming the |
|
99 // result into capital letters |
99 def toU(s: String) = s.map(_.toUpper) |
100 def toU(s: String) = s.map(_.toUpper) |
100 |
101 |
101 (p"ELSE").map(toU(_)).parse("ELSEifthen") |
102 (p"else").map(toU(_)).parse("elseifthen") |
102 |
103 |
103 // these implicits allow us to use an infix notation for |
104 // these implicits allow us to use an infix notation for |
104 // sequences and alternatives; we also can write the usual |
105 // sequences and alternatives; we also can write the usual |
105 // map for a MapParser |
106 // map for a MapParser |
106 |
107 |
110 |
111 |
111 val NumParserInt2 = NumParser.map(_.toInt) |
112 val NumParserInt2 = NumParser.map(_.toInt) |
112 |
113 |
113 |
114 |
114 // A parser for palindromes (just returns them as string) |
115 // A parser for palindromes (just returns them as string) |
|
116 // since the parser is recursive it needs to be lazy |
115 lazy val Pal : Parser[String, String] = { |
117 lazy val Pal : Parser[String, String] = { |
116 (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } || |
118 (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } || |
117 (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } || |
119 (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } || |
118 p"a" || p"b" || p"" |
120 p"a" || p"b" || p"" |
119 } |
121 } |