JAL-1807 still testing
[jalviewjs.git] / unused / com / stevesoft / pat / parsePerl.java
index 4b8a93f..ab43a94 100644 (file)
-//
-// This software is now distributed according to
-// the Lesser Gnu Public License.  Please see
-// http://www.gnu.org/copyleft/lesser.txt for
-// the details.
-//    -- Happy Computing!
-//
-package com.stevesoft.pat;
-
-/**
- * This class provides a method for parsing the "s/.../.../" constructs of
- * Regex.perlCode.
- * 
- * @see Regex#perlCode
- */
-class parsePerl
-{
-  final static char close(char c)
-  {
-    // This switch statement does not behave
-    // properly when compiled with jdk1.1.5
-    // and the -O flag.
-    /*
-     * switch(c) { case '[': return ']'; case '(': return ')'; case '{': return
-     * '}'; } return c;
-     */
-    if (c == '<')
-    {
-      return '>';
-    }
-    if (c == '[')
-    {
-      return ']';
-    }
-    if (c == '(')
-    {
-      return ')';
-    }
-    if (c == '{')
-    {
-      return '}';
-    }
-    return c;
-  }
-
-  final public static String codify(String s, boolean keepbs)
-  {
-    return codify(s, 0, s.length(), keepbs);
-  }
-
-  final public static String codify(String s, int i0, int iN, boolean keepbs)
-  {
-    javajs.util.SB sb = new javajs.util.SB();
-    boolean ucmode = false, lcmode = false, litmode = false;
-    boolean uc1 = false, lc1 = false;
-    boolean modified = false;
-    for (int i = i0; i < iN; i++)
-    {
-      char c = s.charAt(i);
-      boolean mf = true, app = true;
-      if (c == '\\')
-      {
-        app = false;
-        i++;
-        if (i < s.length())
-        {
-          char c2 = s.charAt(i);
-          switch (c2)
-          {
-          case 'Q':
-            litmode = true;
-            break;
-          case 'U':
-            ucmode = true;
-            break;
-          case 'L':
-            lcmode = true;
-            break;
-          case 'u':
-            uc1 = true;
-            break;
-          case 'l':
-            lc1 = true;
-            break;
-          case 'E':
-            uc1 = lc1 = ucmode = lcmode = litmode = false;
-            break;
-          default:
-            if (keepbs)
-            {
-              sb.appendC('\\');
-            }
-            c = c2;
-            if (keepbs)
-            {
-              mf = false;
-            }
-            app = true;
-            break;
-          }
-          modified |= mf;
-        }
-      }
-      if (app)
-      {
-        if (lc1)
-        {
-          c = lc(c);
-          lc1 = false;
-        }
-        else if (uc1)
-        {
-          c = uc(c);
-          uc1 = false;
-        }
-        else if (ucmode)
-        {
-          c = uc(c);
-        }
-        else if (lcmode)
-        {
-          c = lc(c);
-        }
-        if (litmode && needbs(c))
-        {
-          sb.appendC('\\');
-        }
-        sb.appendC(c);
-      }
-    }
-    return modified ? sb.toString() : s;
-  }
-
-  final static char uc(char c)
-  {
-    return CaseMgr.toUpperCase(c);
-  }
-
-  final static char lc(char c)
-  {
-    return CaseMgr.toLowerCase(c);
-  }
-
-  final static boolean needbs(char c)
-  {
-    if (c >= 'a' && c <= 'z')
-    {
-      return false;
-    }
-    if (c >= 'A' && c <= 'Z')
-    {
-      return false;
-    }
-    if (c >= '0' && c <= '9')
-    {
-      return false;
-    }
-    if (c == '_')
-    {
-      return false;
-    }
-    return true;
-  }
-
-  final static Regex parse(String s)
-  {
-    boolean igncase = false, optim = false, gFlag = false;
-    boolean sFlag = false, mFlag = false, xFlag = false;
-
-    javajs.util.SB s1 = new javajs.util.SB();
-    javajs.util.SB s2 = new javajs.util.SB();
-    int i = 0, count = 0;
-    char mode, delim = '/', cdelim = '/';
-    if (s.length() >= 3 && s.charAt(0) == 's')
-    {
-      mode = 's';
-      delim = s.charAt(1);
-      cdelim = close(delim);
-      i = 2;
-    }
-    else if (s.length() >= 2 && s.charAt(0) == 'm')
-    {
-      mode = 'm';
-      delim = s.charAt(1);
-      cdelim = close(delim);
-      i = 2;
-    }
-    else if (s.length() >= 1 && s.charAt(0) == '/')
-    {
-      mode = 'm';
-      i = 1;
-    }
-    else
-    {
-      try
-      {
-        RegSyntaxError.endItAll("Regex.perlCode should be of the "
-                + "form s/// or m// or //");
-      } catch (RegSyntax rs)
-      {
-      }
-      return null;
-    }
-    for (; i < s.length(); i++)
-    {
-      if (s.charAt(i) == '\\')
-      {
-        s1.appendC('\\');
-        i++;
-      }
-      else if (s.charAt(i) == cdelim && count == 0)
-      {
-        i++;
-        break;
-      }
-      else if (s.charAt(i) == delim && cdelim != delim)
-      {
-        count++;
-      }
-      else if (s.charAt(i) == cdelim && cdelim != delim)
-      {
-        count--;
-      }
-      s1.appendC(s.charAt(i));
-    }
-    if (mode == 's' && cdelim != delim)
-    {
-      while (i < s.length() && Prop.isWhite(s.charAt(i)))
-      {
-        i++;
-      }
-      if (i >= s.length())
-      {
-        try
-        {
-          RegSyntaxError.endItAll("" + mode + delim + " needs " + cdelim);
-        } catch (RegSyntax rs)
-        {
-        }
-        return null;
-      }
-      cdelim = close(delim = s.charAt(i));
-      i++;
-    }
-    count = 0;
-    if (mode == 's')
-    {
-      for (; i < s.length(); i++)
-      {
-        if (s.charAt(i) == '\\')
-        {
-          s2.appendC('\\');
-          i++;
-        }
-        else if (s.charAt(i) == cdelim && count == 0)
-        {
-          i++;
-          break;
-        }
-        else if (s.charAt(i) == delim && cdelim != delim)
-        {
-          count++;
-        }
-        else if (s.charAt(i) == cdelim && cdelim != delim)
-        {
-          count--;
-        }
-        s2.appendC(s.charAt(i));
-      }
-    }
-    for (; i < s.length(); i++)
-    {
-      char c = s.charAt(i);
-      switch (c)
-      {
-      case 'x':
-        xFlag = true;
-        break;
-      case 'i':
-        igncase = true;
-        break;
-      case 'o':
-        optim = true;
-        break;
-      case 's':
-        sFlag = true;
-        break;
-      case 'm':
-        mFlag = true;
-        break;
-      case 'g':
-        gFlag = true;
-        break;
-      default:
-
-        // syntax error!
-        try
-        {
-          RegSyntaxError.endItAll("Illegal flag to pattern: " + c);
-        } catch (RegSyntax rs)
-        {
-        }
-        return null;
-      }
-    }
-    Regex r = new Regex();
-    try
-    {
-      String pat = s1.toString(), reprul = s2.toString();
-      if (xFlag)
-      {
-        pat = strip(pat);
-        reprul = strip(reprul);
-      }
-      r.compile(pat);
-      r.ignoreCase |= igncase;
-      r.gFlag |= gFlag;
-      r.sFlag |= sFlag;
-      r.mFlag |= mFlag;
-      if (optim)
-      {
-        r.optimize();
-      }
-      if (delim == '\'')
-      {
-        r.setReplaceRule(new StringRule(reprul));
-      }
-      else
-      {
-        r.setReplaceRule(parsePerl.perlCode(reprul));
-      }
-    } catch (RegSyntax rs)
-    {
-      r = null;
-    }
-    return r;
-  }
-
-  static String strip(String s)
-  {
-    javajs.util.SB sb = new javajs.util.SB();
-    for (int i = 0; i < s.length(); i++)
-    {
-      char c = s.charAt(i);
-      if (Prop.isWhite(c))
-      {
-        ;
-      }
-      else if (c == '#')
-      {
-        i++;
-        while (i < s.length())
-        {
-          if (s.charAt(i) == '\n')
-          {
-            break;
-          }
-          i++;
-        }
-      }
-      else if (c == '\\')
-      {
-        sb.appendC(c);
-        sb.appendC(s.charAt(++i));
-      }
-      else
-      {
-        sb.appendC(c);
-      }
-    }
-    return sb.toString();
-  }
-
-       /**
-        * Compile a ReplaceRule using the text that would go between the second and
-        * third /'s in a typical substitution pattern in Perl: s/ ... / <i>The
-        * argument to ReplaceRule.perlCode</i> /.
-        */
-       public static ReplaceRule perlCode(String s)
-       {
-         // String sav_backGs = Regex.backGs;
-         // int sav_backGto = Regex.backGto;
-         try
-         {
-           int mf = 0, mt = 0;
-           Regex gv = ReplaceRule.getv();
-           ReplaceRule head = null;
-           Object tmp = null;
-           while (gv.searchFrom(s, mt))
-           {
-             int off = Regex.BackRefOffset - 1;
-             mf = gv.matchedFrom();
-             if (mf > mt)
-             {
-               head = ReplaceRule.add(head, new StringRule(s.substring(mt, mf)));
-             }
-             String var = null;
-             if ((var = gv.stringMatched(1 + off)) != null
-                     || (var = gv.stringMatched(2 + off)) != null
-                     || (var = gv.stringMatched(5 + off)) != null)
-             {
-               int d = 0;
-               for (int i = 0; i < var.length(); i++)
-               {
-                 d = 8 * d + (var.charAt(i) - '0');
-               }
-               if (var.length() == 1)
-               {
-                 head = ReplaceRule.add(head, new BackRefRule(d));
-               }
-               else
-               {
-                 head = new StringRule("" + (char) d);
-               }
-             }
-             else if ((var = gv.stringMatched(10 + off)) != null)
-             {
-               if ("QELlUu".indexOf(var) >= 0)
-               {
-                 head = ReplaceRule.add(head, new CodeRule(var.charAt(0)));
-               }
-               else
-               {
-                 head = ReplaceRule.add(head, new StringRule(var));
-               }
-             }
-             else if ((var = gv.stringMatched(3 + off)) != null
-                     || (var = gv.stringMatched(4 + off)) != null
-                     || (var = gv.stringMatched(6 + off)) != null)
-             {
-               String arg = "";
-               int pc;
-               if ((pc = var.indexOf(':')) > 0)
-               {
-                 arg = var.substring(pc + 1);
-                 var = var.substring(0, pc);
-               }
-               if (var.equals("&") || var.equals("MATCH"))
-               {
-                 head = ReplaceRule.add(head, new AmpersandRule());
-               }
-               else if (var.equals("`") || var.equals("PREMATCH"))
-               {
-                 head = ReplaceRule.add(head, new LeftRule());
-               }
-               else if (var.equals("'") || var.equals("POSTMATCH"))
-               {
-                 head = ReplaceRule.add(head, new RightRule());
-               }
-               else if (var.equals("WANT_MORE_TEXT"))
-               {
-                 head = ReplaceRule.add(head, new WantMoreTextReplaceRule());
-               }
-               else if (var.equals("POP"))
-               {
-                 head = ReplaceRule.add(head, new PopRule());
-               }
-               else if (var.startsWith("+")
-                       && (tmp = ReplaceRule.defs.get(var.substring(1))) != null)
-               {
-                 if (tmp instanceof Regex)
-                 {
-                   head = ReplaceRule.add(head, new PushRule(var.substring(1), (Regex) tmp));
-                 }
-                 else if (tmp instanceof Transformer)
-                 {
-                   head = ReplaceRule.add(head, new PushRule(var.substring(1),
-                           (Transformer) tmp));
-                 }
-                 else
-                 {
-                   head = ReplaceRule.add(head, new StringRule("${" + var + "}"));
-                 }
-               }
-               else if (var.startsWith("=")
-                       && (tmp = ReplaceRule.defs.get(var.substring(1))) != null)
-               {
-                 if (tmp instanceof Regex)
-                 {
-                   head = ReplaceRule.add(head,
-                           new ChangeRule(var.substring(1), (Regex) tmp));
-                 }
-                 else if (tmp instanceof Transformer)
-                 {
-                   head = ReplaceRule.add(head, new ChangeRule(var.substring(1),
-                           (Transformer) tmp));
-                 }
-                 else
-                 {
-                   head = ReplaceRule.add(head, new StringRule("${" + var + "}"));
-                 }
-               }
-               else if ((tmp = ReplaceRule.defs.get(var)) != null)
-               {
-                 if (tmp instanceof ReplaceRule)
-                 {
-                   ReplaceRule alt = ((ReplaceRule) tmp).arg(arg);
-                   if (alt == null)
-                   {
-                     alt = ((ReplaceRule) tmp);
-                   }
-                   head = ReplaceRule.add(head, (ReplaceRule) (alt.clone()));
-                 }
-               }
-               else
-               // can't figure out how to transform this thing...
-               {
-                 head = ReplaceRule.add(head, new StringRule("${" + var + "}"));
-               }
-             }
-             else if ((var = gv.stringMatched(7 + off)) != null)
-             {
-               char c = var.charAt(0);
-               if (c == 'n')
-               {
-                 head = ReplaceRule.add(head, new StringRule("\n"));
-               }
-               else if (c == 't')
-               {
-                 head = ReplaceRule.add(head, new StringRule("\t"));
-               }
-               else if (c == 'r')
-               {
-                 head = ReplaceRule.add(head, new StringRule("\r"));
-               }
-               else if (c == 'b')
-               {
-                 head = ReplaceRule.add(head, new StringRule("\r"));
-               }
-               else if (c == 'a')
-               {
-                 head = ReplaceRule.add(head, new StringRule("" + (char) 7));
-               }
-               else if (c == 'e')
-               {
-                 head = ReplaceRule.add(head, new StringRule("" + (char) 27));
-               }
-               else if (c == 'f')
-               {
-                 head = ReplaceRule.add(head, new StringRule("" + (char) 12));
-               }
-             }
-             else if ((var = gv.stringMatched(8 + off)) != null)
-             {
-               char c = var.charAt(0);
-               if (c < Ctrl.cmap.length)
-               {
-                 c = Ctrl.cmap[c];
-               }
-               head = ReplaceRule.add(head, new StringRule("" + c));
-             }
-             else if ((var = gv.stringMatched(9 + off)) != null)
-             {
-               int d = 16 * ReplaceRule.getHexDigit(var.charAt(0))
-                       + ReplaceRule.getHexDigit(var.charAt(1));
-               head = ReplaceRule.add(head, new StringRule("" + (char) d));
-             }
-             mt = gv.matchedTo();
-           }
-           if (mt <= s.length())
-           {
-             head = ReplaceRule.add(head, new StringRule(s.substring(mt)));
-           }
-           return head;
-         } finally
-         {
-           // Regex.backGs = sav_backGs;
-           // Regex.backGto = sav_backGto;
-         }
-       }
-}
+//\r
+// This software is now distributed according to\r
+// the Lesser Gnu Public License.  Please see\r
+// http://www.gnu.org/copyleft/lesser.txt for\r
+// the details.\r
+//    -- Happy Computing!\r
+//\r
+package com.stevesoft.pat;\r
+\r
+/**\r
+ * This class provides a method for parsing the "s/.../.../" constructs of\r
+ * Regex.perlCode.\r
+ * \r
+ * @see Regex#perlCode\r
+ */\r
+class parsePerl\r
+{\r
+  final static char close(char c)\r
+  {\r
+    // This switch statement does not behave\r
+    // properly when compiled with jdk1.1.5\r
+    // and the -O flag.\r
+    /*\r
+     * switch(c) { case '[': return ']'; case '(': return ')'; case '{': return\r
+     * '}'; } return c;\r
+     */\r
+    if (c == '<')\r
+    {\r
+      return '>';\r
+    }\r
+    if (c == '[')\r
+    {\r
+      return ']';\r
+    }\r
+    if (c == '(')\r
+    {\r
+      return ')';\r
+    }\r
+    if (c == '{')\r
+    {\r
+      return '}';\r
+    }\r
+    return c;\r
+  }\r
+\r
+  final public static String codify(String s, boolean keepbs)\r
+  {\r
+    return codify(s, 0, s.length(), keepbs);\r
+  }\r
+\r
+  final public static String codify(String s, int i0, int iN, boolean keepbs)\r
+  {\r
+    javajs.util.SB sb = new javajs.util.SB();\r
+    boolean ucmode = false, lcmode = false, litmode = false;\r
+    boolean uc1 = false, lc1 = false;\r
+    boolean modified = false;\r
+    for (int i = i0; i < iN; i++)\r
+    {\r
+      char c = s.charAt(i);\r
+      boolean mf = true, app = true;\r
+      if (c == '\\')\r
+      {\r
+        app = false;\r
+        i++;\r
+        if (i < s.length())\r
+        {\r
+          char c2 = s.charAt(i);\r
+          switch (c2)\r
+          {\r
+          case 'Q':\r
+            litmode = true;\r
+            break;\r
+          case 'U':\r
+            ucmode = true;\r
+            break;\r
+          case 'L':\r
+            lcmode = true;\r
+            break;\r
+          case 'u':\r
+            uc1 = true;\r
+            break;\r
+          case 'l':\r
+            lc1 = true;\r
+            break;\r
+          case 'E':\r
+            uc1 = lc1 = ucmode = lcmode = litmode = false;\r
+            break;\r
+          default:\r
+            if (keepbs)\r
+            {\r
+              sb.appendC('\\');\r
+            }\r
+            c = c2;\r
+            if (keepbs)\r
+            {\r
+              mf = false;\r
+            }\r
+            app = true;\r
+            break;\r
+          }\r
+          modified |= mf;\r
+        }\r
+      }\r
+      if (app)\r
+      {\r
+        if (lc1)\r
+        {\r
+          c = lc(c);\r
+          lc1 = false;\r
+        }\r
+        else if (uc1)\r
+        {\r
+          c = uc(c);\r
+          uc1 = false;\r
+        }\r
+        else if (ucmode)\r
+        {\r
+          c = uc(c);\r
+        }\r
+        else if (lcmode)\r
+        {\r
+          c = lc(c);\r
+        }\r
+        if (litmode && needbs(c))\r
+        {\r
+          sb.appendC('\\');\r
+        }\r
+        sb.appendC(c);\r
+      }\r
+    }\r
+    return modified ? sb.toString() : s;\r
+  }\r
+\r
+  final static char uc(char c)\r
+  {\r
+    return CaseMgr.toUpperCase(c);\r
+  }\r
+\r
+  final static char lc(char c)\r
+  {\r
+    return CaseMgr.toLowerCase(c);\r
+  }\r
+\r
+  final static boolean needbs(char c)\r
+  {\r
+    if (c >= 'a' && c <= 'z')\r
+    {\r
+      return false;\r
+    }\r
+    if (c >= 'A' && c <= 'Z')\r
+    {\r
+      return false;\r
+    }\r
+    if (c >= '0' && c <= '9')\r
+    {\r
+      return false;\r
+    }\r
+    if (c == '_')\r
+    {\r
+      return false;\r
+    }\r
+    return true;\r
+  }\r
+\r
+  final static Regex parse(String s)\r
+  {\r
+    boolean igncase = false, optim = false, gFlag = false;\r
+    boolean sFlag = false, mFlag = false, xFlag = false;\r
+\r
+    javajs.util.SB s1 = new javajs.util.SB();\r
+    javajs.util.SB s2 = new javajs.util.SB();\r
+    int i = 0, count = 0;\r
+    char mode, delim = '/', cdelim = '/';\r
+    if (s.length() >= 3 && s.charAt(0) == 's')\r
+    {\r
+      mode = 's';\r
+      delim = s.charAt(1);\r
+      cdelim = close(delim);\r
+      i = 2;\r
+    }\r
+    else if (s.length() >= 2 && s.charAt(0) == 'm')\r
+    {\r
+      mode = 'm';\r
+      delim = s.charAt(1);\r
+      cdelim = close(delim);\r
+      i = 2;\r
+    }\r
+    else if (s.length() >= 1 && s.charAt(0) == '/')\r
+    {\r
+      mode = 'm';\r
+      i = 1;\r
+    }\r
+    else\r
+    {\r
+      try\r
+      {\r
+        RegSyntaxError.endItAll("Regex.perlCode should be of the "\r
+                + "form s/// or m// or //");\r
+      } catch (RegSyntax rs)\r
+      {\r
+      }\r
+      return null;\r
+    }\r
+    for (; i < s.length(); i++)\r
+    {\r
+      if (s.charAt(i) == '\\')\r
+      {\r
+        s1.appendC('\\');\r
+        i++;\r
+      }\r
+      else if (s.charAt(i) == cdelim && count == 0)\r
+      {\r
+        i++;\r
+        break;\r
+      }\r
+      else if (s.charAt(i) == delim && cdelim != delim)\r
+      {\r
+        count++;\r
+      }\r
+      else if (s.charAt(i) == cdelim && cdelim != delim)\r
+      {\r
+        count--;\r
+      }\r
+      s1.appendC(s.charAt(i));\r
+    }\r
+    if (mode == 's' && cdelim != delim)\r
+    {\r
+      while (i < s.length() && Prop.isWhite(s.charAt(i)))\r
+      {\r
+        i++;\r
+      }\r
+      if (i >= s.length())\r
+      {\r
+        try\r
+        {\r
+          RegSyntaxError.endItAll("" + mode + delim + " needs " + cdelim);\r
+        } catch (RegSyntax rs)\r
+        {\r
+        }\r
+        return null;\r
+      }\r
+      cdelim = close(delim = s.charAt(i));\r
+      i++;\r
+    }\r
+    count = 0;\r
+    if (mode == 's')\r
+    {\r
+      for (; i < s.length(); i++)\r
+      {\r
+        if (s.charAt(i) == '\\')\r
+        {\r
+          s2.appendC('\\');\r
+          i++;\r
+        }\r
+        else if (s.charAt(i) == cdelim && count == 0)\r
+        {\r
+          i++;\r
+          break;\r
+        }\r
+        else if (s.charAt(i) == delim && cdelim != delim)\r
+        {\r
+          count++;\r
+        }\r
+        else if (s.charAt(i) == cdelim && cdelim != delim)\r
+        {\r
+          count--;\r
+        }\r
+        s2.appendC(s.charAt(i));\r
+      }\r
+    }\r
+    for (; i < s.length(); i++)\r
+    {\r
+      char c = s.charAt(i);\r
+      switch (c)\r
+      {\r
+      case 'x':\r
+        xFlag = true;\r
+        break;\r
+      case 'i':\r
+        igncase = true;\r
+        break;\r
+      case 'o':\r
+        optim = true;\r
+        break;\r
+      case 's':\r
+        sFlag = true;\r
+        break;\r
+      case 'm':\r
+        mFlag = true;\r
+        break;\r
+      case 'g':\r
+        gFlag = true;\r
+        break;\r
+      default:\r
+\r
+        // syntax error!\r
+        try\r
+        {\r
+          RegSyntaxError.endItAll("Illegal flag to pattern: " + c);\r
+        } catch (RegSyntax rs)\r
+        {\r
+        }\r
+        return null;\r
+      }\r
+    }\r
+    Regex r = new Regex();\r
+    try\r
+    {\r
+      String pat = s1.toString(), reprul = s2.toString();\r
+      if (xFlag)\r
+      {\r
+        pat = strip(pat);\r
+        reprul = strip(reprul);\r
+      }\r
+      r.compile(pat);\r
+      r.ignoreCase |= igncase;\r
+      r.gFlag |= gFlag;\r
+      r.sFlag |= sFlag;\r
+      r.mFlag |= mFlag;\r
+      if (optim)\r
+      {\r
+        r.optimize();\r
+      }\r
+      if (delim == '\'')\r
+      {\r
+        r.setReplaceRule(new StringRule(reprul));\r
+      }\r
+      else\r
+      {\r
+        r.setReplaceRule(parsePerl.perlCode(reprul));\r
+      }\r
+    } catch (RegSyntax rs)\r
+    {\r
+      r = null;\r
+    }\r
+    return r;\r
+  }\r
+\r
+  static String strip(String s)\r
+  {\r
+    javajs.util.SB sb = new javajs.util.SB();\r
+    for (int i = 0; i < s.length(); i++)\r
+    {\r
+      char c = s.charAt(i);\r
+      if (Prop.isWhite(c))\r
+      {\r
+        ;\r
+      }\r
+      else if (c == '#')\r
+      {\r
+        i++;\r
+        while (i < s.length())\r
+        {\r
+          if (s.charAt(i) == '\n')\r
+          {\r
+            break;\r
+          }\r
+          i++;\r
+        }\r
+      }\r
+      else if (c == '\\')\r
+      {\r
+        sb.appendC(c);\r
+        sb.appendC(s.charAt(++i));\r
+      }\r
+      else\r
+      {\r
+        sb.appendC(c);\r
+      }\r
+    }\r
+    return sb.toString();\r
+  }\r
+\r
+       /**\r
+        * Compile a ReplaceRule using the text that would go between the second and\r
+        * third /'s in a typical substitution pattern in Perl: s/ ... / <i>The\r
+        * argument to ReplaceRule.perlCode</i> /.\r
+        */\r
+       public static ReplaceRule perlCode(String s)\r
+       {\r
+         // String sav_backGs = Regex.backGs;\r
+         // int sav_backGto = Regex.backGto;\r
+         try\r
+         {\r
+           int mf = 0, mt = 0;\r
+           Regex gv = ReplaceRule.getv();\r
+           ReplaceRule head = null;\r
+           Object tmp = null;\r
+           while (gv.searchFrom(s, mt))\r
+           {\r
+             int off = Regex.BackRefOffset - 1;\r
+             mf = gv.matchedFrom();\r
+             if (mf > mt)\r
+             {\r
+               head = ReplaceRule.add(head, new StringRule(s.substring(mt, mf)));\r
+             }\r
+             String var = null;\r
+             if ((var = gv.stringMatched(1 + off)) != null\r
+                     || (var = gv.stringMatched(2 + off)) != null\r
+                     || (var = gv.stringMatched(5 + off)) != null)\r
+             {\r
+               int d = 0;\r
+               for (int i = 0; i < var.length(); i++)\r
+               {\r
+                 d = 8 * d + (var.charAt(i) - '0');\r
+               }\r
+               if (var.length() == 1)\r
+               {\r
+                 head = ReplaceRule.add(head, new BackRefRule(d));\r
+               }\r
+               else\r
+               {\r
+                 head = new StringRule("" + (char) d);\r
+               }\r
+             }\r
+             else if ((var = gv.stringMatched(10 + off)) != null)\r
+             {\r
+               if ("QELlUu".indexOf(var) >= 0)\r
+               {\r
+                 head = ReplaceRule.add(head, new CodeRule(var.charAt(0)));\r
+               }\r
+               else\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule(var));\r
+               }\r
+             }\r
+             else if ((var = gv.stringMatched(3 + off)) != null\r
+                     || (var = gv.stringMatched(4 + off)) != null\r
+                     || (var = gv.stringMatched(6 + off)) != null)\r
+             {\r
+               String arg = "";\r
+               int pc;\r
+               if ((pc = var.indexOf(':')) > 0)\r
+               {\r
+                 arg = var.substring(pc + 1);\r
+                 var = var.substring(0, pc);\r
+               }\r
+               if (var.equals("&") || var.equals("MATCH"))\r
+               {\r
+                 head = ReplaceRule.add(head, new AmpersandRule());\r
+               }\r
+               else if (var.equals("`") || var.equals("PREMATCH"))\r
+               {\r
+                 head = ReplaceRule.add(head, new LeftRule());\r
+               }\r
+               else if (var.equals("'") || var.equals("POSTMATCH"))\r
+               {\r
+                 head = ReplaceRule.add(head, new RightRule());\r
+               }\r
+               else if (var.equals("WANT_MORE_TEXT"))\r
+               {\r
+                 head = ReplaceRule.add(head, new WantMoreTextReplaceRule());\r
+               }\r
+               else if (var.equals("POP"))\r
+               {\r
+                 head = ReplaceRule.add(head, new PopRule());\r
+               }\r
+               else if (var.startsWith("+")\r
+                       && (tmp = ReplaceRule.defs.get(var.substring(1))) != null)\r
+               {\r
+                 if (tmp instanceof Regex)\r
+                 {\r
+                   head = ReplaceRule.add(head, new PushRule(var.substring(1), (Regex) tmp));\r
+                 }\r
+                 else if (tmp instanceof Transformer)\r
+                 {\r
+                   head = ReplaceRule.add(head, new PushRule(var.substring(1),\r
+                           (Transformer) tmp));\r
+                 }\r
+                 else\r
+                 {\r
+                   head = ReplaceRule.add(head, new StringRule("${" + var + "}"));\r
+                 }\r
+               }\r
+               else if (var.startsWith("=")\r
+                       && (tmp = ReplaceRule.defs.get(var.substring(1))) != null)\r
+               {\r
+                 if (tmp instanceof Regex)\r
+                 {\r
+                   head = ReplaceRule.add(head,\r
+                           new ChangeRule(var.substring(1), (Regex) tmp));\r
+                 }\r
+                 else if (tmp instanceof Transformer)\r
+                 {\r
+                   head = ReplaceRule.add(head, new ChangeRule(var.substring(1),\r
+                           (Transformer) tmp));\r
+                 }\r
+                 else\r
+                 {\r
+                   head = ReplaceRule.add(head, new StringRule("${" + var + "}"));\r
+                 }\r
+               }\r
+               else if ((tmp = ReplaceRule.defs.get(var)) != null)\r
+               {\r
+                 if (tmp instanceof ReplaceRule)\r
+                 {\r
+                   ReplaceRule alt = ((ReplaceRule) tmp).arg(arg);\r
+                   if (alt == null)\r
+                   {\r
+                     alt = ((ReplaceRule) tmp);\r
+                   }\r
+                   head = ReplaceRule.add(head, (ReplaceRule) (alt.clone()));\r
+                 }\r
+               }\r
+               else\r
+               // can't figure out how to transform this thing...\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("${" + var + "}"));\r
+               }\r
+             }\r
+             else if ((var = gv.stringMatched(7 + off)) != null)\r
+             {\r
+               char c = var.charAt(0);\r
+               if (c == 'n')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("\n"));\r
+               }\r
+               else if (c == 't')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("\t"));\r
+               }\r
+               else if (c == 'r')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("\r"));\r
+               }\r
+               else if (c == 'b')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("\r"));\r
+               }\r
+               else if (c == 'a')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("" + (char) 7));\r
+               }\r
+               else if (c == 'e')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("" + (char) 27));\r
+               }\r
+               else if (c == 'f')\r
+               {\r
+                 head = ReplaceRule.add(head, new StringRule("" + (char) 12));\r
+               }\r
+             }\r
+             else if ((var = gv.stringMatched(8 + off)) != null)\r
+             {\r
+               char c = var.charAt(0);\r
+               if (c < Ctrl.cmap.length)\r
+               {\r
+                 c = Ctrl.cmap[c];\r
+               }\r
+               head = ReplaceRule.add(head, new StringRule("" + c));\r
+             }\r
+             else if ((var = gv.stringMatched(9 + off)) != null)\r
+             {\r
+               int d = 16 * ReplaceRule.getHexDigit(var.charAt(0))\r
+                       + ReplaceRule.getHexDigit(var.charAt(1));\r
+               head = ReplaceRule.add(head, new StringRule("" + (char) d));\r
+             }\r
+             mt = gv.matchedTo();\r
+           }\r
+           if (mt <= s.length())\r
+           {\r
+             head = ReplaceRule.add(head, new StringRule(s.substring(mt)));\r
+           }\r
+           return head;\r
+         } finally\r
+         {\r
+           // Regex.backGs = sav_backGs;\r
+           // Regex.backGto = sav_backGto;\r
+         }\r
+       }\r
+}\r