progs/token2.scala
changeset 368 a9911966c0df
parent 367 04127a5aad23
child 385 7f8516ff408d
--- 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")