]> granicus.if.org Git - re2c/commitdiff
Don't use special regexp type for counted repetitions.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 15 Aug 2015 16:42:41 +0000 (17:42 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 15 Aug 2015 16:42:41 +0000 (17:42 +0100)
Counted repetitions are regexps of the form:
    r{n}
    r{n,m}
    r{n,}

They can be expressed in terms of concatenation, alternation and
iteration:
    r{0}      <empty regexp>
    r{n}      r{n-1} r
    r{n,m}    r{n} (r{0} | ... | r{m-n})
    r{n,}     r{n} r*

Reducing special regexp type to represent counted repetitions allows
us substitute complex code that compiles them to bytecode instructions
with simpler code that constructs counted repetitions using concatenation,
alternation and iteration.

re2c/Makefile.am
re2c/src/ir/bytecode/calc_size.cc
re2c/src/ir/bytecode/compile.cc
re2c/src/ir/bytecode/split.cc
re2c/src/ir/regexp/display.cc
re2c/src/ir/regexp/regexp.cc
re2c/src/ir/regexp/regexp.h
re2c/src/ir/regexp/regexp_closev.h [deleted file]
re2c/src/parse/parser.ypp

index 8cdcfb9bbaa9cce02e5da8219e056205852b5fa9..b8e77ef3e6b477a63ea84711bf749c2cb45c999b 100644 (file)
@@ -44,7 +44,6 @@ SRC_HDR = \
        src/ir/regexp/regexp_match.h \
        src/ir/regexp/regexp_rule.h \
        src/ir/regexp/regexp_cat.h \
-       src/ir/regexp/regexp_closev.h \
        src/ir/regexp/regexp_null.h \
        src/ir/regexp/regexp.h \
        src/ir/regexp/regexp_close.h \
index 4daeb7054ac2842d171d1a24b007e55e57b66c90..39861baf9975cac06b0dedb2035f286295a5bb82 100644 (file)
@@ -1,7 +1,6 @@
 #include "src/ir/regexp/regexp_alt.h"
 #include "src/ir/regexp/regexp_cat.h"
 #include "src/ir/regexp/regexp_close.h"
-#include "src/ir/regexp/regexp_closev.h"
 #include "src/ir/regexp/regexp_match.h"
 #include "src/ir/regexp/regexp_null.h"
 #include "src/ir/regexp/regexp_rule.h"
@@ -29,19 +28,6 @@ void CloseOp::calcSize (Char * rep)
        size = exp->size + 1;
 }
 
-void CloseVOp::calcSize (Char * rep)
-{
-       exp->calcSize (rep);
-       if (max >= 0)
-       {
-               size = (exp->size * min) + ((1 + exp->size) * (max - min));
-       }
-       else
-       {
-               size = (exp->size * min) + 1;
-       }
-}
-
 void MatchOp::calcSize (Char * rep)
 {
        size = 1;
index d67ebf9c51be7fc8eb6c3b09308e5b3390525e29..4fc0813d99fa205df4ab94c303c60bb763499455 100644 (file)
@@ -1,7 +1,6 @@
 #include "src/ir/regexp/regexp_alt.h"
 #include "src/ir/regexp/regexp_cat.h"
 #include "src/ir/regexp/regexp_close.h"
-#include "src/ir/regexp/regexp_closev.h"
 #include "src/ir/regexp/regexp_match.h"
 #include "src/ir/regexp/regexp_null.h"
 #include "src/ir/regexp/regexp_rule.h"
@@ -114,54 +113,6 @@ void CloseOp::decompile ()
        }
 }
 
