001 /** 002 * ========================================= 003 * LibFormula : a free Java formula library 004 * ========================================= 005 * 006 * Project Info: http://reporting.pentaho.org/libformula/ 007 * 008 * (C) Copyright 2006-2007, by Pentaho Corporation and Contributors. 009 * 010 * This library is free software; you can redistribute it and/or modify it under the terms 011 * of the GNU Lesser General Public License as published by the Free Software Foundation; 012 * either version 2.1 of the License, or (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 016 * See the GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public License along with this 019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 020 * Boston, MA 02111-1307, USA. 021 * 022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 023 * in the United States and other countries.] 024 * 025 * 026 * ------------ 027 * $Id: JavaCharStream.java 3521 2007-10-16 10:55:14Z tmorgner $ 028 * ------------ 029 * (C) Copyright 2006-2007, by Pentaho Corporation. 030 */ 031 032 /* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 3.0 */ 033 package org.jfree.formula.parser; 034 035 /** 036 * An implementation of interface CharStream, where the stream is assumed to 037 * contain only ASCII characters (with java-like unicode escape processing). 038 */ 039 040 public class JavaCharStream 041 { 042 public static final boolean staticFlag = false; 043 static int hexval(final char c) throws java.io.IOException { 044 switch(c) 045 { 046 case '0' : 047 return 0; 048 case '1' : 049 return 1; 050 case '2' : 051 return 2; 052 case '3' : 053 return 3; 054 case '4' : 055 return 4; 056 case '5' : 057 return 5; 058 case '6' : 059 return 6; 060 case '7' : 061 return 7; 062 case '8' : 063 return 8; 064 case '9' : 065 return 9; 066 067 case 'a' : 068 case 'A' : 069 return 10; 070 case 'b' : 071 case 'B' : 072 return 11; 073 case 'c' : 074 case 'C' : 075 return 12; 076 case 'd' : 077 case 'D' : 078 return 13; 079 case 'e' : 080 case 'E' : 081 return 14; 082 case 'f' : 083 case 'F' : 084 return 15; 085 } 086 087 throw new java.io.IOException(); // Should never come here 088 } 089 090 public int bufpos = -1; 091 int bufsize; 092 int available; 093 int tokenBegin; 094 protected int[] bufline; 095 protected int[] bufcolumn; 096 097 protected int column = 0; 098 protected int line = 1; 099 100 protected boolean prevCharIsCR = false; 101 protected boolean prevCharIsLF = false; 102 103 protected java.io.Reader inputStream; 104 105 protected char[] nextCharBuf; 106 protected char[] buffer; 107 protected int maxNextCharInd = 0; 108 protected int nextCharInd = -1; 109 protected int inBuf = 0; 110 111 protected void ExpandBuff(final boolean wrapAround) 112 { 113 final char[] newbuffer = new char[bufsize + 2048]; 114 final int[] newbufline = new int[bufsize + 2048]; 115 final int[] newbufcolumn = new int[bufsize + 2048]; 116 117 try 118 { 119 if (wrapAround) 120 { 121 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); 122 System.arraycopy(buffer, 0, newbuffer, 123 bufsize - tokenBegin, bufpos); 124 buffer = newbuffer; 125 126 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); 127 System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); 128 bufline = newbufline; 129 130 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); 131 System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); 132 bufcolumn = newbufcolumn; 133 134 bufpos += (bufsize - tokenBegin); 135 } 136 else 137 { 138 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); 139 buffer = newbuffer; 140 141 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); 142 bufline = newbufline; 143 144 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); 145 bufcolumn = newbufcolumn; 146 147 bufpos -= tokenBegin; 148 } 149 } 150 catch (Throwable t) 151 { 152 throw new Error(t.getMessage()); 153 } 154 155 available = (bufsize += 2048); 156 tokenBegin = 0; 157 } 158 159 protected void FillBuff() throws java.io.IOException 160 { 161 if (maxNextCharInd == 4096) 162 { 163 maxNextCharInd = nextCharInd = 0; 164 } 165 166 try { 167 final int i; 168 if ((i = inputStream.read(nextCharBuf, maxNextCharInd, 169 4096 - maxNextCharInd)) == -1) 170 { 171 inputStream.close(); 172 throw new java.io.IOException(); 173 } 174 maxNextCharInd += i; 175 return; 176 } 177 catch(java.io.IOException e) { 178 if (bufpos != 0) 179 { 180 --bufpos; 181 backup(0); 182 } 183 else 184 { 185 bufline[bufpos] = line; 186 bufcolumn[bufpos] = column; 187 } 188 throw e; 189 } 190 } 191 192 protected char ReadByte() throws java.io.IOException 193 { 194 if (++nextCharInd >= maxNextCharInd) 195 { 196 FillBuff(); 197 } 198 199 return nextCharBuf[nextCharInd]; 200 } 201 202 public char BeginToken() throws java.io.IOException 203 { 204 if (inBuf > 0) 205 { 206 --inBuf; 207 208 if (++bufpos == bufsize) 209 { 210 bufpos = 0; 211 } 212 213 tokenBegin = bufpos; 214 return buffer[bufpos]; 215 } 216 217 tokenBegin = 0; 218 bufpos = -1; 219 220 return readChar(); 221 } 222 223 protected void AdjustBuffSize() 224 { 225 if (available == bufsize) 226 { 227 if (tokenBegin > 2048) 228 { 229 bufpos = 0; 230 available = tokenBegin; 231 } 232 else 233 { 234 ExpandBuff(false); 235 } 236 } 237 else if (available > tokenBegin) 238 { 239 available = bufsize; 240 } 241 else if ((tokenBegin - available) < 2048) 242 { 243 ExpandBuff(true); 244 } 245 else 246 { 247 available = tokenBegin; 248 } 249 } 250 251 protected void UpdateLineColumn(final char c) 252 { 253 column++; 254 255 if (prevCharIsLF) 256 { 257 prevCharIsLF = false; 258 line += (column = 1); 259 } 260 else if (prevCharIsCR) 261 { 262 prevCharIsCR = false; 263 if (c == '\n') 264 { 265 prevCharIsLF = true; 266 } 267 else 268 { 269 line += (column = 1); 270 } 271 } 272 273 switch (c) 274 { 275 case '\r' : 276 prevCharIsCR = true; 277 break; 278 case '\n' : 279 prevCharIsLF = true; 280 break; 281 case '\t' : 282 column--; 283 column += (8 - (column & 07)); 284 break; 285 default : 286 break; 287 } 288 289 bufline[bufpos] = line; 290 bufcolumn[bufpos] = column; 291 } 292 293 public char readChar() throws java.io.IOException 294 { 295 if (inBuf > 0) 296 { 297 --inBuf; 298 299 if (++bufpos == bufsize) 300 { 301 bufpos = 0; 302 } 303 304 return buffer[bufpos]; 305 } 306 307 if (++bufpos == available) 308 { 309 AdjustBuffSize(); 310 } 311 312 char c; 313 if ((buffer[bufpos] = c = ReadByte()) == '\\') 314 { 315 UpdateLineColumn(c); 316 317 int backSlashCnt = 1; 318 319 for (;;) // Read all the backslashes 320 { 321 if (++bufpos == available) 322 { 323 AdjustBuffSize(); 324 } 325 326 try 327 { 328 if ((buffer[bufpos] = c = ReadByte()) != '\\') 329 { 330 UpdateLineColumn(c); 331 // found a non-backslash char. 332 if ((c == 'u') && ((backSlashCnt & 1) == 1)) 333 { 334 if (--bufpos < 0) 335 { 336 bufpos = bufsize - 1; 337 } 338 339 break; 340 } 341 342 backup(backSlashCnt); 343 return '\\'; 344 } 345 } 346 catch(java.io.IOException e) 347 { 348 if (backSlashCnt > 1) 349 { 350 backup(backSlashCnt); 351 } 352 353 return '\\'; 354 } 355 356 UpdateLineColumn(c); 357 backSlashCnt++; 358 } 359 360 // Here, we have seen an odd number of backslash's followed by a 'u' 361 try 362 { 363 while ((c = ReadByte()) == 'u') 364 { 365 ++column; 366 } 367 368 buffer[bufpos] = c = (char)(hexval(c) << 12 | 369 hexval(ReadByte()) << 8 | 370 hexval(ReadByte()) << 4 | 371 hexval(ReadByte())); 372 373 column += 4; 374 } 375 catch(java.io.IOException e) 376 { 377 throw new Error("Invalid escape character at line " + line + 378 " column " + column + "."); 379 } 380 381 if (backSlashCnt == 1) 382 { 383 return c; 384 } 385 else 386 { 387 backup(backSlashCnt - 1); 388 return '\\'; 389 } 390 } 391 else 392 { 393 UpdateLineColumn(c); 394 return (c); 395 } 396 } 397 398 /** 399 * @deprecated 400 * @see #getEndColumn 401 */ 402 403 public int getColumn() { 404 return bufcolumn[bufpos]; 405 } 406 407 /** 408 * @deprecated 409 * @see #getEndLine 410 */ 411 412 public int getLine() { 413 return bufline[bufpos]; 414 } 415 416 public int getEndColumn() { 417 return bufcolumn[bufpos]; 418 } 419 420 public int getEndLine() { 421 return bufline[bufpos]; 422 } 423 424 public int getBeginColumn() { 425 return bufcolumn[tokenBegin]; 426 } 427 428 public int getBeginLine() { 429 return bufline[tokenBegin]; 430 } 431 432 public void backup(final int amount) { 433 434 inBuf += amount; 435 if ((bufpos -= amount) < 0) 436 { 437 bufpos += bufsize; 438 } 439 } 440 441 public JavaCharStream(final java.io.Reader dstream, 442 final int startline, final int startcolumn, final int buffersize) 443 { 444 inputStream = dstream; 445 line = startline; 446 column = startcolumn - 1; 447 448 available = bufsize = buffersize; 449 buffer = new char[buffersize]; 450 bufline = new int[buffersize]; 451 bufcolumn = new int[buffersize]; 452 nextCharBuf = new char[4096]; 453 } 454 455 public JavaCharStream(final java.io.Reader dstream, 456 final int startline, final int startcolumn) 457 { 458 this(dstream, startline, startcolumn, 4096); 459 } 460 461 public JavaCharStream(final java.io.Reader dstream) 462 { 463 this(dstream, 1, 1, 4096); 464 } 465 public void ReInit(final java.io.Reader dstream, 466 final int startline, final int startcolumn, final int buffersize) 467 { 468 inputStream = dstream; 469 line = startline; 470 column = startcolumn - 1; 471 472 if (buffer == null || buffersize != buffer.length) 473 { 474 available = bufsize = buffersize; 475 buffer = new char[buffersize]; 476 bufline = new int[buffersize]; 477 bufcolumn = new int[buffersize]; 478 nextCharBuf = new char[4096]; 479 } 480 prevCharIsLF = prevCharIsCR = false; 481 tokenBegin = inBuf = maxNextCharInd = 0; 482 nextCharInd = bufpos = -1; 483 } 484 485 public void ReInit(final java.io.Reader dstream, 486 final int startline, final int startcolumn) 487 { 488 ReInit(dstream, startline, startcolumn, 4096); 489 } 490 491 public void ReInit(final java.io.Reader dstream) 492 { 493 ReInit(dstream, 1, 1, 4096); 494 } 495 public JavaCharStream(final java.io.InputStream dstream, final int startline, 496 final int startcolumn, final int buffersize) 497 { 498 this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096); 499 } 500 501 public JavaCharStream(final java.io.InputStream dstream, final int startline, 502 final int startcolumn) 503 { 504 this(dstream, startline, startcolumn, 4096); 505 } 506 507 public JavaCharStream(final java.io.InputStream dstream) 508 { 509 this(dstream, 1, 1, 4096); 510 } 511 512 public void ReInit(final java.io.InputStream dstream, final int startline, 513 final int startcolumn, final int buffersize) 514 { 515 ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096); 516 } 517 public void ReInit(final java.io.InputStream dstream, final int startline, 518 final int startcolumn) 519 { 520 ReInit(dstream, startline, startcolumn, 4096); 521 } 522 public void ReInit(final java.io.InputStream dstream) 523 { 524 ReInit(dstream, 1, 1, 4096); 525 } 526 527 public String GetImage() 528 { 529 if (bufpos >= tokenBegin) 530 { 531 return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); 532 } 533 else 534 { 535 return new String(buffer, tokenBegin, bufsize - tokenBegin) + 536 new String(buffer, 0, bufpos + 1); 537 } 538 } 539 540 public char[] GetSuffix(final int len) 541 { 542 final char[] ret = new char[len]; 543 544 if ((bufpos + 1) >= len) 545 { 546 System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); 547 } 548 else 549 { 550 System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, 551 len - bufpos - 1); 552 System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); 553 } 554 555 return ret; 556 } 557 558 public void Done() 559 { 560 nextCharBuf = null; 561 buffer = null; 562 bufline = null; 563 bufcolumn = null; 564 } 565 566 /** 567 * Method to adjust line and column numbers for the start of a token. 568 */ 569 public void adjustBeginLineColumn(int newLine, final int newCol) 570 { 571 int start = tokenBegin; 572 final int len; 573 574 if (bufpos >= tokenBegin) 575 { 576 len = bufpos - tokenBegin + inBuf + 1; 577 } 578 else 579 { 580 len = bufsize - tokenBegin + bufpos + 1 + inBuf; 581 } 582 583 int i = 0; 584 int j = 0; 585 int k; 586 int nextColDiff; 587 int columnDiff = 0; 588 589 while (i < len && 590 bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) 591 { 592 bufline[j] = newLine; 593 nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; 594 bufcolumn[j] = newCol + columnDiff; 595 columnDiff = nextColDiff; 596 i++; 597 } 598 599 if (i < len) 600 { 601 bufline[j] = newLine++; 602 bufcolumn[j] = newCol + columnDiff; 603 604 while (i++ < len) 605 { 606 if (bufline[j = start % bufsize] != bufline[++start % bufsize]) 607 { 608 bufline[j] = newLine++; 609 } 610 else 611 { 612 bufline[j] = newLine; 613 } 614 } 615 } 616 617 line = bufline[j]; 618 column = bufcolumn[j]; 619 } 620 621 }