1 17 18 package com.finalist.jag.template.parser; 19 20 21 22 30 public class JagParser implements JagParserConstants { 31 32 33 private CharBuffer input = null; 34 35 36 private JagBlockCollection lnkJagBlockCollection = null; 37 38 39 private String tagDefBegin = null; 40 41 42 private String tagDefEnd = null; 43 44 45 private String tagDefClose = null; 46 47 48 private String tagDefBodyClose = null; 49 50 51 private JagBlockImpl currentBlock = null; 52 53 54 59 public JagParser() { 60 } 61 62 63 72 public boolean process(CharBuffer input) { 73 tagDefBegin = getTokenString(TAGDEF_BEGIN); 75 tagDefEnd = getTokenString(TAGDEF_END); 76 tagDefClose = getTokenString(TAGDEF_CLOSE) + tagDefEnd; 77 tagDefBodyClose = getTokenString(TAGDEF_BEGIN) + getTokenString(TAGDEF_CLOSE); 78 lnkJagBlockCollection = new JagBlockCollection(); 79 currentBlock = lnkJagBlockCollection; 80 this.input = input; 81 82 StringBuffer text = new StringBuffer (); 84 85 try { 86 boolean expandBuffer = true; 88 while (EOF_CHAR != input.LA(1)) { 89 if (isHeaderDefinition()) { 91 expandBuffer = !processHeader(); 92 text = new StringBuffer (); 93 } else if (isCommentDefinition()) { 94 consumeComment(); 95 } 96 else if (isTagDefinition()) { 98 insertTextBlock(currentBlock, new String (text)); 99 text = new StringBuffer (); 100 expandBuffer = !processTag(); 103 } 104 if (expandBuffer) { 106 text.append(input.LA(1)); 107 input.consume(); 108 } 109 expandBuffer = true; 110 } 111 } catch (Exception e) { 112 } 113 insertTextBlock(currentBlock, new String (text)); 115 return false; 116 } 117 118 119 124 public boolean processTagBody() throws CharStreamException, JagParserException { 125 StringBuffer text = new StringBuffer (); 126 boolean expandBuffer = true; 127 while (EOF_CHAR != input.LA(1)) { 128 if (isTagDefBodyClose()) { 130 insertTextBlock(currentBlock, new String (text)); 131 text = new StringBuffer (); 132 return true; 133 } else if (isCommentDefinition()) { 134 consumeComment(); 135 } 136 else if (isTagDefinition()) { 138 insertTextBlock(currentBlock, new String (text)); 139 text = new StringBuffer (); 140 expandBuffer = !processTag(); 141 } 142 143 if (expandBuffer) { 145 text.append(input.LA(1)); 146 input.consume(); 147 } 148 expandBuffer = true; 149 } 150 insertTextBlock(currentBlock, new String (text)); 152 return false; 153 } 154 155 156 167 protected void insertTextBlock(JagBlock parent, String text) { 168 if (text.length() > 0 && text.charAt(0) != EOF_CHAR) { 169 JagBlockImpl blockChild = new JagBlockImpl(); 170 blockChild.initialize(TEXT, new String (text)); 171 parent.addChild(blockChild); 172 } 173 } 174 175 176 183 protected boolean processHeader() { 184 int mark = input.mark(); 185 try { 186 match(HEADERDEF_BEGIN); 187 JagBlockImpl block = new JagBlockImpl(); 189 block.initialize(HEADERDEF_BEGIN, "HEADERDEF_BEGIN"); 190 currentBlock.addChild(block); 191 processParameters(block); 192 retrieveDataFromHeader(block); 193 consumeSpaces(); 194 match(HEADERDEF_END); 196 return true; 197 } 198 catch (CharStreamException exc) { 200 input.rewind(mark); 201 } catch (JagParserException exc) { 202 input.rewind(mark); 203 } 204 input.commit(); 205 return false; 206 } 207 208 209 216 protected void retrieveDataFromHeader(JagBlock headerBlock) { 217 if (headerBlock.getType() != HEADERDEF_BEGIN) 218 return; 219 220 JagBlock childBlock = headerBlock.getFirstChild(); 221 while (childBlock != null) { 222 if (childBlock.getType() == PARAMDEF) { 223 JagBlock childBlock2 = childBlock.getFirstChild(); 224 if (childBlock2 != null && childBlock2.getType() == IDENT) { 225 if (childBlock2.getText().equals(getTokenString(TAGSTART))) { 226 childBlock2 = childBlock2.getNextSibling(); 227 if (childBlock2 != null) { 228 tagDefBegin = childBlock2.getText(); 229 tagDefBodyClose = tagDefBegin + getTokenString(TAGDEF_CLOSE); 230 } 231 } else if (childBlock2.getText().equals(getTokenString(TAGEND))) { 232 childBlock2 = childBlock2.getNextSibling(); 233 if (childBlock2 != null) { 234 tagDefEnd = childBlock2.getText(); 235 tagDefClose = getTokenString(TAGDEF_CLOSE) + tagDefEnd; 236 } 237 } 238 } 239 } 240 childBlock = childBlock.getNextSibling(); 241 } 242 } 243 244 245 252 protected boolean processTag() { 253 JagBlockImpl prevCurrentBlock = currentBlock; 254 int mark = input.mark(); 255 try { 256 match(tagDefBegin); 257 JagBlockImpl blockTag = new JagBlockImpl(); 258 blockTag.initialize(TAGSTART, "TAGSTART"); 259 260 JagBlock endtagname = processIdent(TAGNAME); 261 blockTag.addChild(endtagname); 262 match(COLON); 263 JagBlock endtagaction = processIdent(TAGACTION); 264 blockTag.addChild(endtagaction); 265 processParameters(blockTag); 266 267 consumeSpaces(); 268 if (ismatch(tagDefClose)) { 269 match(tagDefClose); 270 blockTag.setText(input.getCharsFromMark(mark)); 271 currentBlock.addChild(blockTag); 272 } else { 273 match(tagDefEnd); 274 blockTag.setText(input.getCharsFromMark(mark)); 275 276 JagBlockImpl blockSlist = new JagBlockImpl(); 278 blockSlist.initialize(SLIST, getTokenString(SLIST)); 279 blockTag.addChild(blockSlist); 280 currentBlock = blockSlist; 281 282 if (!processTagBody()) 284 throw new JagParserException("Closing tag expected"); 285 286 int mark2 = input.mark(); 288 match(tagDefBodyClose); 289 if (!endtagname.equals(processIdent(TAGNAME))) 290 throw new JagParserException("Invalid tag name in closing tag"); 291 match(COLON); 292 if (!endtagaction.equals(processIdent(TAGACTION))) 293 throw new JagParserException("Infinite tag in closing tag"); 294 match(tagDefEnd); 295 296 JagBlockImpl blockBodyEndTag = new JagBlockImpl(); 298 blockBodyEndTag.initialize(TAGEND, input.getCharsFromMark(mark2)); 299 blockTag.addChild(blockBodyEndTag); 300 301 currentBlock = prevCurrentBlock; 303 currentBlock.addChild(blockTag); 304 input.commit(); 306 } 307 input.commit(); 308 return true; 309 } catch (CharStreamException exc) { 310 input.rewind(mark); 311 currentBlock = prevCurrentBlock; 312 } catch (JagParserException exc) { 313 input.rewind(mark); 314 currentBlock = prevCurrentBlock; 315 } 316 return false; 317 } 318 319 320 330 protected void processParameters(JagBlock blockRoot) 331 throws CharStreamException, JagParserException { 332 while (true) { 333 consumeSpaces(); 334 StringBuffer text = new StringBuffer (); 335 while (Character.isLetter(input.LA(1)) || (input.LA(1) == '_')) { 336 text.append(input.LA(1)); 337 input.consume(); 338 } 339 if (text.length() == 0) { 340 return; 341 } 342 343 consumeSpaces(); 344 345 if (!ismatch(ASSIGN)) { 346 JagBlockImpl blockChild = new JagBlockImpl(); 347 blockChild.initialize(IDENT, new String (text)); 348 blockRoot.addChild(blockChild); 349 continue; 350 } 351 352 match(ASSIGN); 353 354 JagBlockImpl blockParamDef = new JagBlockImpl(); 355 blockParamDef.initialize(PARAMDEF, getTokenString(PARAMDEF)); 356 blockRoot.addChild(blockParamDef); 357 358 JagBlockImpl blockChild = new JagBlockImpl(); 359 blockChild.initialize(IDENT, new String (text)); 360 blockParamDef.addChild(blockChild); 361 consumeSpaces(); 362 363 text = new StringBuffer (); 364 365 if ((input.LA(1) == '"') && (input.LA(0) != '\\')) { 366 match("\""); 367 while (!((input.LA(1) == '"') && (input.LA(0) != '\\'))) { 368 text.append(input.LA(1)); 369 input.consume(); 370 } 371 match("\""); 372 373 JagBlockImpl blockString = new JagBlockImpl(); 374 375 blockString.initialize(STRING, new String (text)); 376 blockParamDef.addChild(blockString); 377 } else if ((input.LA(1) == '\'') && (input.LA(0) != '\\')) { 378 match("'"); 379 while (!((input.LA(1) == '\'') && (input.LA(0) != '\\'))) { 380 text.append(input.LA(1)); 381 input.consume(); 382 } 383 match("'"); 384 385 JagBlockImpl blockString = new JagBlockImpl(); 386 387 blockString.initialize(STRING, new String (text)); 388 blockParamDef.addChild(blockString); 389 } else { 390 boolean bInteger = true; 391 boolean bFloat = true; 392 393 while (Character.isDigit(input.LA(1)) 394 || Character.isLetter(input.LA(1)) 395 || (input.LA(1) == '_') || (input.LA(1) == '.')) { 396 if (!Character.isDigit(input.LA(1)) && (input.LA(1) != '.')) { 397 bInteger = false; 398 bFloat = false; 399 } else if (!Character.isDigit(input.LA(1))) { 400 bInteger = false; 401 } 402 403 text.append(input.LA(1)); 404 input.consume(); 405 } 406 407 if (text.length() > 0) { 408 JagBlockImpl block = new JagBlockImpl(); 409 410 block.initialize(bInteger ? INTEGER : bFloat ? FLOAT : STRING, new String (text)); 411 blockParamDef.addChild(block); 412 } else { 413 throw new JagParserException("Invalid parameter definition"); 414 } 415 } 416 } 417 } 418 419 420 protected JagBlock processIdent(int tagtype) 421 throws CharStreamException, JagParserException { 422 StringBuffer text = new StringBuffer (); 423 while (Character.isLetter(input.LA(1)) || (input.LA(1) == '_')) { 424 text.append(input.LA(1)); 425 input.consume(); 426 } 427 if (text.length() < 1) 428 throw new JagParserException("Identifier expected"); 429 430 JagBlockImpl blockChild = new JagBlockImpl(); 431 blockChild.initialize(tagtype, new String (text)); 432 return blockChild; 433 } 434 435 436 442 protected void consumeComment() 443 throws CharStreamException, JagParserException { 444 match(tagDefBegin + getTokenString(COMMENT_BEGIN)); 445 while (EOF_CHAR != input.LA(1) && !ismatch(getTokenString(COMMENT_END) + tagDefBegin)) { 446 input.consume(); 447 } 448 match(getTokenString(COMMENT_END) + tagDefBegin); 449 } 450 451 452 459 protected boolean isTagDefinition() { 460 return ismatch(tagDefBegin) && !ismatch(tagDefEnd); 461 } 462 463 464 471 protected boolean isHeaderDefinition() { 472 return ismatch(HEADERDEF_BEGIN); 473 } 474 475 476 483 protected boolean isCommentDefinition() { 484 return ismatch(tagDefBegin + getTokenString(COMMENT_BEGIN)); 485 } 486 487 488 495 protected boolean isTagDefBodyClose() { 496 497 if (!ismatch(tagDefBodyClose)) 498 return false; 499 500 int mark = input.mark(); 501 boolean returnValue = true; 502 try { 503 match(tagDefBodyClose); 504 processIdent(TAGNAME); 505 match(COLON); 506 processIdent(TAGACTION); 507 match(tagDefEnd); 508 } catch (Exception e) { 509 returnValue = false; 510 } 511 input.rewind(mark); 512 return returnValue; 513 } 514 515 516 523 public final JagBlockCollection getJagBlockCollection() { 524 return lnkJagBlockCollection; 525 } 526 527 528 538 protected int consumeSpaces() throws CharStreamException, JagParserException { 539 int nCounter = 0; 540 541 while (true) { 542 if (Character.isWhitespace(input.LA(1)) || (input.LA(1) == '\n')) { 543 input.consume(); 544 nCounter++; 545 } else if (input.LAChars(2) == "\r\n") { 546 match("\r\n"); 547 nCounter += 2; 548 } else { 549 break; 550 } 551 } 552 553 return nCounter; 554 } 555 556 557 567 protected void match(int token) throws CharStreamException, JagParserException { 568 match(getTokenString(token)); 569 } 570 571 572 582 protected void match(String s) throws CharStreamException, JagParserException { 583 StringBuffer text = new StringBuffer (); 584 585 for (int i = 0; i < s.length(); i++) { 586 text.append(input.LA(1)); 587 588 if (s.charAt(i) != input.LA(1)) { 589 throw new JagParserException("\" " + s 590 + " \" excpected, found \" " 591 + text.toString() + " \""); 592 } 593 input.consume(); 594 } 595 } 596 597 598 607 protected boolean ismatch(int token) { 608 return ismatch(getTokenString(token)); 609 } 610 611 612 621 protected boolean ismatch(String s) { 622 try { 623 String sChars = input.LAChars(s.length()); 624 return sChars.compareTo(s) == 0; 625 } catch (CharStreamException exc) { 626 } 627 628 return false; 629 } 630 631 632 641 protected String getTokenString(int n) { 642 return tokennames[n]; 643 } 644 } 645 646 ; | Popular Tags |