-uint32_t CloseVOp::compile (Char * rep, Ins * i)
-{
-       if (ins_cache)
-       {
-               return compile_goto (ins_cache, i);
-       }
-       else
-       {
-               ins_cache = i;
-
-               for (int st = min; st < max; st++)
-               {
-                       const uint32_t sz = exp->compile (rep, &i[1]);
-                       i->i.tag = FORK;
-                       i->i.link = ins_cache + (1 + sz) * (max - min);
-                       i += sz + 1;
-               }
-               for (int st = 0; st < min; st++)
-               {
-                       const uint32_t sz = exp->compile (rep, &i[0]);
-                       i += sz;
-                       if (max < 0 && st == 0)
-                       {
-                               i->i.tag = FORK;
-                               i->i.link = i - sz;
-                               i++;
-                       }
-               }
-               const uint32_t sz = static_cast<uint32_t> (i - ins_cache);
-
-               if (ins_access == PRIVATE)
-               {
-                       decompile ();
-               }
-
-               return sz;
-       }
-}
-
-void CloseVOp::decompile ()
-{
-       if (ins_cache)
-       {
-               exp->decompile ();
-               ins_cache = NULL;
-       }
-}
-
 uint32_t MatchOp::compile (Char * rep, Ins * i)
 {
        if (ins_cache)
index 5300d45de1446b88701a665cf105ece6d451872b..4607150e892318b0455651eb085d330b72f8b286 100644 (file)
@@ -1,7 +1,6 @@
 #include "src/ir/regexp/regexp_alt.h"
 #include "src/ir/regexp/regexp_cat.h"
 #include "src/ir/regexp/regexp_close.h"
-#include "src/ir/regexp/regexp_closev.h"
 #include "src/ir/regexp/regexp_match.h"
 #include "src/ir/regexp/regexp_null.h"
 #include "src/ir/regexp/regexp_rule.h"
@@ -25,11 +24,6 @@ void CloseOp::split (CharSet & s)
        exp->split (s);
 }
 
-void CloseVOp::split (CharSet & s)
-{
-       exp->split (s);
-}
-
 void MatchOp::split (CharSet & s)
 {
        for (Range *r = match; r; r = r->next ())
index 1e12d3500ce382b56e98559157c02c40c918128e..d139dc53a5f250fcf832e5927ea4411c376084e2 100644 (file)
@@ -4,7 +4,6 @@
 #include "src/ir/regexp/regexp_alt.h"
 #include "src/ir/regexp/regexp_cat.h"
 #include "src/ir/regexp/regexp_close.h"
-#include "src/ir/regexp/regexp_closev.h"
 #include "src/ir/regexp/regexp_match.h"
 #include "src/ir/regexp/regexp_null.h"
 #include "src/ir/regexp/regexp_rule.h"
@@ -33,11 +32,6 @@ void CloseOp::display (std::ostream & o) const
        o << exp << "+";
 }
 
-void CloseVOp::display (std::ostream & o) const
-{
-       o << exp << "+";
-}
-
 void MatchOp::display (std::ostream & o) const
 {
        o << match;
index c99d5f2c503c40b1ad607865709d7a69d42cafd5..5476d3ce0ac5c4ce1fb5740b88e699e47ffdcffb 100644 (file)
@@ -4,6 +4,7 @@
 #include "src/ir/regexp/regexp.h"
 #include "src/ir/regexp/regexp_alt.h"
 #include "src/ir/regexp/regexp_cat.h"
+#include "src/ir/regexp/regexp_close.h"
 #include "src/ir/regexp/regexp_match.h"
 #include "src/ir/regexp/regexp_null.h"
 #include "src/parse/scanner.h"
@@ -284,4 +285,44 @@ RegExp * Scanner::mkDefault() const
        return new MatchOp(def);
 }
 
