|     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) } ||  |