| 725 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      1 | import scala.language.implicitConversions    
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      2 | import scala.language.reflectiveCalls
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      3 | import scala.annotation.tailrec   
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      4 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      5 | abstract class Rexp 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      6 | case object NULL extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      7 | case object EMPTY extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      8 | case class CHAR(c: Char) extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      9 | case class ALT(r1: Rexp, r2: Rexp) extends Rexp 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     10 | case class SEQ(r1: Rexp, r2: Rexp) extends Rexp 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     11 | case class STAR(r: Rexp) extends Rexp 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     12 | case class RECD(x: String, r: Rexp) extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     13 | case class CRANGE(cs: String) extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     14 | case class PLUS(r: Rexp) extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     15 | case class OPT(r: Rexp) extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     16 | case class NTIMES(r: Rexp, n: Int) extends Rexp
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     17 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     18 | abstract class Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     19 | case object Empty extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     20 | case class Chr(c: Char) extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     21 | case class Seq(v1: Val, v2: Val) extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     22 | case class Left(v: Val) extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     23 | case class Right(v: Val) extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     24 | case class Stars(vs: List[Val]) extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     25 | case class Rec(x: String, v: Val) extends Val
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     26 |    
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     27 | // some convenience for typing in regular expressions
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     28 | def charlist2rexp(s : List[Char]): Rexp = s match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     29 |   case Nil => EMPTY
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     30 |   case c::Nil => CHAR(c)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     31 |   case c::s => SEQ(CHAR(c), charlist2rexp(s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     32 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     33 | implicit def string2rexp(s : String) : Rexp = charlist2rexp(s.toList)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     34 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     35 | implicit def RexpOps(r: Rexp) = new {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     36 |   def | (s: Rexp) = ALT(r, s)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     37 |   def % = STAR(r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     38 |   def ~ (s: Rexp) = SEQ(r, s)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     39 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     40 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     41 | implicit def stringOps(s: String) = new {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     42 |   def | (r: Rexp) = ALT(s, r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     43 |   def | (r: String) = ALT(s, r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     44 |   def % = STAR(s)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     45 |   def ~ (r: Rexp) = SEQ(s, r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     46 |   def ~ (r: String) = SEQ(s, r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     47 |   def $ (r: Rexp) = RECD(s, r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     48 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     49 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     50 | // nullable function: tests whether the regular 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     51 | // expression can recognise the empty string
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     52 | def nullable (r: Rexp) : Boolean = r match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     53 |   case NULL => false
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     54 |   case EMPTY => true
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     55 |   case CHAR(_) => false
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     56 |   case ALT(r1, r2) => nullable(r1) || nullable(r2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     57 |   case SEQ(r1, r2) => nullable(r1) && nullable(r2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     58 |   case STAR(_) => true
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     59 |   case RECD(_, r) => nullable(r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     60 |   case CRANGE(_) => false
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     61 |   case PLUS(r) => nullable(r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     62 |   case OPT(_) => true
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     63 |   case NTIMES(r, n) => if (n == 0) true else nullable(r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     64 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     65 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     66 | // derivative of a regular expression w.r.t. a character
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     67 | def der (c: Char, r: Rexp) : Rexp = r match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     68 |   case NULL => NULL
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     69 |   case EMPTY => NULL
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     70 |   case CHAR(d) => if (c == d) EMPTY else NULL
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     71 |   case ALT(r1, r2) => ALT(der(c, r1), der(c, r2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     72 |   case SEQ(r1, r2) => 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     73 |     if (nullable(r1)) ALT(SEQ(der(c, r1), r2), der(c, r2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     74 |     else SEQ(der(c, r1), r2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     75 |   case STAR(r) => SEQ(der(c, r), STAR(r))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     76 |   case RECD(_, r1) => der(c, r1)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     77 |   case CRANGE(cs) => if (cs.contains(c)) EMPTY else NULL
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     78 |   case PLUS(r) => SEQ(der(c, r), STAR(r))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     79 |   case OPT(r) => ALT(der(c, r), NULL)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     80 |   case NTIMES(r, n) => if (n == 0) NULL else der(c, SEQ(r, NTIMES(r, n - 1)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     81 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     82 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     83 | // derivative w.r.t. a string (iterates der)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     84 | def ders (s: List[Char], r: Rexp) : Rexp = s match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     85 |   case Nil => r
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     86 |   case c::s => ders(s, der(c, r))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     87 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     88 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     89 | // extracts a string from value
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     90 | def flatten(v: Val) : String = v match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     91 |   case Empty => ""
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     92 |   case Chr(c) => c.toString
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     93 |   case Left(v) => flatten(v)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     94 |   case Right(v) => flatten(v)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     95 |   case Seq(v1, v2) => flatten(v1) + flatten(v2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     96 |   case Stars(vs) => vs.map(flatten).mkString
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     97 |   case Rec(_, v) => flatten(v)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     98 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     99 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    100 | // extracts an environment from a value
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    101 | def env(v: Val) : List[(String, String)] = v match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    102 |   case Empty => Nil
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    103 |   case Chr(c) => Nil
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    104 |   case Left(v) => env(v)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    105 |   case Right(v) => env(v)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    106 |   case Seq(v1, v2) => env(v1) ::: env(v2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    107 |   case Stars(vs) => vs.flatMap(env)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    108 |   case Rec(x, v) => (x, flatten(v))::env(v)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    109 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    110 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    111 | // injection part
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    112 | def mkeps(r: Rexp) : Val = r match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    113 |   case EMPTY => Empty
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    114 |   case ALT(r1, r2) => 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    115 |     if (nullable(r1)) Left(mkeps(r1)) else Right(mkeps(r2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    116 |   case SEQ(r1, r2) => Seq(mkeps(r1), mkeps(r2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    117 |   case STAR(r) => Stars(Nil)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    118 |   case RECD(x, r) => Rec(x, mkeps(r))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    119 |   case PLUS(r) => Stars(List(mkeps(r)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    120 |   case OPT(_) => Right(Empty)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    121 |   case NTIMES(r, n) => if (n == 0) Stars(Nil) else Stars(Nil.padTo(n, mkeps(r)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    122 |   case _ => { println ("r : " + r.toString); 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    123 |               throw new Exception("mkeps error")}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    124 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    125 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    126 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    127 | def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    128 |   case (STAR(r), Seq(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    129 |   case (SEQ(r1, r2), Seq(v1, v2)) => Seq(inj(r1, c, v1), v2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    130 |   case (SEQ(r1, r2), Left(Seq(v1, v2))) => Seq(inj(r1, c, v1), v2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    131 |   case (SEQ(r1, r2), Right(v2)) => Seq(mkeps(r1), inj(r2, c, v2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    132 |   case (ALT(r1, r2), Left(v1)) => Left(inj(r1, c, v1))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    133 |   case (ALT(r1, r2), Right(v2)) => Right(inj(r2, c, v2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    134 |   case (CHAR(_), Empty) => Chr(c) 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    135 |   case (CRANGE(_), Empty) => Chr(c) 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    136 |   case (RECD(x, r1), _) => Rec(x, inj(r1, c, v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    137 |   case (PLUS(r), Seq(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    138 |   case (OPT(r), Left(v1)) => Left(inj(r, c, v1))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    139 |   case (NTIMES(r, n), Seq(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    140 |   case (NTIMES(r, n), Left(Seq(v1, Stars(vs)))) => Stars(inj(r, c, v1)::vs)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    141 |   case (NTIMES(r, n), Right(Stars(v::vs))) => Stars(mkeps(r)::inj(r, c, v)::vs)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    142 |   case _ => { println ("r : " + r.toString + "  v: " + v.toString); 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    143 |               throw new Exception("inj error")}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    144 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    145 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    146 | // main lexing function (produces a value)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    147 | def lex(r: Rexp, s: List[Char]) : Val = s match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    148 |   case Nil => if (nullable(r)) mkeps(r) else throw new Exception("Not matched")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    149 |   case c::cs => inj(r, c, lex(der(c, r), cs))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    150 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    151 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    152 | def lexing(r: Rexp, s: String) : Val = lex(r, s.toList)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    153 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    154 | lexing(("ab" | "ab") ~ ("b" | EMPTY), "ab")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    155 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    156 | lexing(OPT("ab"), "ab")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    157 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    158 | lexing(NTIMES("1", 3), "111")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    159 | lexing(NTIMES("1" | EMPTY, 3), "11")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    160 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    161 | // some "rectification" functions for simplification
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    162 | def F_ID(v: Val): Val = v
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    163 | def F_RIGHT(f: Val => Val) = (v:Val) => Right(f(v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    164 | def F_LEFT(f: Val => Val) = (v:Val) => Left(f(v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    165 | def F_ALT(f1: Val => Val, f2: Val => Val) = (v:Val) => v match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    166 |   case Right(v) => Right(f2(v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    167 |   case Left(v) => Left(f1(v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    168 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    169 | def F_SEQ(f1: Val => Val, f2: Val => Val) = (v:Val) => v match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    170 |   case Seq(v1, v2) => Seq(f1(v1), f2(v2))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    171 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    172 | def F_SEQ_Empty1(f1: Val => Val, f2: Val => Val) = 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    173 |   (v:Val) => Seq(f1(Empty), f2(v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    174 | def F_SEQ_Empty2(f1: Val => Val, f2: Val => Val) = 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    175 |   (v:Val) => Seq(f1(v), f2(Empty))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    176 | def F_RECD(f: Val => Val) = (v:Val) => v match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    177 |   case Rec(x, v) => Rec(x, f(v))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    178 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    179 | def F_ERROR(v: Val): Val = throw new Exception("error")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    180 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    181 | // simplification of regular expressions returning also an
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    182 | // rectification function; no simplification under STAR 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    183 | def simp(r: Rexp): (Rexp, Val => Val) = r match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    184 |   case ALT(r1, r2) => {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    185 |     val (r1s, f1s) = simp(r1)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    186 |     val (r2s, f2s) = simp(r2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    187 |     (r1s, r2s) match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    188 |       case (NULL, _) => (r2s, F_RIGHT(f2s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    189 |       case (_, NULL) => (r1s, F_LEFT(f1s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    190 |       case _ => if (r1s == r2s) (r1s, F_LEFT(f1s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    191 |                 else (ALT (r1s, r2s), F_ALT(f1s, f2s)) 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    192 |     }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    193 |   }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    194 |   case SEQ(r1, r2) => {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    195 |     val (r1s, f1s) = simp(r1)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    196 |     val (r2s, f2s) = simp(r2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    197 |     (r1s, r2s) match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    198 |       case (NULL, _) => (NULL, F_ERROR)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    199 |       case (_, NULL) => (NULL, F_ERROR)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    200 |       case (EMPTY, _) => (r2s, F_SEQ_Empty1(f1s, f2s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    201 |       case (_, EMPTY) => (r1s, F_SEQ_Empty2(f1s, f2s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    202 |       case _ => (SEQ(r1s,r2s), F_SEQ(f1s, f2s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    203 |     }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    204 |   }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    205 |   case RECD(x, r1) => {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    206 |     val (r1s, f1s) = simp(r1)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    207 |     (RECD(x, r1s), F_RECD(f1s))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    208 |   }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    209 |   case r => (r, F_ID)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    210 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    211 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    212 | def lex_simp(r: Rexp, s: List[Char]) : Val = s match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    213 |   case Nil => if (nullable(r)) mkeps(r) else throw new Exception("Not matched")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    214 |   case c::cs => {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    215 |     val (r_simp, f_simp) = simp(der(c, r))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    216 |     inj(r, c, f_simp(lex_simp(r_simp, cs)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    217 |   }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    218 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    219 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    220 | def lexing_simp(r: Rexp, s: String) : Val = lex_simp(r, s.toList)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    221 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    222 | lexing_simp(("a" | "ab") ~ ("b" | ""), "ab")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    223 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    224 | lexing_simp(OPT("ab"), "ab")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    225 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    226 | // Lexing Rules for a Small While Language
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    227 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    228 | val SYM = CRANGE("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    229 | val DIGIT = CRANGE("0123456789")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    230 | val ID = SYM ~ (SYM | DIGIT).% 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    231 | val NUM = PLUS(DIGIT)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    232 | val KEYWORD : Rexp = "skip" | "while" | "do" | "if" | "then" | "else" | "read" | "write" | "true" | "false"
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    233 | val SEMI: Rexp = ";"
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    234 | val OP: Rexp = ":=" | "==" | "-" | "+" | "*" | "!=" | "<" | ">" | "<=" | ">=" | "%" | "/"
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    235 | val WHITESPACE = PLUS(" " | "\n" | "\t")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    236 | val RPAREN: Rexp = ")"
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    237 | val LPAREN: Rexp = "("
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    238 | val BEGIN: Rexp = "{"
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    239 | val END: Rexp = "}"
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    240 | val STRING: Rexp = "\"" ~ SYM.% ~ "\""
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    241 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    242 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    243 | val WHILE_REGS = (("k" $ KEYWORD) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    244 |                   ("i" $ ID) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    245 |                   ("o" $ OP) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    246 |                   ("n" $ NUM) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    247 |                   ("s" $ SEMI) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    248 |                   ("str" $ STRING) |
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    249 |                   ("p" $ (LPAREN | RPAREN)) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    250 |                   ("b" $ (BEGIN | END)) | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    251 |                   ("w" $ WHITESPACE)).%
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    252 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    253 | // filters out all white spaces
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    254 | def tokenise(r: Rexp, s: String) = 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    255 |   env(lexing_simp(r, s)).filterNot { (s) => s._1 == "w"}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    256 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    257 | //   Testing
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    258 | //============
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    259 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    260 | def time[T](code: => T) = {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    261 |   val start = System.nanoTime()
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    262 |   val result = code
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    263 |   val end = System.nanoTime()
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    264 |   println((end - start)/1.0e9)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    265 |   result
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    266 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    267 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    268 | println(lexing_simp(OPT("1"), "1"))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    269 | println(lexing_simp(OPT("1"), ""))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    270 | println(ders("111".toList, NTIMES("1",3)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    271 | println(lexing_simp(NTIMES("1",3), "111"))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    272 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    273 | val r1 = ("a" | "ab") ~ ("bcd" | "c")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    274 | println(lexing(r1, "abcd"))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    275 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    276 | val r2 = ("" | "a") ~ ("ab" | "b")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    277 | println(lexing(r2, "ab"))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    278 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    279 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    280 | // Two Simple While Tests
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    281 | //========================
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    282 | println("prog0 test")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    283 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    284 | val prog0 = """read n"""
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    285 | println(env(lexing_simp(WHILE_REGS, prog0)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    286 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    287 | println("prog1 test")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    288 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    289 | val prog1 = """read  n; write (n)"""
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    290 | println(env(lexing_simp(WHILE_REGS, prog1)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    291 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    292 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    293 | // Big Test
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    294 | //==========
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    295 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    296 | def escape(raw: String): String = {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    297 |   import scala.reflect.runtime.universe._
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    298 |   Literal(Constant(raw)).toString
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    299 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    300 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    301 | val prog2 = """
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    302 | write "Fib";
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    303 | read n;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    304 | minus1 := 0;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    305 | minus2 := 1;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    306 | while n > 0 do {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    307 |   temp := minus2;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    308 |   minus2 := minus1 + minus2;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    309 |   minus1 := temp;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    310 |   n := n - 1
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    311 | };
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    312 | write "Result";
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    313 | write minus2
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    314 | """
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    315 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    316 | val prog3 = """
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    317 | start := 1000;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    318 | x := start;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    319 | y := start;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    320 | z := start;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    321 | while 0 < x do {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    322 |  while 0 < y do {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    323 |   while 0 < z do {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    324 |     z := z - 1
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    325 |   };
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    326 |   z := start;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    327 |   y := y - 1
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    328 |  };     
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    329 |  y := start;
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    330 |  x := x - 1
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    331 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    332 | """
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    333 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    334 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    335 | println("Tokens")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    336 | println(tokenise(WHILE_REGS, prog2).mkString("\n"))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    337 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    338 | val fib_tokens = tokenise(WHILE_REGS, prog2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    339 | fib_tokens.map{case (s1, s2) => (escape(s1), escape(s2))}.mkString(",\n")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    340 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    341 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    342 | val test_tokens = tokenise(WHILE_REGS, prog3)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    343 | test_tokens.map{case (s1, s2) => (escape(s1), escape(s2))}.mkString(",\n")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    344 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    345 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    346 | /*
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    347 | for (i <- 1 to 120 by 10) {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    348 |   print(i.toString + ":  ")
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    349 |   time(lexing_simp(WHILE_REGS, prog2 * i))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    350 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    351 | */
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    352 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    353 | val toks_fib = 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    354 |   List(("k","write"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    355 |        ("str","Fib"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    356 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    357 |        ("k","read"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    358 |        ("i","n"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    359 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    360 |        ("i","minus1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    361 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    362 |        ("n","0"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    363 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    364 |        ("i","minus2"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    365 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    366 |        ("n","1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    367 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    368 |        ("k","while"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    369 |        ("i","n"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    370 |        ("o",">"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    371 |        ("n","0"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    372 |        ("k","do"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    373 |        ("b","{"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    374 |        ("i","temp"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    375 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    376 |        ("i","minus2"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    377 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    378 |        ("i","minus2"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    379 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    380 |        ("i","minus1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    381 |        ("o","+"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    382 |        ("i","minus2"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    383 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    384 |        ("i","minus1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    385 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    386 |        ("i","temp"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    387 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    388 |        ("i","n"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    389 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    390 |        ("i","n"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    391 |        ("o","-"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    392 |        ("n","1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    393 |        ("b","}"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    394 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    395 |        ("k","write"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    396 |        ("str","Result"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    397 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    398 |        ("k","write"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    399 |        ("i","minus2"))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    400 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    401 | val toks_test =
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    402 |   List(("i","start"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    403 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    404 |        ("n","1000"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    405 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    406 |        ("i","x"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    407 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    408 |        ("i","start"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    409 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    410 |        ("i","y"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    411 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    412 |        ("i","start"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    413 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    414 |        ("i","z"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    415 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    416 |        ("i","start"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    417 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    418 |        ("k","while"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    419 |        ("n","0"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    420 |        ("o","<"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    421 |        ("i","x"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    422 |        ("k","do"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    423 |        ("b","{"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    424 |        ("k","while"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    425 |        ("n","0"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    426 |        ("o","<"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    427 |        ("i","y"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    428 |        ("k","do"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    429 |        ("b","{"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    430 |        ("k","while"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    431 |        ("n","0"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    432 |        ("o","<"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    433 |        ("i","z"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    434 |        ("k","do"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    435 |        ("b","{"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    436 |        ("i","z"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    437 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    438 |        ("i","z"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    439 |        ("o","-"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    440 |        ("n","1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    441 |        ("b","}"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    442 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    443 |        ("i","z"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    444 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    445 |        ("i","start"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    446 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    447 |        ("i","y"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    448 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    449 |        ("i","y"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    450 |        ("o","-"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    451 |        ("n","1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    452 |        ("b","}"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    453 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    454 |        ("i","y"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    455 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    456 |        ("i","start"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    457 |        ("s",";"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    458 |        ("i","x"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    459 |        ("o",":="),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    460 |        ("i","x"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    461 |        ("o","-"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    462 |        ("n","1"),
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    463 |        ("b","}"))
 |