+/*
+ * note [counted repetition expansion]
+ *
+ * r{0} ;;= <empty regexp>
+ * r{n} ::= r{n-1} r
+ * r{n,m} ::= r{n} (r{0} | ... | r{m-n})
+ * r{n,} ::= r{n} r*
+ */
+
+// see note [counted repetition expansion]
+RegExp * repeat (RegExp * e, uint32_t n)
+{
+       RegExp * r = NULL;
+       for (uint32_t i = 0; i < n; ++i)
+       {
+               r = doCat (r, e);
+       }
+       return r;
+}
+
+// see note [counted repetition expansion]
+RegExp * repeat_from_to (RegExp * e, uint32_t n, uint32_t m)
+{
+       RegExp * r1 = repeat (e, n);
+       RegExp * r2 = NULL;
+       for (uint32_t i = n; i < m; ++i)
+       {
+               r2 = mkAlt (new NullOp, doCat (e, r2));
+       }
+       return doCat (r1, r2);
+}
+
+// see note [counted repetition expansion]
+RegExp * repeat_from (RegExp * e, uint32_t n)
+{
+       RegExp * r1 = repeat (e, n);
+       RegExp * r2 = mkAlt (new NullOp, new CloseOp (e));
+       return doCat (r1, r2);
+}
+
 } // namespace re2c
index a5323146a3f02b4a4d78c055ebe666194f8d0142..34d0763c2d50d72022f47b7d2690ad8551bf98d7 100644 (file)
@@ -69,6 +69,9 @@ public:
 RegExp * doAlt (RegExp * e1, RegExp * e2);
 RegExp * mkAlt (RegExp * e1, RegExp * e2);
 RegExp * doCat (RegExp * e1, RegExp * e2);
+RegExp * repeat (RegExp * e, uint32_t n);
+RegExp * repeat_from_to (RegExp * e, uint32_t n, uint32_t m);
+RegExp * repeat_from (RegExp * e, uint32_t n);
 
 } // end namespace re2c
 
diff --git a/re2c/src/ir/regexp/regexp_closev.h b/re2c/src/ir/regexp/regexp_closev.h
deleted file mode 100644 (file)
index 8cd054e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _RE2C_IR_REGEXP_REGEXP_CLOSEV_
-#define _RE2C_IR_REGEXP_REGEXP_CLOSEV_
-
-#include "src/ir/regexp/regexp.h"
-
-namespace re2c
-{
-
-class CloseVOp: public RegExp
-{
-       RegExp * exp;
-       int32_t min;
-       int32_t max;
-
-public:
-       inline CloseVOp (RegExp * e, int lb, int ub)
-               : exp (e)
-               , min (lb)
-               , max (ub)
-       {
-               exp->ins_access = PRIVATE;
-       }
-       void split (CharSet &);
-       void calcSize (Char *);
-       uint32_t compile (Char *, Ins *);
-       void decompile ();
-       void display (std::ostream & o) const;
-
-       FORBID_COPY (CloseVOp);
-};
-
-} // end namespace re2c
-
-#endif // _RE2C_IR_REGEXP_REGEXP_CLOSEV_
index 5dbfc78a3ffec5f5c66f5a0f04a3972e1c5e40dd..1c9ae042e98c0331953ef56c4fff9e8ef21e6e02 100644 (file)
@@ -12,7 +12,6 @@
 #include "src/ir/regexp/encoding/range_suffix.h"
 #include "src/ir/regexp/regexp_cat.h"
 #include "src/ir/regexp/regexp_close.h"
-#include "src/ir/regexp/regexp_closev.h"
 #include "src/ir/regexp/regexp_null.h"
 #include "src/codegen/emit.h" // genTypes
 #include "src/globals.h"
@@ -420,7 +419,20 @@ factor:
                }
        |       primary CLOSESIZE
                {
-                       $$ = new CloseVOp($1, $2.minsize, $2.maxsize);
+                       $1->ins_access = RegExp::PRIVATE;
+                       if ($2.maxsize < 0)
+                       {
+                               $$ = repeat_from ($1, $2.minsize);
+                       }
+                       else if ($2.minsize == $2.maxsize)
+                       {
+                               $$ = repeat ($1, $2.minsize);
+                       }
+                       else
+                       {
+                               $$ = repeat_from_to ($1, $2.minsize, $2.maxsize);
+                       }
+                       $$ = $$ ? $$ : new NullOp;
                }
 ;