progs/parser-combinators/comb2.sc
changeset 948 6bb67c2dcfd3
parent 941 66adcae6c762
child 954 eda0ccf56c72
equal deleted inserted replaced
947:dc31a099dc98 948:6bb67c2dcfd3
    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) } ||