--- /dev/null
+//\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
+/** This class provides a method for parsing the "s/.../.../" constructs\r
+of Regex.perlCode.\r
+@see Regex#perlCode\r
+*/\r
+class parsePerl {\r
+ final static char close(char c) {\r
+ // This switch statement does not behave\r
+ // properly when compiled with jdk1.1.5\r
+ // and the -O flag.\r
+ /*\r
+ switch(c) {\r
+ case '[':\r
+ return ']';\r
+ case '(':\r
+ return ')';\r
+ case '{':\r
+ return '}';\r
+ }\r
+ return c;*/\r
+ if(c == '<')\r
+ return '>';\r
+ if(c == '[')\r
+ return ']';\r
+ if(c == '(')\r
+ return ')';\r
+ if(c == '{')\r
+ return '}';\r
+ return c;\r
+ }\r
+\r
+ final public static String codify(String s,boolean keepbs) {\r
+ return codify(s,0,s.length(),keepbs);\r
+ }\r
+ final public static String codify(String s,int i0,int iN,boolean keepbs) {\r
+ StringBuffer sb = new StringBuffer();\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
+ char c = s.charAt(i);\r
+ boolean mf = true, app=true;\r
+ if(c=='\\') {\r
+ app=false;\r
+ i++;\r
+ if(i<s.length()) {\r
+ char c2 = s.charAt(i);\r
+ switch(c2) {\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
+ sb.append('\\');\r
+ c=c2;\r
+ if(keepbs) mf = false;\r
+ app = true;\r
+ break;\r
+ }\r
+ modified |= mf;\r
+ }\r
+ }\r
+ if(app) {\r
+ if(lc1) {\r
+ c=lc(c);\r
+ lc1=false;\r
+ } else if(uc1) {\r
+ c=uc(c);\r
+ uc1=false;\r
+ } else if(ucmode) {\r
+ c=uc(c);\r
+ } else if(lcmode) {\r
+ c=lc(c);\r
+ }\r
+ if(litmode && needbs(c))\r
+ sb.append('\\');\r
+ sb.append(c);\r
+ }\r
+ }\r
+ return modified ? sb.toString() : s;\r
+ }\r
+ final static char uc(char c) {\r
+ return CaseMgr.toUpperCase(c);\r
+ }\r
+ final static char lc(char c) {\r
+ return CaseMgr.toLowerCase(c);\r
+ }\r
+ final static boolean needbs(char c) {\r
+ if(c >= 'a' && c <= 'z')\r
+ return false;\r
+ if(c >= 'A' && c <= 'Z')\r
+ return false;\r
+ if(c >= '0' && c <= '9')\r
+ return false;\r
+ if(c == '_')\r
+ return false;\r
+ return true;\r
+ }\r
+ final static Regex parse(String s) {\r
+ boolean igncase = false, optim = false, gFlag = false;\r
+ boolean sFlag = false, mFlag = false, xFlag = false;\r
+\r
+ StringBuffer s1 = new StringBuffer();\r
+ StringBuffer s2 = new StringBuffer();\r
+ int i=0,count=0;\r
+ char mode,delim='/',cdelim='/';\r
+ if(s.length() >= 3 && s.charAt(0)=='s') {\r
+ mode = 's';\r
+ delim = s.charAt(1);\r
+ cdelim = close(delim);\r
+ i=2;\r
+ } else if(s.length() >= 2 && s.charAt(0)=='m') {\r
+ mode = 'm';\r
+ delim = s.charAt(1);\r
+ cdelim = close(delim);\r
+ i=2;\r
+ } else if(s.length() >= 1 && s.charAt(0)=='/') {\r
+ mode = 'm';\r
+ i=1;\r
+ } else {\r
+ try {\r
+ RegSyntaxError.endItAll(\r
+ "Regex.perlCode should be of the "+\r
+ "form s/// or m// or //");\r
+ } catch(RegSyntax rs) {}\r
+ return null;\r
+ }\r
+ for(;i<s.length();i++) {\r
+ if(s.charAt(i)=='\\') {\r
+ s1.append('\\');\r
+ i++;\r
+ } else if(s.charAt(i)==cdelim && count==0) {\r
+ i++;\r
+ break;\r
+ } else if(s.charAt(i)==delim && cdelim != delim) {\r
+ count++;\r
+ } else if(s.charAt(i)==cdelim && cdelim != delim) {\r
+ count--;\r
+ }\r
+ s1.append(s.charAt(i));\r
+ }\r
+ if(mode=='s' && cdelim != delim) {\r
+ while(i<s.length() && Prop.isWhite(s.charAt(i)) )\r
+ i++;\r
+ if(i>=s.length()) {\r
+ try {\r
+ RegSyntaxError.endItAll(""+mode+delim+" needs "+cdelim);\r
+ } catch(RegSyntax rs) {}\r
+ return null;\r
+ }\r
+ cdelim = close(delim = s.charAt(i));\r
+ i++;\r
+ }\r
+ count=0;\r
+ if(mode=='s') {\r
+ for(;i<s.length();i++) {\r
+ if(s.charAt(i)=='\\') {\r
+ s2.append('\\');\r
+ i++;\r
+ } else if(s.charAt(i)==cdelim && count==0) {\r
+ i++;\r
+ break;\r
+ } else if(s.charAt(i)==delim && cdelim != delim) {\r
+ count++;\r
+ } else if(s.charAt(i)==cdelim && cdelim != delim) {\r
+ count--;\r
+ }\r
+ s2.append(s.charAt(i));\r
+ }\r
+ }\r
+ for(;i<s.length();i++) {\r
+ char c = s.charAt(i);\r
+ switch(c) {\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
+ // syntax error!\r
+ try {\r
+ RegSyntaxError.endItAll("Illegal flag to pattern: "+c);\r
+ } catch(RegSyntax rs) {}\r
+ return null;\r
+ }\r
+ }\r
+ Regex r = new Regex();\r
+ try {\r
+ String pat=s1.toString(),reprul=s2.toString();\r
+ if(xFlag) {\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.optimize();\r
+ if(delim=='\'')\r
+ r.setReplaceRule(new StringRule(reprul));\r
+ else\r
+ r.setReplaceRule(ReplaceRule.perlCode(reprul));\r
+ } catch(RegSyntax rs) {\r
+ r = null;\r
+ }\r
+ return r;\r
+ }\r
+ static String strip(String s) {\r
+ StringBuffer sb = new StringBuffer();\r
+ for(int i=0;i<s.length();i++) {\r
+ char c = s.charAt(i);\r
+ if(Prop.isWhite(c)) {\r
+ ;\r
+ } else if(c == '#') {\r
+ i++;\r
+ while(i<s.length()) {\r
+ if(s.charAt(i) == '\n')\r
+ break;\r
+ i++;\r
+ }\r
+ } else if(c == '\\') {\r
+ sb.append(c);\r
+ sb.append(s.charAt(++i));\r
+ } else\r
+ sb.append(c);\r
+ }\r
+ return sb.toString();\r
+ }\r
+}\r