progs/token2.scala
changeset 385 7f8516ff408d
parent 368 a9911966c0df
child 388 66f66f1710ed
--- a/progs/token2.scala	Mon Nov 23 16:45:07 2015 +0000
+++ b/progs/token2.scala	Wed Nov 25 15:59:32 2015 +0000
@@ -13,6 +13,7 @@
 case class CRANGE(cs: String) extends Rexp
 case class PLUS(r: Rexp) extends Rexp
 case class OPT(r: Rexp) extends Rexp
+case class NTIMES(r: Rexp, n: Int) extends Rexp
 
 abstract class Val
 case object Empty extends Val
@@ -59,6 +60,7 @@
   case CRANGE(_) => false
   case PLUS(r) => nullable(r)
   case OPT(_) => true
+  case NTIMES(r, n) => if (n == 0) true else nullable(r)
 }
 
 // derivative of a regular expression w.r.t. a character
@@ -75,6 +77,7 @@
   case CRANGE(cs) => if (cs.contains(c)) EMPTY else NULL
   case PLUS(r) => SEQ(der(c, r), STAR(r))
   case OPT(r) => ALT(der(c, r), NULL)
+  case NTIMES(r, n) => if (n == 0) NULL else der(c, SEQ(r, NTIMES(r, n - 1)))
 }
 
 // derivative w.r.t. a string (iterates der)
@@ -115,6 +118,9 @@
   case RECD(x, r) => Rec(x, mkeps(r))
   case PLUS(r) => Stars(List(mkeps(r)))
   case OPT(_) => Right(Empty)
+  case NTIMES(r, n) => if (n == 0) Stars(Nil) else Stars(Nil.padTo(n, mkeps(r)))
+  case _ => { println ("r : " + r.toString); 
+              throw new Exception("mkeps error")}
 }
 
 
@@ -130,6 +136,11 @@
   case (RECD(x, r1), _) => Rec(x, inj(r1, c, v))
   case (PLUS(r), Seq(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs)
   case (OPT(r), Left(v1)) => Left(inj(r, c, v1))
+  case (NTIMES(r, n), Seq(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs)
+  case (NTIMES(r, n), Left(Seq(v1, Stars(vs)))) => Stars(inj(r, c, v1)::vs)
+  case (NTIMES(r, n), Right(Stars(v::vs))) => Stars(mkeps(r)::inj(r, c, v)::vs)
+  case _ => { println ("r : " + r.toString + "  v: " + v.toString); 
+              throw new Exception("inj error")}
 }
 
 // main lexing function (produces a value)
@@ -240,7 +251,6 @@
 def tokenise(r: Rexp, s: String) = 
   env(lexing_simp(r, s)).filterNot { (s) => s._1 == "w"}.mkString("\n")
 
-
 //   Testing
 //============
 
@@ -252,6 +262,11 @@
   result
 }
 
+println(lexing_simp(OPT("1"), "1"))
+println(lexing_simp(OPT("1"), ""))
+println(ders("111".toList, NTIMES("1",3)))
+println(lexing_simp(NTIMES("1",3), "111"))
+
 val r1 = ("a" | "ab") ~ ("bcd" | "c")
 println(lexing(r1, "abcd"))