--- a/progs/token2.scala Sat Nov 07 21:37:03 2015 +0000
+++ b/progs/token2.scala Tue Nov 10 22:27:46 2015 +0000
@@ -12,6 +12,7 @@
case class RECD(x: String, r: Rexp) extends Rexp
case class CRANGE(cs: String) extends Rexp
case class PLUS(r: Rexp) extends Rexp
+case class OPT(r: Rexp) extends Rexp
abstract class Val
case object Empty extends Val
@@ -57,6 +58,7 @@
case RECD(_, r) => nullable(r)
case CRANGE(_) => false
case PLUS(r) => nullable(r)
+ case OPT(_) => true
}
// derivative of a regular expression w.r.t. a character
@@ -72,6 +74,7 @@
case RECD(_, r1) => der(c, r1)
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)
}
// derivative w.r.t. a string (iterates der)
@@ -111,6 +114,7 @@
case STAR(r) => Stars(Nil)
case RECD(x, r) => Rec(x, mkeps(r))
case PLUS(r) => Stars(List(mkeps(r)))
+ case OPT(_) => Right(Empty)
}
@@ -125,6 +129,7 @@
case (CRANGE(_), Empty) => Chr(c)
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))
}
// main lexing function (produces a value)
@@ -137,6 +142,8 @@
lexing(("ab" | "ab") ~ ("b" | EMPTY), "ab")
+lexing(OPT("ab"), "ab")
+
// some "rectification" functions for simplification
def F_ID(v: Val): Val = v
def F_RIGHT(f: Val => Val) = (v:Val) => Right(f(v))
@@ -200,6 +207,8 @@
lexing_simp(("a" | "ab") ~ ("b" | ""), "ab")
+lexing_simp(OPT("ab"), "ab")
+
// Lexing Rules for a Small While Language
val SYM = CRANGE("abcdefghijklmnopqrstuvwxyz")