progs/parser-combinators/comb2.sc
changeset 742 b5b5583a3a08
parent 732 c7bdd7eac4cb
child 803 d4fb8c7fc3bf
equal deleted inserted replaced
741:e66bd5c563eb 742:b5b5583a3a08
     1 // Parser Combinators: Simple Version
     1 // Parser Combinators:
       
     2 // Simple Version for WHILE-language
     2 //====================================
     3 //====================================
     3 
     4 //
     4 
     5 // with some added convenience for
     5 // more convenience for the map parsers later on
     6 // map-parsers and grammar rules
       
     7 //
       
     8 // call with
       
     9 //
       
    10 //    amm comb2.sc
       
    11 
       
    12 
       
    13 
       
    14 
       
    15 // more convenience for the map parsers later on;
       
    16 // it allows writing nested patterns as
       
    17 // case x ~ y ~ z => ...
       
    18 
     6 case class ~[+A, +B](_1: A, _2: B)
    19 case class ~[+A, +B](_1: A, _2: B)
     7 
    20 
     8 /* 
    21 
     9   Note, in the lectures I did not show the implicit type constraint
    22 // constraint for the input
    10   I : IsSeq, which means that the input type 'I' needs to be
       
    11   a sequence. 
       
    12 */
       
    13 
       
    14 type IsSeq[A] = A => Seq[_]
    23 type IsSeq[A] = A => Seq[_]
       
    24 
    15 
    25 
    16 abstract class Parser[I : IsSeq, T]{
    26 abstract class Parser[I : IsSeq, T]{
    17   def parse(in: I): Set[(T, I)]
    27   def parse(in: I): Set[(T, I)]
    18 
    28 
    19   def parse_all(in: I) : Set[T] =
    29   def parse_all(in: I) : Set[T] =
   139    (p"(" ~ BExp ~ p")" ~ p"||" ~ BExp).map[BExp]{ case _ ~ y ~ _ ~ _ ~ v => Or(y, v) } ||
   149    (p"(" ~ BExp ~ p")" ~ p"||" ~ BExp).map[BExp]{ case _ ~ y ~ _ ~ _ ~ v => Or(y, v) } ||
   140    (p"true".map[BExp]{ _ => True }) || 
   150    (p"true".map[BExp]{ _ => True }) || 
   141    (p"false".map[BExp]{ _ => False }) ||
   151    (p"false".map[BExp]{ _ => False }) ||
   142    (p"(" ~ BExp ~ p")").map[BExp]{ case _ ~ x ~ _ => x }
   152    (p"(" ~ BExp ~ p")").map[BExp]{ case _ ~ x ~ _ => x }
   143 
   153 
   144 // statement 
   154 // a single statement 
   145 lazy val Stmt: Parser[String, Stmt] =
   155 lazy val Stmt: Parser[String, Stmt] =
   146   ((p"skip".map[Stmt]{_ => Skip }) ||
   156   ((p"skip".map[Stmt]{_ => Skip }) ||
   147    (IdParser ~ p":=" ~ AExp).map[Stmt]{ case x ~ _ ~ z => Assign(x, z) } ||
   157    (IdParser ~ p":=" ~ AExp).map[Stmt]{ case x ~ _ ~ z => Assign(x, z) } ||
   148    (p"write(" ~ IdParser ~ p")").map[Stmt]{ case _ ~ y ~ _ => Write(y) } ||
   158    (p"write(" ~ IdParser ~ p")").map[Stmt]{ case _ ~ y ~ _ => Write(y) } ||
   149    (p"if" ~ BExp ~ p"then" ~ Block ~ p"else" ~ Block)
   159    (p"if" ~ BExp ~ p"then" ~ Block ~ p"else" ~ Block)
   221 }
   231 }
   222 
   232 
   223 def eval(bl: Block) : Env = eval_bl(bl, Map())
   233 def eval(bl: Block) : Env = eval_bl(bl, Map())
   224 
   234 
   225 // parse + evaluate fib program; then lookup what is
   235 // parse + evaluate fib program; then lookup what is
   226 // stored under the variable result 
   236 // stored under the variable "result" 
   227 println(eval(Stmts.parse_all(fib).head)("result"))
   237 println(eval(Stmts.parse_all(fib).head)("result"))
   228 
   238 
   229 
   239 
   230 // more examles
   240 // more examles
   231 
   241 
   240         if ((n / f) * f == n) then  { write(f) } else { skip };
   250         if ((n / f) * f == n) then  { write(f) } else { skip };
   241         f := f + 1
   251         f := f + 1
   242       }""".replaceAll("\\s+", "")
   252       }""".replaceAll("\\s+", "")
   243 
   253 
   244 println(eval(Stmts.parse_all(factors).head))
   254 println(eval(Stmts.parse_all(factors).head))
       
   255 
   245 
   256 
   246 // calculate all prime numbers up to a number 
   257 // calculate all prime numbers up to a number 
   247 println("Primes")
   258 println("Primes")
   248 
   259 
   249 val primes =  
   260 val primes =