--- 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
/*