diff -r 4629448c1bd9 -r 7f8516ff408d progs/token2.scala --- 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"))