// // 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.ewe_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) { StringBuffer sb = new StringBuffer(); 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.append('\\'); 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.append('\\'); sb.append(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; StringBuffer s1 = new StringBuffer(); StringBuffer s2 = new StringBuffer(); 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.append('\\'); 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.append(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.append('\\'); 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.append(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(ReplaceRule.perlCode(reprul)); } catch(RegSyntax rs) { r = null; } return r; } static String strip(String s) { StringBuffer sb = new StringBuffer(); 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.append(c); sb.append(s.charAt(++i)); } else sb.append(c); } return sb.toString(); } }