progs/re1.scala
changeset 477 b78664a24f5d
parent 471 9476086849ad
child 479 52aa298211f6
child 480 9e42ccbbd1e6
equal deleted inserted replaced
476:d922cc83b70c 477:b78664a24f5d
       
     1 // Simple matcher for basic regular expressions
       
     2 
     1 
     3 
     2 abstract class Rexp
     4 abstract class Rexp
     3 case object ZERO extends Rexp                    // matches nothing
     5 case object ZERO extends Rexp                    // matches nothing
     4 case object ONE extends Rexp                     // matches the empty string
     6 case object ONE extends Rexp                     // matches the empty string
     5 case class CHAR(c: Char) extends Rexp            // matches a character c
     7 case class CHAR(c: Char) extends Rexp            // matches a character c
    38 }
    40 }
    39 
    41 
    40 // main matcher function
    42 // main matcher function
    41 def matches(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
    43 def matches(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
    42 
    44 
       
    45 
    43 //examples from the homework
    46 //examples from the homework
       
    47 
    44 val r = STAR(ALT(SEQ(CHAR('a'), CHAR('b')), CHAR('b')))
    48 val r = STAR(ALT(SEQ(CHAR('a'), CHAR('b')), CHAR('b')))
    45 der('a', r)
    49 der('a', r)
    46 der('b', r)
    50 der('b', r)
    47 der('c', r)
    51 der('c', r)
    48 
    52 
    49 //optional (one or zero times)
    53 //optional regular expression (one or zero times)
    50 def OPT(r: Rexp) = ALT(r, ONE)
    54 def OPT(r: Rexp) = ALT(r, ONE)
    51 
    55 
    52 //n-times (explicitly expanded)
    56 //n-times regular expression (explicitly expanded)
    53 def NTIMES(r: Rexp, n: Int) : Rexp = n match {
    57 def NTIMES(r: Rexp, n: Int) : Rexp = n match {
    54   case 0 => ONE
    58   case 0 => ONE
    55   case 1 => r
    59   case 1 => r
    56   case n => SEQ(r, NTIMES(r, n - 1))
    60   case n => SEQ(r, NTIMES(r, n - 1))
    57 }
    61 }
       
    62 
       
    63 
       
    64 // Test Cases
    58 
    65 
    59 // the evil regular expression  a?{n} a{n}
    66 // the evil regular expression  a?{n} a{n}
    60 def EVIL1(n: Int) = SEQ(NTIMES(OPT(CHAR('a')), n), NTIMES(CHAR('a'), n))
    67 def EVIL1(n: Int) = SEQ(NTIMES(OPT(CHAR('a')), n), NTIMES(CHAR('a'), n))
    61 
    68 
    62 // the evil regular expression (a*)*b
    69 // the evil regular expression (a*)*b
    86 
    93 
    87 for (i <- 1 to 20) {
    94 for (i <- 1 to 20) {
    88   println(i + " " + "%.5f".format(time_needed(2, matches(EVIL2, "a" * i))))
    95   println(i + " " + "%.5f".format(time_needed(2, matches(EVIL2, "a" * i))))
    89 }
    96 }
    90 
    97 
       
    98 
       
    99 
       
   100 
       
   101 // size of a regular expressions - for testing purposes 
       
   102 def size(r: Rexp) : Int = r match {
       
   103   case ZERO => 1
       
   104   case ONE => 1
       
   105   case CHAR(_) => 1
       
   106   case ALT(r1, r2) => 1 + size(r1) + size(r2)
       
   107   case SEQ(r1, r2) => 1 + size(r1) + size(r2)
       
   108   case STAR(r) => 1 + size(r)
       
   109 }
       
   110 
       
   111 // the expicit expansion in EVIL1(n) increases
       
   112 // drastically its size
       
   113 
       
   114 size(EVIL1(1))  // 5
       
   115 size(EVIL1(3))  // 17
       
   116 size(EVIL1(5))  // 29
       
   117 size(EVIL1(7))  // 41