6 case object ONE extends Rexp  | 
     6 case object ONE extends Rexp  | 
     7 case class CHAR(c: Char) extends Rexp  | 
     7 case class CHAR(c: Char) extends Rexp  | 
     8 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   | 
     8 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   | 
     9 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   | 
     9 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   | 
    10 case class STAR(r: Rexp) extends Rexp   | 
    10 case class STAR(r: Rexp) extends Rexp   | 
    11 case class RECD(x: String, r: Rexp) extends Rexp  | 
    11 case class RECD[A](f: String => A, r: Rexp) extends Rexp  | 
    12   | 
    12   | 
    13 abstract class Val  | 
    13 abstract class Val  | 
    14 case object Empty extends Val  | 
    14 case object Empty extends Val  | 
    15 case class Chr(c: Char) extends Val  | 
    15 case class Chr(c: Char) extends Val  | 
    16 case class Sequ(v1: Val, v2: Val) extends Val  | 
    16 case class Sequ(v1: Val, v2: Val) extends Val  | 
    17 case class Left(v: Val) extends Val  | 
    17 case class Left(v: Val) extends Val  | 
    18 case class Right(v: Val) extends Val  | 
    18 case class Right(v: Val) extends Val  | 
    19 case class Stars(vs: List[Val]) extends Val  | 
    19 case class Stars(vs: List[Val]) extends Val  | 
    20 case class Rec(x: String, v: Val) extends Val  | 
    20 case class Rec[A](f: String => A, v: Val) extends Val  | 
    21      | 
    21      | 
    22 // some convenience for typing in regular expressions  | 
    22 // some convenience for typing in regular expressions  | 
    23 def charlist2rexp(s : List[Char]): Rexp = s match { | 
    23 def charlist2rexp(s : List[Char]): Rexp = s match { | 
    24   case Nil => ONE  | 
    24   case Nil => ONE  | 
    25   case c::Nil => CHAR(c)  | 
    25   case c::Nil => CHAR(c)  | 
    77 def flatten(v: Val) : String = v match { | 
    77 def flatten(v: Val) : String = v match { | 
    78   case Empty => ""  | 
    78   case Empty => ""  | 
    79   case Chr(c) => c.toString  | 
    79   case Chr(c) => c.toString  | 
    80   case Left(v) => flatten(v)  | 
    80   case Left(v) => flatten(v)  | 
    81   case Right(v) => flatten(v)  | 
    81   case Right(v) => flatten(v)  | 
    82   case Sequ(v1, v2) => flatten(v1) + flatten(v2)  | 
    82   case Sequ(v1, v2) => flatten(v1) ++ flatten(v2)  | 
    83   case Stars(vs) => vs.map(flatten).mkString  | 
    83   case Stars(vs) => vs.map(flatten).mkString  | 
    84   case Rec(_, v) => flatten(v)  | 
    84   case Rec(_, v) => flatten(v)  | 
    85 }  | 
    85 }  | 
    86   | 
    86   | 
    87 // extracts an environment from a value  | 
    87 // extracts an environment from a value  | 
    88 def env(v: Val) : List[(String, String)] = v match { | 
    88 def env[A](v: Val) : List[A] = v match { | 
    89   case Empty => Nil  | 
    89   case Empty => Nil  | 
    90   case Chr(c) => Nil  | 
    90   case Chr(c) => Nil  | 
    91   case Left(v) => env(v)  | 
    91   case Left(v) => env(v)  | 
    92   case Right(v) => env(v)  | 
    92   case Right(v) => env(v)  | 
    93   case Sequ(v1, v2) => env(v1) ::: env(v2)  | 
    93   case Sequ(v1, v2) => env(v1) ::: env(v2)  | 
    94   case Stars(vs) => vs.flatMap(env)  | 
    94   case Stars(vs) => vs.flatMap(env)  | 
    95   case Rec(x, v) => (x, flatten(v))::env(v)  | 
    95   case Rec(f, v) => ((f:String => A)(flatten(v)))::env(v)  | 
    96 }  | 
    96 }  | 
    97   | 
    97   | 
    98 // injection part  | 
    98 // injection part  | 
    99 def mkeps(r: Rexp) : Val = r match { | 
    99 def mkeps(r: Rexp) : Val = r match { | 
   100   case ONE => Empty  | 
   100   case ONE => Empty  | 
   209 val BEGIN: Rexp = "{" | 
   209 val BEGIN: Rexp = "{" | 
   210 val END: Rexp = "}"  | 
   210 val END: Rexp = "}"  | 
   211 val STRING: Rexp = "\"" ~ SYM.% ~ "\""  | 
   211 val STRING: Rexp = "\"" ~ SYM.% ~ "\""  | 
   212   | 
   212   | 
   213   | 
   213   | 
   214 val WHILE_REGS = (("k" $ KEYWORD) |  | 
   214 val WHILE_REGS = (((s) => Token $ KEYWORD) |   | 
   215                   ("i" $ ID) |  | 
   215                   ("i" $ ID) |  | 
   216                   ("o" $ OP) |  | 
   216                   ("o" $ OP) |  | 
   217                   ("n" $ NUM) |  | 
   217                   ("n" $ NUM) |  | 
   218                   ("s" $ SEMI) |  | 
   218                   ("s" $ SEMI) |  | 
   219                   ("str" $ STRING) | | 
   219                   ("str" $ STRING) | | 
   220                   ("p" $ (LPAREN | RPAREN)) |  | 
   220                   ("p" $ (LPAREN | RPAREN)) |  | 
   221                   ("b" $ (BEGIN | END)) |  | 
   221                   ("b" $ (BEGIN | END)) |  | 
   222                   ("w" $ WHITESPACE)).% | 
   222                   ("w" $ WHITESPACE)).% | 
         | 
   223   | 
         | 
   224   | 
         | 
   225   | 
         | 
   226   | 
         | 
   227 // extracts an environment from a value  | 
         | 
   228 def env(v: Val) : List[Token] = v match { | 
         | 
   229   case Empty => Nil  | 
         | 
   230   case Chr(c) => Nil  | 
         | 
   231   case Left(v) => env(v)  | 
         | 
   232   case Right(v) => env(v)  | 
         | 
   233   case Sequ(v1, v2) => env(v1) ::: env(v2)  | 
         | 
   234   case Stars(vs) => vs.flatMap(env)  | 
         | 
   235   case Rec(f, v) => (f(flatten(v)))::env(v)  | 
         | 
   236 }  | 
   223   | 
   237   | 
   224 //   Testing  | 
   238 //   Testing  | 
   225 //============  | 
   239 //============  | 
   226   | 
   240   | 
   227 def time[T](code: => T) = { | 
   241 def time[T](code: => T) = { | 
   280 for (i <- 1 to 21 by 10) { | 
   294 for (i <- 1 to 21 by 10) { | 
   281   print(i.toString + ":  ")  | 
   295   print(i.toString + ":  ")  | 
   282   time(lexing_simp(WHILE_REGS, prog2 * i))  | 
   296   time(lexing_simp(WHILE_REGS, prog2 * i))  | 
   283 }  | 
   297 }  | 
   284   | 
   298   | 
   285   | 
   299 abstract class Token  | 
         | 
   300 case class KeyToken(s: String) extends Token  | 
         | 
   301 case class IdToken(s: String) extends Token  | 
         | 
   302   | 
         | 
   303 list[(STRING, STRING)]=> List(TOKEN)  |