1 // Parser Combinators: Simple Version |
1 // Parser Combinators: |
|
2 // Simple Version for WHILE-language |
2 //==================================== |
3 //==================================== |
3 |
4 // |
4 |
5 // with some added convenience for |
5 // more convenience for the map parsers later on |
6 // map-parsers and grammar rules |
|
7 // |
|
8 // call with |
|
9 // |
|
10 // amm comb2.sc |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 // more convenience for the map parsers later on; |
|
16 // it allows writing nested patterns as |
|
17 // case x ~ y ~ z => ... |
|
18 |
6 case class ~[+A, +B](_1: A, _2: B) |
19 case class ~[+A, +B](_1: A, _2: B) |
7 |
20 |
8 /* |
21 |
9 Note, in the lectures I did not show the implicit type constraint |
22 // constraint for the input |
10 I : IsSeq, which means that the input type 'I' needs to be |
|
11 a sequence. |
|
12 */ |
|
13 |
|
14 type IsSeq[A] = A => Seq[_] |
23 type IsSeq[A] = A => Seq[_] |
|
24 |
15 |
25 |
16 abstract class Parser[I : IsSeq, T]{ |
26 abstract class Parser[I : IsSeq, T]{ |
17 def parse(in: I): Set[(T, I)] |
27 def parse(in: I): Set[(T, I)] |
18 |
28 |
19 def parse_all(in: I) : Set[T] = |
29 def parse_all(in: I) : Set[T] = |
139 (p"(" ~ BExp ~ p")" ~ p"||" ~ BExp).map[BExp]{ case _ ~ y ~ _ ~ _ ~ v => Or(y, v) } || |
149 (p"(" ~ BExp ~ p")" ~ p"||" ~ BExp).map[BExp]{ case _ ~ y ~ _ ~ _ ~ v => Or(y, v) } || |
140 (p"true".map[BExp]{ _ => True }) || |
150 (p"true".map[BExp]{ _ => True }) || |
141 (p"false".map[BExp]{ _ => False }) || |
151 (p"false".map[BExp]{ _ => False }) || |
142 (p"(" ~ BExp ~ p")").map[BExp]{ case _ ~ x ~ _ => x } |
152 (p"(" ~ BExp ~ p")").map[BExp]{ case _ ~ x ~ _ => x } |
143 |
153 |
144 // statement |
154 // a single statement |
145 lazy val Stmt: Parser[String, Stmt] = |
155 lazy val Stmt: Parser[String, Stmt] = |
146 ((p"skip".map[Stmt]{_ => Skip }) || |
156 ((p"skip".map[Stmt]{_ => Skip }) || |
147 (IdParser ~ p":=" ~ AExp).map[Stmt]{ case x ~ _ ~ z => Assign(x, z) } || |
157 (IdParser ~ p":=" ~ AExp).map[Stmt]{ case x ~ _ ~ z => Assign(x, z) } || |
148 (p"write(" ~ IdParser ~ p")").map[Stmt]{ case _ ~ y ~ _ => Write(y) } || |
158 (p"write(" ~ IdParser ~ p")").map[Stmt]{ case _ ~ y ~ _ => Write(y) } || |
149 (p"if" ~ BExp ~ p"then" ~ Block ~ p"else" ~ Block) |
159 (p"if" ~ BExp ~ p"then" ~ Block ~ p"else" ~ Block) |