progs/matcher/re3.sc
changeset 919 53f08d873e09
parent 882 5fcad75ade92
child 929 9541e073f2ed
equal deleted inserted replaced
918:53e7da9f372a 919:53f08d873e09
     1 // A version with simplification of derivatives;
     1 // A version of the matcher with simplification 
       
     2 // of derivatives
       
     3 //
     2 // this keeps the regular expressions small, which
     4 // this keeps the regular expressions small, which
     3 // is good for the run-time
     5 // is good for the run-time
     4 // 
     6 // 
     5 // call the test cases with X = {1,2}
     7 // call the test cases with X = {1,2}
     6 //
     8 //
    46   case STAR(r1) => SEQ(der(c, r1), STAR(r1))
    48   case STAR(r1) => SEQ(der(c, r1), STAR(r1))
    47   case NTIMES(r, i) => 
    49   case NTIMES(r, i) => 
    48     if (i == 0) ZERO else SEQ(der(c, r), NTIMES(r, i - 1))
    50     if (i == 0) ZERO else SEQ(der(c, r), NTIMES(r, i - 1))
    49 }
    51 }
    50 
    52 
       
    53 // simplification
    51 def simp(r: Rexp) : Rexp = r match {
    54 def simp(r: Rexp) : Rexp = r match {
    52   case ALT(r1, r2) => (simp(r1), simp(r2)) match {
    55   case ALT(r1, r2) => (simp(r1), simp(r2)) match {
    53     case (ZERO, r2s) => r2s
    56     case (ZERO, r2s) => r2s
    54     case (r1s, ZERO) => r1s
    57     case (r1s, ZERO) => r1s
    55     case (r1s, r2s) => if (r1s == r2s) r1s else ALT (r1s, r2s)
    58     case (r1s, r2s) => if (r1s == r2s) r1s else ALT (r1s, r2s)
    62     case (r1s, r2s) => SEQ(r1s, r2s)
    65     case (r1s, r2s) => SEQ(r1s, r2s)
    63   }
    66   }
    64   case r => r
    67   case r => r
    65 }
    68 }
    66 
    69 
    67 
       
    68 
       
    69 // the derivative w.r.t. a string (iterates der)
    70 // the derivative w.r.t. a string (iterates der)
    70 def ders(s: List[Char], r: Rexp) : Rexp = s match {
    71 def ders(s: List[Char], r: Rexp) : Rexp = s match {
    71   case Nil => r
    72   case Nil => r
    72   case c::s => ders(s, simp(der(c, r)))
    73   case c::s => ders(s, simp(der(c, r)))
    73 }
    74 }
    74 
    75 
    75 
       
    76 // the main matcher function
    76 // the main matcher function
    77 def matcher(r: Rexp, s: String) : Boolean = 
    77 def matcher(r: Rexp, s: String) : Boolean = 
    78   nullable(ders(s.toList, r))
    78   nullable(ders(s.toList, r))
    79 
    79 
    80 
    80 
       
    81 // Test Cases
       
    82 //============
       
    83 
    81 // one or zero
    84 // one or zero
    82 def OPT(r: Rexp) = ALT(r, ONE)
    85 def OPT(r: Rexp) = ALT(r, ONE)
    83 
       
    84 
       
    85 // Test Cases
       
    86 
    86 
    87 // evil regular expressions: (a?){n} a{n}  and (a*)* b
    87 // evil regular expressions: (a?){n} a{n}  and (a*)* b
    88 def EVIL1(n: Int) = SEQ(NTIMES(OPT(CHAR('a')), n), NTIMES(CHAR('a'), n))
    88 def EVIL1(n: Int) = SEQ(NTIMES(OPT(CHAR('a')), n), NTIMES(CHAR('a'), n))
    89 val EVIL2 = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))
    89 val EVIL2 = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))
    90 
    90