progs/re4.scala
changeset 121 43c116860e47
parent 93 4794759139ea
child 407 4b454a6d1814
equal deleted inserted replaced
120:3e71efb25ce9 121:43c116860e47
     1 import scala.annotation.tailrec    
     1 import scala.annotation.tailrec    
       
     2     
     2 abstract class Rexp {
     3 abstract class Rexp {
     3   def simp : Rexp = this
     4   def simp : Rexp = this
     4 }
     5 }
     5 
     6 
     6 case object NULL extends Rexp
     7 case object NULL extends Rexp
    10   override def simp = (r1.simp, r2.simp) match {
    11   override def simp = (r1.simp, r2.simp) match {
    11     case (NULL, r) => r
    12     case (NULL, r) => r
    12     case (r, NULL) => r
    13     case (r, NULL) => r
    13     case (r, EMPTY) => if (nullable(r)) r else ALT(r, EMPTY)
    14     case (r, EMPTY) => if (nullable(r)) r else ALT(r, EMPTY)
    14     case (EMPTY, r) => if (nullable(r)) r else ALT(r, EMPTY)
    15     case (EMPTY, r) => if (nullable(r)) r else ALT(r, EMPTY)
    15     case (r1, r2) => ALT(r1, r2)
    16     case (r1, r2) => if (r1 == r2) r1 else ALT(r1, r2)
    16   }
    17   }
    17 }
    18 }
    18 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp {
    19 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp {
    19   override def simp = (r1.simp, r2.simp) match {
    20   override def simp = (r1.simp, r2.simp) match {
    20     case (NULL, _) => NULL
    21     case (NULL, _) => NULL
    22     case (EMPTY, r) => r
    23     case (EMPTY, r) => r
    23     case (r, EMPTY) => r
    24     case (r, EMPTY) => r
    24     case (r1, r2) => SEQ(r1, r2)
    25     case (r1, r2) => SEQ(r1, r2)
    25   }
    26   }
    26 }
    27 }
    27 case class STAR(r: Rexp) extends Rexp 
    28 case class STAR(r: Rexp) extends Rexp {
    28 case class NTIMES(r: Rexp, n: Int) extends Rexp 
    29   override def simp = r.simp match {
       
    30     case NULL => EMPTY
       
    31     case EMPTY => EMPTY
       
    32     case r => STAR(r)
       
    33   }
       
    34 }
       
    35 case class NTIMES(r: Rexp, n: Int) extends Rexp {
       
    36   override def simp = if (n == 0) EMPTY else 
       
    37     r.simp match {
       
    38       case NULL => NULL
       
    39       case EMPTY => EMPTY
       
    40       case r => NTIMES(r, n)
       
    41     }
       
    42 }
    29 
    43 
    30 // some convenience for typing in regular expressions
    44 // some convenience for typing in regular expressions
    31 def charlist2rexp(s : List[Char]) : Rexp = s match {
    45 def charlist2rexp(s : List[Char]) : Rexp = s match {
    32   case Nil => EMPTY
    46   case Nil => EMPTY
    33   case c::Nil => CHAR(c)
    47   case c::Nil => CHAR(c)
    43   case EMPTY => true
    57   case EMPTY => true
    44   case CHAR(_) => false
    58   case CHAR(_) => false
    45   case ALT(r1, r2) => nullable(r1) || nullable(r2)
    59   case ALT(r1, r2) => nullable(r1) || nullable(r2)
    46   case SEQ(r1, r2) => nullable(r1) && nullable(r2)
    60   case SEQ(r1, r2) => nullable(r1) && nullable(r2)
    47   case STAR(_) => true
    61   case STAR(_) => true
    48   case NTIMES(r, i) => if (i == 0) false else nullable(r)
    62   case NTIMES(r, i) => if (i == 0) true else nullable(r)
    49 }
    63 }
    50 
    64 
    51 // derivative of a regular expression w.r.t. a character
    65 // derivative of a regular expression w.r.t. a character
    52 def der (c: Char, r: Rexp) : Rexp = r match {
    66 def der (c: Char, r: Rexp) : Rexp = r match {
    53   case NULL => NULL
    67   case NULL => NULL
    71 
    85 
    72 // main matcher function
    86 // main matcher function
    73 def matcher(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
    87 def matcher(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
    74 
    88 
    75 
    89 
    76 
       
    77 //one or zero
    90 //one or zero
    78 def OPT(r: Rexp) = ALT(r, EMPTY)
    91 def OPT(r: Rexp) = ALT(r, EMPTY)
    79 
    92 
    80 //n-times
    93 def EVIL(n: Int) = SEQ(NTIMES(OPT("a"), n), NTIMES("a", n))
    81 /*def NTIMES(r: Rexp, n: Int) : Rexp = n match {
       
    82   case 0 => NULL
       
    83   case 1 => r
       
    84   case n => SEQ(r, NTIMES(r, n - 1))
       
    85 }*/
       
    86 
       
    87 def RTEST(n: Int) = SEQ(NTIMES(OPT("a"), n), NTIMES("a", n))
       
    88 
    94 
    89 def time_needed[T](i: Int, code: => T) = {
    95 def time_needed[T](i: Int, code: => T) = {
    90   val start = System.nanoTime()
    96   val start = System.nanoTime()
    91   for (j <- 1 to i) code
    97   for (j <- 1 to i) code
    92   val end = System.nanoTime()
    98   val end = System.nanoTime()
    93   (end - start)/(i * 1.0e9)
    99   (end - start)/(i * 1.0e9)
    94 }
   100 }
    95 
   101 
    96 
   102 
    97 for (i <- 1 to 13001 by 500) {
   103 for (i <- 1 to 12001 by 500) {
    98   println(i + " " + time_needed(1, matcher(RTEST(i), "a" * i)))
   104   println(i + " " + "%.5f".format(time_needed(1, matcher(EVIL(i), "a" * i))))
    99 }
   105 }
   100 
   106 
   101 
   107