progs/comb2.scala
changeset 673 715b46eee102
parent 628 8067d0a8ba04
child 683 c6c79d21f8a8
equal deleted inserted replaced
672:e0d76f7f0688 673:715b46eee102
     2 // 
     2 // 
     3 
     3 
     4 import scala.language.implicitConversions
     4 import scala.language.implicitConversions
     5 import scala.language.reflectiveCalls
     5 import scala.language.reflectiveCalls
     6 
     6 
     7 
     7 // more convenience for the semantic actions later on
     8 abstract class Parser[I, T](implicit ev: I => Seq[_]) {
     8 case class ~[+A, +B](_1: A, _2: B)
       
     9 
       
    10 
       
    11 type IsSeq[A] = A => Seq[_]
       
    12 
       
    13 abstract class Parser[I : IsSeq, T] {
     9   def parse(ts: I): Set[(T, I)]
    14   def parse(ts: I): Set[(T, I)]
    10 
    15 
    11   def parse_all(ts: I) : Set[T] =
    16   def parse_all(ts: I) : Set[T] =
    12     for ((head, tail) <- parse(ts); if (tail.isEmpty)) yield head
    17     for ((head, tail) <- parse(ts); if (tail.isEmpty)) yield head
    13 }
    18 }
    14 
    19 
    15 class SeqParser[I, T, S](p: => Parser[I, T], q: => Parser[I, S])(implicit ev: I => Seq[_]) extends Parser[I, (T, S)] {
    20 class SeqParser[I : IsSeq, T, S](p: => Parser[I, T], q: => Parser[I, S]) extends Parser[I, ~[T, S]] {
    16   def parse(sb: I) = 
    21   def parse(sb: I) = 
    17     for ((head1, tail1) <- p.parse(sb); 
    22     for ((head1, tail1) <- p.parse(sb); 
    18          (head2, tail2) <- q.parse(tail1)) yield ((head1, head2), tail2)
    23          (head2, tail2) <- q.parse(tail1)) yield (new ~(head1, head2), tail2)
    19 }
    24 }
    20 
    25 
    21 class AltParser[I, T](p: => Parser[I, T], q: => Parser[I, T])(implicit ev: I => Seq[_]) extends Parser[I, T] {
    26 class AltParser[I : IsSeq, T](p: => Parser[I, T], q: => Parser[I, T]) extends Parser[I, T] {
    22   def parse(sb: I) = p.parse(sb) ++ q.parse(sb)   
    27   def parse(sb: I) = p.parse(sb) ++ q.parse(sb)   
    23 }
    28 }
    24 
    29 
    25 class FunParser[I, T, S](p: => Parser[I, T], f: T => S)(implicit ev: I => Seq[_]) extends Parser[I, S] {
    30 class FunParser[I : IsSeq, T, S](p: => Parser[I, T], f: T => S) extends Parser[I, S] {
    26   def parse(sb: I) = 
    31   def parse(sb: I) = 
    27     for ((head, tail) <- p.parse(sb)) yield (f(head), tail)
    32     for ((head, tail) <- p.parse(sb)) yield (f(head), tail)
    28 }
    33 }
    29 
    34 
    30 case class StringParser(s: String) extends Parser[String, String] {
    35 case class StringParser(s: String) extends Parser[String, String] {
    46 }
    51 }
    47 
    52 
    48 
    53 
    49 implicit def string2parser(s : String) = StringParser(s)
    54 implicit def string2parser(s : String) = StringParser(s)
    50 
    55 
    51 implicit def ParserOps[I, T](p: Parser[I, T])(implicit ev: I => Seq[_]) = new {
    56 implicit def ParserOps[I : IsSeq, T](p: Parser[I, T]) = new {
    52   def || (q : => Parser[I, T]) = new AltParser[I, T](p, q)
    57   def || (q : => Parser[I, T]) = new AltParser[I, T](p, q)
    53   def ==>[S] (f: => T => S) = new FunParser[I, T, S](p, f)
    58   def ==>[S] (f: => T => S) = new FunParser[I, T, S](p, f)
    54   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    59   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    55 }
    60 }
    56 
    61 
    96     case Some(s) => Set(sb.splitAt(s.length))
   101     case Some(s) => Set(sb.splitAt(s.length))
    97   }
   102   }
    98 }
   103 }
    99 
   104 
   100 lazy val AExp: Parser[String, AExp] = 
   105 lazy val AExp: Parser[String, AExp] = 
   101   (Te ~ "+" ~ AExp) ==> { case ((x, y), z) => Aop("+", x, z): AExp } ||
   106   (Te ~ "+" ~ AExp) ==> { case x ~ y ~ z => Aop("+", x, z): AExp } ||
   102   (Te ~ "-" ~ AExp) ==> { case ((x, y), z) => Aop("-", x, z): AExp } || Te 
   107   (Te ~ "-" ~ AExp) ==> { case x ~ y ~ z => Aop("-", x, z): AExp } || Te 
   103 lazy val Te: Parser[String, AExp] = 
   108 lazy val Te: Parser[String, AExp] = 
   104   (Fa ~ "*" ~ Te) ==> { case ((x, y), z) => Aop("*", x, z): AExp } || 
   109   (Fa ~ "*" ~ Te) ==> { case x ~ y ~ z => Aop("*", x, z): AExp } || 
   105   (Fa ~ "/" ~ Te) ==> { case ((x, y), z) => Aop("/", x, z): AExp } || Fa  
   110   (Fa ~ "/" ~ Te) ==> { case x ~ y ~ z => Aop("/", x, z): AExp } || Fa  
   106 lazy val Fa: Parser[String, AExp] = 
   111 lazy val Fa: Parser[String, AExp] = 
   107    ("(" ~ AExp ~ ")") ==> { case ((x, y), z) => y } || 
   112    ("(" ~ AExp ~ ")") ==> { case x ~ y ~ z => y } || 
   108    IdParser ==> Var || 
   113    IdParser ==> Var || 
   109    NumParser ==> Num
   114    NumParser ==> Num
   110 
   115 
   111 // boolean expressions with some simple nesting
   116 // boolean expressions with some simple nesting
   112 lazy val BExp: Parser[String, BExp] = 
   117 lazy val BExp: Parser[String, BExp] = 
   113    (AExp ~ "==" ~ AExp) ==> { case ((x, y), z) => Bop("==", x, z): BExp } || 
   118    (AExp ~ "==" ~ AExp) ==> { case x ~ y ~ z => Bop("==", x, z): BExp } || 
   114    (AExp ~ "!=" ~ AExp) ==> { case ((x, y), z) => Bop("!=", x, z): BExp } || 
   119    (AExp ~ "!=" ~ AExp) ==> { case x ~ y ~ z => Bop("!=", x, z): BExp } || 
   115    (AExp ~ "<" ~ AExp) ==> { case ((x, y), z) => Bop("<", x, z): BExp } || 
   120    (AExp ~ "<" ~ AExp) ==> { case x ~ y ~ z => Bop("<", x, z): BExp } || 
   116    (AExp ~ ">" ~ AExp) ==> { case ((x, y), z) => Bop(">", x, z): BExp } ||
   121    (AExp ~ ">" ~ AExp) ==> { case x ~ y ~ z => Bop(">", x, z): BExp } ||
   117    ("(" ~ BExp ~ ")" ~ "&&" ~ BExp) ==> { case ((((x, y), z), u), v) => And(y, v): BExp } ||
   122    ("(" ~ BExp ~ ")" ~ "&&" ~ BExp) ==> { case x ~ y ~ z ~ u ~ v => And(y, v): BExp } ||
   118    ("(" ~ BExp ~ ")" ~ "||" ~ BExp) ==> { case ((((x, y), z), u), v) => Or(y, v): BExp } ||
   123    ("(" ~ BExp ~ ")" ~ "||" ~ BExp) ==> { case x ~ y ~ z ~ u ~ v => Or(y, v): BExp } ||
   119    ("true" ==> ((_) => True: BExp )) || 
   124    ("true" ==> (_ => True: BExp )) || 
   120    ("false" ==> ((_) => False: BExp )) ||
   125    ("false" ==> (_ => False: BExp )) ||
   121    ("(" ~ BExp ~ ")") ==> { case ((x, y), z) => y}
   126    ("(" ~ BExp ~ ")") ==> { case x ~ y ~ z => y}
   122 
   127 
   123 // statement / statements
   128 // statement / statements
   124 lazy val Stmt: Parser[String, Stmt] =
   129 lazy val Stmt: Parser[String, Stmt] =
   125   (("skip" ==> ((_) => Skip: Stmt)) ||
   130   (("skip" ==> (_ => Skip: Stmt)) ||
   126    (IdParser ~ ":=" ~ AExp) ==> { case ((x, y), z) => Assign(x, z): Stmt } ||
   131    (IdParser ~ ":=" ~ AExp) ==> { case x ~ y ~ z => Assign(x, z): Stmt } ||
   127    ("write(" ~ IdParser ~ ")") ==> { case ((x, y), z) => Write(y): Stmt } ||
   132    ("write(" ~ IdParser ~ ")") ==> { case x ~y ~ z => Write(y): Stmt } ||
   128    ("if" ~ BExp ~ "then" ~ Block ~ "else" ~ Block) ==>
   133    ("if" ~ BExp ~ "then" ~ Block ~ "else" ~ Block) ==>
   129     { case (((((x,y),z),u),v),w) => If(y, u, w): Stmt } ||
   134     { case x ~ y ~ z ~ u ~ v ~ w => If(y, u, w): Stmt } ||
   130    ("while" ~ BExp ~ "do" ~ Block) ==> { case (((x, y), z), w) => While(y, w) }) 
   135    ("while" ~ BExp ~ "do" ~ Block) ==> { case x ~ y ~ z ~ w => While(y, w) }) 
   131  
   136  
   132 lazy val Stmts: Parser[String, Block] =
   137 lazy val Stmts: Parser[String, Block] =
   133   (Stmt ~ ";" ~ Stmts) ==> { case ((x, y), z) => x :: z : Block } ||
   138   (Stmt ~ ";" ~ Stmts) ==> { case x ~ y ~ z => x :: z : Block } ||
   134   (Stmt ==> ((s) => List(s) : Block))
   139   (Stmt ==> ( s => List(s) : Block))
   135 
   140 
   136 // blocks (enclosed in curly braces)
   141 // blocks (enclosed in curly braces)
   137 lazy val Block: Parser[String, Block] =
   142 lazy val Block: Parser[String, Block] =
   138   (("{" ~ Stmts ~ "}") ==> { case ((x, y), z) => y} || 
   143   (("{" ~ Stmts ~ "}") ==> { case x ~ y ~ z => y} || 
   139    (Stmt ==> ((s) => List(s))))
   144    (Stmt ==> (s => List(s))))
   140 
   145 
   141 
   146 
   142 Stmts.parse_all("x2:=5+3;")
   147 Stmts.parse_all("x2:=5+3;")
   143 Block.parse_all("{x:=5;y:=8}")
   148 Block.parse_all("{x:=5;y:=8}")
   144 Block.parse_all("if(false)then{x:=5}else{x:=10}")
   149 Block.parse_all("if(false)then{x:=5}else{x:=10}")