1 17 18 package org.apache.jasper.compiler; 19 20 30 31 public class ELParser { 32 33 private Token curToken; 35 private ELNode.Nodes expr; 36 37 private ELNode.Nodes ELexpr; 38 39 private int index; 41 private String expression; 43 private char type; 44 45 private boolean escapeBS; 47 private static final String reservedWords[] = { "and", "div", "empty", 48 "eq", "false", "ge", "gt", "instanceof", "le", "lt", "mod", "ne", 49 "not", "null", "or", "true" }; 50 51 public ELParser(String expression) { 52 index = 0; 53 this.expression = expression; 54 expr = new ELNode.Nodes(); 55 } 56 57 65 public static ELNode.Nodes parse(String expression) { 66 ELParser parser = new ELParser(expression); 67 while (parser.hasNextChar()) { 68 String text = parser.skipUntilEL(); 69 if (text.length() > 0) { 70 parser.expr.add(new ELNode.Text(text)); 71 } 72 ELNode.Nodes elexpr = parser.parseEL(); 73 if (!elexpr.isEmpty()) { 74 parser.expr.add(new ELNode.Root(elexpr, parser.type)); 75 } 76 } 77 return parser.expr; 78 } 79 80 87 private ELNode.Nodes parseEL() { 88 89 StringBuffer buf = new StringBuffer (); 90 ELexpr = new ELNode.Nodes(); 91 while (hasNext()) { 92 curToken = nextToken(); 93 if (curToken instanceof Char) { 94 if (curToken.toChar() == '}') { 95 break; 96 } 97 buf.append(curToken.toChar()); 98 } else { 99 if (buf.length() > 0) { 101 ELexpr.add(new ELNode.ELText(buf.toString())); 102 } 103 if (!parseFunction()) { 104 ELexpr.add(new ELNode.ELText(curToken.toString())); 105 } 106 } 107 } 108 if (buf.length() > 0) { 109 ELexpr.add(new ELNode.ELText(buf.toString())); 110 } 111 112 return ELexpr; 113 } 114 115 120 private boolean parseFunction() { 121 if (!(curToken instanceof Id) || isELReserved(curToken.toString())) { 122 return false; 123 } 124 String s1 = null; String s2 = curToken.toString(); int mark = getIndex(); 127 if (hasNext()) { 128 Token t = nextToken(); 129 if (t.toChar() == ':') { 130 if (hasNext()) { 131 Token t2 = nextToken(); 132 if (t2 instanceof Id) { 133 s1 = s2; 134 s2 = t2.toString(); 135 if (hasNext()) { 136 t = nextToken(); 137 } 138 } 139 } 140 } 141 if (t.toChar() == '(') { 142 ELexpr.add(new ELNode.Function(s1, s2)); 143 return true; 144 } 145 } 146 setIndex(mark); 147 return false; 148 } 149 150 153 private boolean isELReserved(String id) { 154 int i = 0; 155 int j = reservedWords.length; 156 while (i < j) { 157 int k = (i + j) / 2; 158 int result = reservedWords[k].compareTo(id); 159 if (result == 0) { 160 return true; 161 } 162 if (result < 0) { 163 i = k + 1; 164 } else { 165 j = k; 166 } 167 } 168 return false; 169 } 170 171 177 private String skipUntilEL() { 178 char prev = 0; 179 StringBuffer buf = new StringBuffer (); 180 while (hasNextChar()) { 181 char ch = nextChar(); 182 if (prev == '\\') { 183 prev = 0; 184 if (ch == '\\') { 185 buf.append('\\'); 186 if (!escapeBS) 187 prev = '\\'; 188 } else if (ch == '$' || ch == '#') { 189 buf.append(ch); 190 } 191 } else if (prev == '$' || prev == '#') { 193 if (ch == '{') { 194 this.type = prev; 195 prev = 0; 196 break; 197 } 198 buf.append(prev); 199 prev = 0; 200 } 201 if (ch == '\\' || ch == '$' || ch == '#') { 202 prev = ch; 203 } else { 204 buf.append(ch); 205 } 206 } 207 if (prev != 0) { 208 buf.append(prev); 209 } 210 return buf.toString(); 211 } 212 213 217 private boolean hasNext() { 218 skipSpaces(); 219 return hasNextChar(); 220 } 221 222 225 private Token nextToken() { 226 skipSpaces(); 227 if (hasNextChar()) { 228 char ch = nextChar(); 229 if (Character.isJavaIdentifierStart(ch)) { 230 StringBuffer buf = new StringBuffer (); 231 buf.append(ch); 232 while ((ch = peekChar()) != -1 233 && Character.isJavaIdentifierPart(ch)) { 234 buf.append(ch); 235 nextChar(); 236 } 237 return new Id(buf.toString()); 238 } 239 240 if (ch == '\'' || ch == '"') { 241 return parseQuotedChars(ch); 242 } else { 243 return new Char(ch); 245 } 246 } 247 return null; 248 } 249 250 254 private Token parseQuotedChars(char quote) { 255 StringBuffer buf = new StringBuffer (); 256 buf.append(quote); 257 while (hasNextChar()) { 258 char ch = nextChar(); 259 if (ch == '\\') { 260 ch = nextChar(); 261 if (ch == '\\' || ch == quote) { 262 buf.append(ch); 263 } 264 } else if (ch == quote) { 266 buf.append(ch); 267 break; 268 } else { 269 buf.append(ch); 270 } 271 } 272 return new QuotedString(buf.toString()); 273 } 274 275 279 280 private void skipSpaces() { 281 while (hasNextChar()) { 282 if (expression.charAt(index) > ' ') 283 break; 284 index++; 285 } 286 } 287 288 private boolean hasNextChar() { 289 return index < expression.length(); 290 } 291 292 private char nextChar() { 293 if (index >= expression.length()) { 294 return (char) -1; 295 } 296 return expression.charAt(index++); 297 } 298 299 private char peekChar() { 300 if (index >= expression.length()) { 301 return (char) -1; 302 } 303 return expression.charAt(index); 304 } 305 306 private int getIndex() { 307 return index; 308 } 309 310 private void setIndex(int i) { 311 index = i; 312 } 313 314 317 private static class Token { 318 319 char toChar() { 320 return 0; 321 } 322 323 public String toString() { 324 return ""; 325 } 326 } 327 328 331 private static class Id extends Token { 332 String id; 333 334 Id(String id) { 335 this.id = id; 336 } 337 338 public String toString() { 339 return id; 340 } 341 } 342 343 346 private static class Char extends Token { 347 348 private char ch; 349 350 Char(char ch) { 351 this.ch = ch; 352 } 353 354 char toChar() { 355 return ch; 356 } 357 358 public String toString() { 359 return (new Character (ch)).toString(); 360 } 361 } 362 363 366 private static class QuotedString extends Token { 367 368 private String value; 369 370 QuotedString(String v) { 371 this.value = v; 372 } 373 374 public String toString() { 375 return value; 376 } 377 } 378 379 public char getType() { 380 return type; 381 } 382 } 383 | Popular Tags |