12 |
12 |
13 // more convenience for the map parsers later on; |
13 // more convenience for the map parsers later on; |
14 // it allows writing nested patterns as |
14 // it allows writing nested patterns as |
15 // case x ~ y ~ z => ... |
15 // case x ~ y ~ z => ... |
16 |
16 |
17 |
|
18 |
|
19 case class ~[+A, +B](x: A, y: B) |
17 case class ~[+A, +B](x: A, y: B) |
|
18 |
|
19 |
20 |
20 |
21 type IsSeq[I] = I => Seq[_] |
21 type IsSeq[I] = I => Seq[_] |
22 |
22 |
23 abstract class Parser[I, T](using is: I => Seq[_]) { |
23 abstract class Parser[I, T](using is: I => Seq[_]) { |
24 def parse(in: I): Set[(T, I)] |
24 def parse(in: I): Set[(T, I)] |
43 for ((hd1, tl1) <- p.parse(in); |
43 for ((hd1, tl1) <- p.parse(in); |
44 (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2) |
44 (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2) |
45 } |
45 } |
46 |
46 |
47 // map parser |
47 // map parser |
48 class maparser[I : IsSeq, T, S](p: => Parser[I, T], |
48 class MapParser[I : IsSeq, T, S](p: => Parser[I, T], |
49 f: T => S) extends Parser[I, S] { |
49 f: T => S) extends Parser[I, S] { |
50 def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl) |
50 def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl) |
51 } |
51 } |
52 |
52 |
53 |
53 |
68 case Some(s) => Set(sb.splitAt(s.length)) |
68 case Some(s) => Set(sb.splitAt(s.length)) |
69 } |
69 } |
70 } |
70 } |
71 |
71 |
72 |
72 |
73 // atomic parser for numbers (transformed into ints) |
73 // atomic parser for numbers (transformed into Ints) |
74 case object NumParser extends Parser[String, Int] { |
74 case object NumParser extends Parser[String, Int] { |
75 val reg = "[0-9]+".r |
75 val reg = "[0-9]+".r |
76 def parse(sb: String) = reg.findPrefixOf(sb) match { |
76 def parse(sb: String) = reg.findPrefixOf(sb) match { |
77 case None => Set() |
77 case None => Set() |
78 case Some(s) => { |
78 case Some(s) => { |
93 |
93 |
94 // more convenient syntax for parser combinators |
94 // more convenient syntax for parser combinators |
95 extension [I : IsSeq, T](p: Parser[I, T]) { |
95 extension [I : IsSeq, T](p: Parser[I, T]) { |
96 def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |
96 def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |
97 def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |
97 def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |
98 def map[S](f: => T => S) = new maparser[I, T, S](p, f) |
98 def map[S](f: => T => S) = new MapParser[I, T, S](p, f) |
99 } |
99 } |
100 |
100 |
101 |
101 |
102 |
102 |
103 |
103 |
132 lazy val Te: Parser[String, AExp] = |
132 lazy val Te: Parser[String, AExp] = |
133 (Fa ~ p"*" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("*", x, z) } || |
133 (Fa ~ p"*" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("*", x, z) } || |
134 (Fa ~ p"/" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("/", x, z) } || Fa |
134 (Fa ~ p"/" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("/", x, z) } || Fa |
135 lazy val Fa: Parser[String, AExp] = |
135 lazy val Fa: Parser[String, AExp] = |
136 (p"(" ~ AExp ~ p")").map{ case _ ~ y ~ _ => y } || |
136 (p"(" ~ AExp ~ p")").map{ case _ ~ y ~ _ => y } || |
137 IdParser.map(Var) || |
137 IdParser.map(Var(_)) || |
138 NumParser.map(Num) |
138 NumParser.map(Num(_)) |
139 |
139 |
140 // boolean expressions with some simple nesting |
140 // boolean expressions with some simple nesting |
141 lazy val BExp: Parser[String, BExp] = |
141 lazy val BExp: Parser[String, BExp] = |
142 (AExp ~ p"==" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("==", x, z) } || |
142 (AExp ~ p"==" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("==", x, z) } || |
143 (AExp ~ p"!=" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("!=", x, z) } || |
143 (AExp ~ p"!=" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("!=", x, z) } || |