lex_blex_Frankensteined.scala
changeset 107 b1e365afa29c
parent 93 d486c12deeab
child 109 79f347cb8b4d
--- a/lex_blex_Frankensteined.scala	Wed Jan 15 13:01:10 2020 +0000
+++ b/lex_blex_Frankensteined.scala	Thu Jan 16 22:34:23 2020 +0000
@@ -402,14 +402,38 @@
       else ASEQ(bs, bder(c, r1), r2)
     case ASTAR(bs, r) => ASEQ(bs, fuse(List(S), bder(c, r)), ASTAR(Nil, r))
   }
-
+  def bder_rf(c: Char, r: ARexp) : ARexp = r match {
+    case AZERO => AZERO
+    case AONE(_) => AZERO
+    case ACHAR(bs, f) => if (c == f) AONE(bs) else AZERO
+    case AALTS(bs, rs) => AALTS(bs, rs.map(bder_rf(c, _)))
+    case ASEQ(bs, r1, r2) =>
+      if (bnullable(r1)) AALT(bs, ASEQ(Nil, bder_rf(c, r1), r2), fuse(mkepsBC(r1), bder_rf(c, r2)))
+      else ASEQ(bs, bder_rf(c, r1), r2)
+    case ASTAR(bs, r) => ASEQ(bs, fuse(List(S), bder_rf(c, r)), ASTAR(Nil, r))
+  }
   // derivative w.r.t. a string (iterates bder)
   @tailrec
   def bders (s: List[Char], r: ARexp) : ARexp = s match {
     case Nil => r
     case c::s => bders(s, bder(c, r))
   }
-
+  
+  def bders_rf(s: List[Char], r: ARexp) : ARexp = s match {
+    case Nil => r
+    case c::s => bders_rf(s, bder_rf(c, r))
+  }
+  def all_zero_except_alt(rs: List[ARexp], a: ARexp): ARexp = rs match{
+    case Nil => a
+    case AZERO :: rs1 => all_zero_except_alt(rs1, a)
+    case AALTS(bs, rs1) :: rs2 => {
+      if (a == AZERO)
+        all_zero_except_alt(rs2, AALTS(bs, rs1))
+      else
+        AZERO
+    }
+    case r1 :: rs2 => AZERO
+  }
   def flats(rs: List[ARexp]): List[ARexp] = rs match {
       case Nil => Nil
       case AZERO :: rs1 => flats(rs1)
@@ -481,6 +505,35 @@
     //case ASTAR(bs, r) => ASTAR(bs, bsimp(r))
     case r => r
   }
+  //minimise fuse operation if possible
+  def bsimp_rf(r: ARexp):ARexp = r match {
+     case ASEQ(bs1, r1, r2) => (bsimp_rf(r1), bsimp_rf(r2)) match {
+        case (AZERO, _) => AZERO
+        case (_, AZERO) => AZERO
+        case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s)
+        case (r1s, r2s) => ASEQ(bs1, r1s, r2s)
+    }
+    case AALTS(bs1, rs) => {
+      //after map simp, before flats, check if all others simplify to 0s, if yes, do not fuse
+      val rs_simp = rs.map(bsimp_rf)
+      //prevent fuse from happening
+      val fuse_alts = all_zero_except_alt(rs_simp, AZERO)//returns AZERO if not the case, return AALTS if yes
+      if(fuse_alts == AZERO){
+        val flat_res = flats(rs_simp)
+        val dist_res = distinctBy(flat_res, erase)
+        dist_res match {
+          case Nil => AZERO
+          case r :: Nil => fuse(bs1, r)
+          case rs => AALTS(bs1, rs)  
+        }
+      }
+      else{
+        fuse(bs1, fuse_alts)
+      }
+    }
+    //case ASTAR(bs, r) => ASTAR(bs, bsimp(r))
+    case r => r   
+  }
   //only print at the top level
 
   def find_pos(v: Val, rs: List[ARexp]): Int = (v, rs) match{
@@ -651,6 +704,11 @@
     case Nil => r
     case c::s => bders_simp(s, bsimp(bder(c, r)))
   }
+  def bders_simp_rf (s: List[Char], r: ARexp) : ARexp = s match {
+    case Nil => r
+    case c::s => bders_simp_rf(s, bsimp_rf(bder(c, r)))
+  }
+  
   //----------------------------------------------------------------------------experiment bsimp
   /*