progs/matcher/re1.sc
changeset 998 69eddde11a65
parent 981 14e5ae1fb541
equal deleted inserted replaced
997:d7dfa3cf527f 998:69eddde11a65
     7 // or 
     7 // or 
     8 //
     8 //
     9 //   amm re1.sc all
     9 //   amm re1.sc all
    10 //
    10 //
    11 
    11 
    12  
    12 
    13 // regular expressions (as enum in Scala 3)
    13 // regular expressions (as enum in Scala 3)
    14 enum Rexp {
    14 enum Rexp {
    15   case ZERO                     // matches nothing
    15   case ZERO                     // matches nothing
    16   case ONE                      // matches an empty string
    16   case ONE                      // matches an empty string
    17   case CHAR(c: Char)            // matches a character c
    17   case CHAR(c: Char)            // matches a character c
    18   case ALT(r1: Rexp, r2: Rexp)  // alternative
    18   case ALT(r1: Rexp, r2: Rexp)  // alternative
    19   case SEQ(r1: Rexp, r2: Rexp)  // sequence
    19   case SEQ(r1: Rexp, r2: Rexp)  // sequence
    20   case STAR(r: Rexp)            // star
    20   case STAR(r: Rexp)            // star
    21 }
    21 }
    22 import Rexp._
    22 import Rexp._
       
    23 
       
    24 
       
    25 /* 
       
    26 UPDATE: The videos and handouts still us the older syntax 
       
    27 with classes, which still works but is more verbose
       
    28 
       
    29 abstract class Rexp
       
    30 case object ZERO extends Rexp
       
    31 case object ONE extends Rexp
       
    32 case class CHAR(c: Char) extends Rexp
       
    33 case class ALT(r1: Rexp, r2: Rexp) extends Rexp
       
    34 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp
       
    35 case class STAR(r: Rexp) extends Rexp
       
    36 */
    23 
    37 
    24 // nullable function: tests whether a regular 
    38 // nullable function: tests whether a regular 
    25 // expression can recognise the empty string  
    39 // expression can recognise the empty string  
    26 def nullable(r: Rexp) : Boolean = r match {
    40 def nullable(r: Rexp) : Boolean = r match {
    27   case ZERO => false
    41   case ZERO => false
   215 }
   229 }
   216 
   230 
   217 @main
   231 @main
   218 def all() = { test1(); test2() ; test3() ; test4() } 
   232 def all() = { test1(); test2() ; test3() ; test4() } 
   219 
   233 
   220 
       
   221 
       
   222 
       
   223 
       
   224 // partial derivatives produce a set of regular expressions
       
   225 def pder(c: Char, r: Rexp) : Set[Rexp] = r match {
       
   226   case ZERO => Set()
       
   227   case ONE => Set()
       
   228   case CHAR(d) => if (c == d) Set(ONE) else Set()
       
   229   case ALT(r1, r2) => pder(c, r1) ++ pder(c, r2)
       
   230   case SEQ(r1, r2) => {
       
   231     (for (pr1 <- pder(c, r1)) yield SEQ(pr1, r2)) ++
       
   232     (if (nullable(r1)) pder(c, r2) else Set())
       
   233   }
       
   234   case STAR(r1) => {
       
   235     for (pr1 <- pder(c, r1)) yield SEQ(pr1, STAR(r1))
       
   236   }
       
   237 }
       
   238 
       
   239 def pders(s: List[Char], rs: Set[Rexp]) : Set[Rexp] = s match {
       
   240   case Nil => rs
       
   241   case c::s => pders(s, rs.flatMap(pder(c, _)))
       
   242 }
       
   243 
       
   244 def pders1(s: String, r: Rexp) = pders(s.toList, Set(r))
       
   245 
       
   246