progs/re3a.scala
changeset 623 47a299e7010f
parent 519 955d5b3b0619
equal deleted inserted replaced
622:b47e140bcccd 623:47a299e7010f
     7 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp 
     7 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp 
     8 case class STAR(r: Rexp) extends Rexp 
     8 case class STAR(r: Rexp) extends Rexp 
     9 case class NTIMES(r: Rexp, n: Int) extends Rexp 
     9 case class NTIMES(r: Rexp, n: Int) extends Rexp 
    10 case class UPNTIMES(r: Rexp, n: Int) extends Rexp 
    10 case class UPNTIMES(r: Rexp, n: Int) extends Rexp 
    11 
    11 
    12 // nullable function: tests whether the regular 
    12 // the nullable function: tests whether the regular 
    13 // expression can recognise the empty string
    13 // expression can recognise the empty string
    14 def nullable (r: Rexp) : Boolean = r match {
    14 def nullable (r: Rexp) : Boolean = r match {
    15   case ZERO => false
    15   case ZERO => false
    16   case ONE => true
    16   case ONE => true
    17   case CHAR(_) => false
    17   case CHAR(_) => false
    20   case STAR(_) => true
    20   case STAR(_) => true
    21   case NTIMES(r, i) => if (i == 0) true else nullable(r)
    21   case NTIMES(r, i) => if (i == 0) true else nullable(r)
    22   case UPNTIMES(r: Rexp, n: Int) => true
    22   case UPNTIMES(r: Rexp, n: Int) => true
    23 }
    23 }
    24 
    24 
    25 // derivative of a regular expression w.r.t. a character
    25 // the derivative of a regular expression w.r.t. a character
    26 def der (c: Char, r: Rexp) : Rexp = r match {
    26 def der (c: Char, r: Rexp) : Rexp = r match {
    27   case ZERO => ZERO
    27   case ZERO => ZERO
    28   case ONE => ZERO
    28   case ONE => ZERO
    29   case CHAR(d) => if (c == d) ONE else ZERO
    29   case CHAR(d) => if (c == d) ONE else ZERO
    30   case ALT(r1, r2) => ALT(der(c, r1), der(c, r2))
    30   case ALT(r1, r2) => ALT(der(c, r1), der(c, r2))
    56   }
    56   }
    57   case r => r
    57   case r => r
    58 }
    58 }
    59 
    59 
    60 
    60 
    61 // derivative w.r.t. a string (iterates der)
    61 // the derivative w.r.t. a string (iterates der)
    62 def ders (s: List[Char], r: Rexp) : Rexp = s match {
    62 def ders (s: List[Char], r: Rexp) : Rexp = s match {
    63   case Nil => r
    63   case Nil => r
    64   case c::s => ders(s, simp(der(c, r)))
    64   case c::s => ders(s, simp(der(c, r)))
    65 }
    65 }
    66 
    66 
    67 
    67 
    68 // main matcher function
    68 // the main matcher function
    69 def matcher(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
    69 def matches(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
    70 
    70 
    71 //one or zero
    71 // one or zero
    72 def OPT(r: Rexp) = ALT(r, ONE)
    72 def OPT(r: Rexp) = ALT(r, ONE)
    73 
    73 
    74 //evil regular expressions
    74 // evil regular expressions
    75 def EVIL1(n: Int) = SEQ(NTIMES(OPT(CHAR('a')), n), NTIMES(CHAR('a'), n))
    75 def EVIL1(n: Int) = SEQ(NTIMES(OPT(CHAR('a')), n), NTIMES(CHAR('a'), n))
    76 val EVIL2 = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))
    76 val EVIL2 = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))
    77 val EVIL3 = SEQ(STAR(ALT(CHAR('a'), SEQ(CHAR('a'),CHAR('a')))), CHAR('b'))
    77 val EVIL3 = SEQ(STAR(ALT(CHAR('a'), SEQ(CHAR('a'),CHAR('a')))), CHAR('b'))
    78 
    78 
    79 def time_needed[T](i: Int, code: => T) = {
    79 def time_needed[T](i: Int, code: => T) = {
    80   val start = System.nanoTime()
    80   val start = System.nanoTime()
    81   for (j <- 1 to i) code
    81   for (j <- 1 to i) code
    82   val end = System.nanoTime()
    82   val end = System.nanoTime()
    83   (end - start)/(i * 1.0e9)
    83   "%.5f".format((end - start) / (i * 1.0e9))
    84 }
    84 }
    85 
    85 
    86 
    86 
    87 //test: (a?{n}) (a{n})
    87 // test: (a?{n}) (a{n})
    88 for (i <- 1 to 8001 by 1000) {
    88 for (i <- 0 to 8000 by 1000) {
    89   println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL1(i), "a" * i))))
    89   println(s"$i: ${time_needed(2, matches(EVIL1(i), "a" * i))}")
    90 }
    90 }
    91 
    91 
    92 for (i <- 1 to 8001 by 1000) {
    92 // test: (a*)* b
    93   println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL1(i), "a" * i))))
    93 for (i <- 0 to 6000000 by 500000) {
    94 }
    94   println(s"$i: ${time_needed(2, matches(EVIL2, "a" * i))}")
    95 
       
    96 //test: (a*)* b
       
    97 for (i <- 1 to 6000001 by 500000) {
       
    98   println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL2, "a" * i))))
       
    99 }
       
   100 
       
   101 for (i <- 1 to 6000001 by 500000) {
       
   102   println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL2, "a" * i))))
       
   103 }
    95 }
   104 
    96 
   105 
    97 
   106 val r0 = simp(der('a', EVIL3))
    98 val r0 = simp(der('a', EVIL3))
   107 val r1 = simp(der('a', r0))
    99 val r1 = simp(der('a', r0))
   111 val r5 = simp(der('a', r4))
   103 val r5 = simp(der('a', r4))
   112 val r6 = simp(der('a', r5))
   104 val r6 = simp(der('a', r5))
   113 
   105 
   114 //test: (a|aa)* b
   106 //test: (a|aa)* b
   115 /*
   107 /*
   116 for (i <- 1 to 7001 by 500) {
   108 for (i <- 0 to 100 by 10) {
   117   println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL3, "a" * i ++ "c"))))
   109   println(s"$i: ${time_needed(2, matches(EVIL3, "a" * i ++ "c"))}")
   118 }
   110 }
   119  */
   111  */
   120 
   112