progs/parser-combinators/comb2.sc
changeset 965 94f5cce73a4f
parent 956 ae9782e62bdd
child 971 51e00f223792
equal deleted inserted replaced
964:da1f8c033b8e 965:94f5cce73a4f
    12 // more convenience for the map parsers later on;
    12 // more convenience for the map parsers later on;
    13 // it allows writing nested patterns as
    13 // it allows writing nested patterns as
    14 // case x ~ y ~ z => ...
    14 // case x ~ y ~ z => ...
    15 
    15 
    16 
    16 
    17 case class ~[+A, +B](x: A, y: B)
    17 case class o[+A, +B](x: A, y: B)
    18 
    18 
    19 
    19 
    20 type IsSeq[I] = I => Seq[_]
    20 type IsSeq[I] = I => Seq[?]
    21 
    21 
    22 abstract class Parser[I, T](using is: I => Seq[_])  {
    22 abstract class Parser[I, T](using is: I => Seq[?])  {
    23   def parse(in: I): Set[(T, I)]  
    23   def parse(in: I): Set[(T, I)]  
    24 
    24 
    25   def parse_all(in: I) : Set[T] =
    25   def parse_all(in: I) : Set[T] =
    26     for ((hd, tl) <- parse(in); 
    26     for ((hd, tl) <- parse(in); 
    27         if is(tl).isEmpty) yield hd
    27         if is(tl).isEmpty) yield hd
    35   def parse(in: I) = p.parse(in) ++ q.parse(in)   
    35   def parse(in: I) = p.parse(in) ++ q.parse(in)   
    36 }
    36 }
    37 
    37 
    38 // sequence parser
    38 // sequence parser
    39 class SeqParser[I : IsSeq, T, S](p: => Parser[I, T], 
    39 class SeqParser[I : IsSeq, T, S](p: => Parser[I, T], 
    40                                  q: => Parser[I, S]) extends Parser[I, ~[T, S]] {
    40                                  q: => Parser[I, S]) extends Parser[I, o[T, S]] {
    41   def parse(in: I) = 
    41   def parse(in: I) = 
    42     for ((hd1, tl1) <- p.parse(in); 
    42     for ((hd1, tl1) <- p.parse(in); 
    43          (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2)
    43          (hd2, tl2) <- q.parse(tl1)) yield (new o(hd1, hd2), tl2)
    44 }
    44 }
    45 
    45 
    46 // map parser
    46 // map parser
    47 class MapParser[I : IsSeq, T, S](p: => Parser[I, T], 
    47 class MapParser[I : IsSeq, T, S](p: => Parser[I, T], 
    48                                 f: T => S) extends Parser[I, S] {
    48                                 f: T => S) extends Parser[I, S] {
    85 // StrParser(_some_string_) more conveniently as 
    85 // StrParser(_some_string_) more conveniently as 
    86 //
    86 //
    87 // p"<_some_string_>" 
    87 // p"<_some_string_>" 
    88 
    88 
    89 extension (sc: StringContext) 
    89 extension (sc: StringContext) 
    90   def p(args: Any*) = StrParser(sc.s(args:_*))
    90   def p(args: Any*) = StrParser(sc.s(args*))
    91 
    91 
    92 
    92 
    93 // more convenient syntax for parser combinators
    93 // more convenient syntax for parser combinators
    94 extension [I : IsSeq, T](p: Parser[I, T]) {
    94 extension [I : IsSeq, T](p: Parser[I, T]) {
    95   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)
    95   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)
    96   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    96   def o[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    97   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
    97   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
    98 }
    98 }
    99 
    99 
   100 
   100 
   101 // the abstract syntax trees for the WHILE language
   101 // the abstract syntax trees for the WHILE language
   122 case class Or(b1: BExp, b2: BExp) extends BExp
   122 case class Or(b1: BExp, b2: BExp) extends BExp
   123 
   123 
   124 
   124 
   125 // arithmetic expressions
   125 // arithmetic expressions
   126 lazy val AExp: Parser[String, AExp] = 
   126 lazy val AExp: Parser[String, AExp] = 
   127   (Te ~ p"+" ~ AExp).map[AExp]{ case x ~ _ ~ z => Aop("+", x, z) } ||
   127   (Te o p"+" o AExp).map[AExp]{ case x o _ o z => Aop("+", x, z): AExp } ||
   128   (Te ~ p"-" ~ AExp).map[AExp]{ case x ~ _ ~ z => Aop("-", x, z) } || Te
   128   (Te o p"-" o AExp).map[AExp]{ case x o _ o z => Aop("-", x, z) } || Te
   129 lazy val Te: Parser[String, AExp] = 
   129 lazy val Te: Parser[String, AExp] = 
   130   (Fa ~ p"*" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("*", x, z) } || 
   130   (Fa o p"*" o Te).map[AExp]{ case x o _ o z => Aop("*", x, z) } || 
   131   (Fa ~ p"/" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("/", x, z) } || Fa  
   131   (Fa o p"/" o Te).map[AExp]{ case x o _ o z => Aop("/", x, z) } || Fa  
   132 lazy val Fa: Parser[String, AExp] = 
   132 lazy val Fa: Parser[String, AExp] = 
   133    (p"(" ~ AExp ~ p")").map{ case _ ~ y ~ _ => y } || 
   133    (p"(" o AExp o p")").map{ case _ o y o _ => y } || 
   134    IdParser.map(Var(_)) || 
   134    IdParser.map(Var(_)) || 
   135    NumParser.map(Num(_))
   135    NumParser.map(Num(_))
   136 
   136 
   137 // boolean expressions with some simple nesting
   137 // boolean expressions with some simple nesting
   138 lazy val BExp: Parser[String, BExp] = 
   138 lazy val BExp: Parser[String, BExp] =