1 19 20 21 package org.netbeans.modules.i18n.regexp; 22 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 28 36 class Generator { 37 38 39 private StringBuffer buf = new StringBuffer (20); 40 41 42 private Map tokenReplacements; 43 44 45 private boolean generatingSetOfChars = false; 46 47 48 56 public static String generateRegexp(TreeNode parseTree) { 57 return generateRegexp(parseTree, null); 58 } 59 60 61 71 public static String generateRegexp(TreeNode parseTree, Map tokenReplacements) { 72 if (parseTree == null) { 73 return null; 74 } 75 76 Generator g = new Generator(); 77 g.setTokenReplacements(tokenReplacements); 78 g.generate(parseTree); 79 return g.buf.toString(); 80 } 81 82 83 84 private static String quoteString(String string) { 85 if (string.length() == 0) { 86 return string; 87 } 88 89 StringBuffer buf; 90 91 int startIndex = 0; 92 int endIndex = string.indexOf('\\'); 94 if (endIndex == -1) { 95 buf = new StringBuffer (string.length() + 4); 96 buf.append("\\Q").append(string).append("\\E"); } else { 98 buf = new StringBuffer (string.length() + 16); 99 do { 100 if (endIndex != startIndex) { 101 buf.append("\\Q"); buf.append(string.substring(startIndex, endIndex)); 103 buf.append("\\E"); } 105 buf.append('\\').append('\\'); startIndex = endIndex + 1; 107 endIndex = string.indexOf('\\', startIndex); } while (endIndex != -1); 109 if (startIndex != string.length()) { 110 buf.append("\\Q"); buf.append(string.substring(startIndex)); 112 buf.append("\\E"); } 114 } 115 return buf.toString(); 116 } 117 118 119 120 private void setTokenReplacements(Map tokenReplacements) { 121 if ((tokenReplacements != null) && tokenReplacements.isEmpty()) { 122 tokenReplacements = null; 123 } 124 this.tokenReplacements = tokenReplacements; 125 126 if (tokenReplacements != null) { 127 quoteTokenReplacements(); 128 } 129 } 130 131 132 133 private void quoteTokenReplacements() { 134 if (tokenReplacements == null || tokenReplacements.isEmpty()) { 135 return; 136 } 137 138 Set replacementEntries = tokenReplacements.entrySet(); 139 for (Iterator i = replacementEntries.iterator(); i.hasNext();) { 140 Map.Entry entry = (Map.Entry ) i.next(); 141 entry.setValue(quoteString((String ) entry.getValue())); 142 } 143 } 144 145 146 147 private void generate(TreeNode treeNode) { 148 List children = treeNode.getChildren(); 149 int tokenType = treeNode.getTokenType(); 150 Object attribs = treeNode.getAttribs(); 151 char charType; 152 switch (tokenType) { 153 case TreeNode.CHAR: 154 char ch = ((Character ) attribs).charValue(); 155 switch (ch) { 156 case '\t': 157 buf.append('\\').append('t'); 158 break; 159 160 case '\n': 161 buf.append('\\').append('n'); 162 break; 163 164 case '\r': 165 buf.append('\\').append('r'); 166 break; 167 168 case '\f': 169 buf.append('\\').append('f'); 170 break; 171 172 case '\\': 173 buf.append('\\').append('\\'); 174 break; 175 176 default: 177 if (!generatingSetOfChars 178 && ("^$|*+?.()[]{}".indexOf(ch) != -1)) { buf.append('\\'); 180 } 181 buf.append(ch); 182 break; 183 } 184 break; 185 186 case TreeNode.METACHAR: 187 charType = ((Character ) attribs).charValue(); 188 if (charType == '.') { 189 buf.append('.'); 190 } else { 191 buf.append('\\').append(charType); } 193 break; 194 195 case TreeNode.QUANTIFIER: 196 if (attribs instanceof Character ) { 197 charType = ((Character ) attribs).charValue(); 198 buf.append(charType); 199 } else { 200 String type = (String ) attribs; 201 buf.append('{'); 202 generate((TreeNode) children.get(0)); if (type.length() > 3) { buf.append(','); 205 if (type.length() == 5) { generate((TreeNode) children.get(1)); } 208 } 209 buf.append('}'); 210 } 211 break; 212 213 case TreeNode.Q_REGEXP: 214 generate((TreeNode) children.get(0)); 215 if (children.size() == 2) { 216 generate((TreeNode) children.get(1)); 217 } 218 break; 219 220 case TreeNode.RANGE: 221 generate((TreeNode) children.get(0)); 222 buf.append('-'); 223 generate((TreeNode) children.get(1)); 224 break; 225 226 case TreeNode.SET: 227 buf.append('['); 228 if (attribs != null) { 229 buf.append((String ) attribs); 230 } 231 if (children != null) { 232 generatingSetOfChars = true; 233 if (children.size() == 1) { 234 generate((TreeNode) children.get(0)); 235 } else { 236 for (Iterator i = children.iterator(); i.hasNext(); ) { 237 generate((TreeNode) i.next()); 238 } 239 } 240 generatingSetOfChars = false; 241 } 242 buf.append(']'); 243 break; 244 245 case TreeNode.SIMPLE_REGEXP: 246 if (children != null) { 247 if (children.size() == 1) { 248 generate((TreeNode) children.get(0)); 249 } else { 250 for (Iterator i = children.iterator(); i.hasNext(); ) { 251 generate((TreeNode) i.next()); 252 } 253 } 254 } 255 break; 256 257 case TreeNode.SUBEXPR: 258 buf.append('(').append('?').append(':'); 259 generate((TreeNode) children.get(0)); 260 buf.append(')'); 261 break; 262 263 case TreeNode.MULTI_REGEXP: 264 generate((TreeNode) children.get(0)); 265 if (children.size() > 1) { 266 Iterator i = children.iterator(); 267 i.next(); do { 269 buf.append('|'); 270 generate((TreeNode) i.next()); 271 } while (i.hasNext()); 272 } 273 break; 274 275 case TreeNode.NUMBER: 276 buf.append(attribs.toString()); 277 break; 278 279 case TreeNode.UNICODE_CHAR: 280 int code = ((Integer ) attribs).intValue(); 281 buf.append((char) code); 282 break; 283 284 case TreeNode.POSIX_SET: 285 buf.append('\\').append('p'); 286 buf.append('{'); 287 String className = (String ) attribs; 288 if (className.equals("ascii")) { buf.append("ASCII"); } else if (className.equals("xdigit")) { buf.append("XDigit"); } else { 293 buf.append(Character.toUpperCase(className.charAt(0))); 294 buf.append(className.substring(1)); 295 } 296 buf.append('}'); 297 break; 298 299 case TreeNode.REGEXP: 300 String attrString = (String ) attribs; 301 if (attrString != null && attrString.charAt(0) == '^') { 302 buf.append('^'); 303 } 304 if (children != null) { 305 generate((TreeNode) children.get(0)); 306 } 307 if (attrString != null && (attrString.length() == 2 308 || attrString.charAt(0) == '$')) { 309 buf.append('$'); 310 } 311 break; 312 313 case TreeNode.TOKEN: 314 String tokenName = (String ) attribs; 315 Object replacement = tokenReplacements != null 316 ? tokenReplacements.get(tokenName) 317 : null; 318 if (replacement != null) { 319 buf.append('(').append('?').append(':'); 320 buf.append(replacement.toString()); 321 buf.append(')'); 322 } else { 323 buf.append('{').append(tokenName).append('}'); 324 } 325 break; 326 327 default: 328 assert false; 329 break; 330 } 331 } 332 333 } 334 | Popular Tags |