1 /***********************************************************************************************************************************
 
   2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. All rights reserved. This program and the
 
   3  * accompanying materials are made available under the terms of the Common Public License v0.5 which accompanies this distribution,
 
   4  * and is available at http://www.eclipse.org/legal/cpl-v05.html
 
   6  * Contributors: IBM Corporation - initial API and implementation
 
   7  **********************************************************************************************************************************/
 
   8 package net.sourceforge.phpdt.internal.compiler.parser;
 
  10 import java.util.ArrayList;
 
  11 import java.util.Iterator;
 
  12 import java.util.List;
 
  13 import java.util.Stack;
 
  15 import net.sourceforge.phpdt.core.compiler.CharOperation;
 
  16 import net.sourceforge.phpdt.core.compiler.IScanner;
 
  17 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
  18 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 
  19 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
 
  20 import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral;
 
  22 public class Scanner implements IScanner, ITerminalSymbols {
 
  24    * APIs ares - getNextToken() which return the current type of the token (this value is not memorized by the scanner) -
 
  25    * getCurrentTokenSource() which provides with the token "REAL" source (aka all unicode have been transformed into a correct char) -
 
  26    * sourceStart gives the position into the stream - currentPosition-1 gives the sourceEnd position into the stream
 
  29   private boolean assertMode;
 
  31   public boolean useAssertAsAnIndentifier = false;
 
  33   //flag indicating if processed source contains occurrences of keyword assert
 
  34   public boolean containsAssertKeyword = false;
 
  36   public boolean recordLineSeparator;
 
  38   public boolean ignorePHPOneLiner = false;
 
  40   public boolean phpMode = false;
 
  42   public Stack encapsedStringStack = null;
 
  44   public char currentCharacter;
 
  46   public int startPosition;
 
  48   public int currentPosition;
 
  50   public int initialPosition, eofPosition;
 
  52   // after this position eof are generated instead of real token from the
 
  54   public boolean tokenizeComments;
 
  56   public boolean tokenizeWhiteSpace;
 
  58   public boolean tokenizeStrings;
 
  60   //source should be viewed as a window (aka a part)
 
  61   //of a entire very large stream
 
  65   public char[] withoutUnicodeBuffer;
 
  67   public int withoutUnicodePtr;
 
  69   //when == 0 ==> no unicode in the current token
 
  70   public boolean unicodeAsBackSlash = false;
 
  72   public boolean scanningFloatLiteral = false;
 
  74   //support for /** comments
 
  75   public int[] commentStops = new int[10];
 
  77   public int[] commentStarts = new int[10];
 
  79   public int commentPtr = -1; // no comment test with commentPtr value -1
 
  81   protected int lastCommentLinePosition = -1;
 
  83   //diet parsing support - jump over some method body when requested
 
  84   public boolean diet = false;
 
  86   //support for the poor-line-debuggers ....
 
  87   //remember the position of the cr/lf
 
  88   public int[] lineEnds = new int[250];
 
  90   public int linePtr = -1;
 
  92   public boolean wasAcr = false;
 
  94   public static final String END_OF_SOURCE = "End_Of_Source"; //$NON-NLS-1$
 
  96   public static final String INVALID_HEXA = "Invalid_Hexa_Literal"; //$NON-NLS-1$
 
  98   public static final String INVALID_OCTAL = "Invalid_Octal_Literal"; //$NON-NLS-1$
 
 100   public static final String INVALID_CHARACTER_CONSTANT = "Invalid_Character_Constant"; //$NON-NLS-1$
 
 102   public static final String INVALID_ESCAPE = "Invalid_Escape"; //$NON-NLS-1$
 
 104   public static final String INVALID_INPUT = "Invalid_Input"; //$NON-NLS-1$
 
 106   public static final String INVALID_UNICODE_ESCAPE = "Invalid_Unicode_Escape"; //$NON-NLS-1$
 
 108   public static final String INVALID_FLOAT = "Invalid_Float_Literal"; //$NON-NLS-1$
 
 110   public static final String NULL_SOURCE_STRING = "Null_Source_String"; //$NON-NLS-1$
 
 112   public static final String UNTERMINATED_STRING = "Unterminated_String"; //$NON-NLS-1$
 
 114   public static final String UNTERMINATED_COMMENT = "Unterminated_Comment"; //$NON-NLS-1$
 
 116   public static final String INVALID_CHAR_IN_STRING = "Invalid_Char_In_String"; //$NON-NLS-1$
 
 118   //----------------optimized identifier managment------------------
 
 119   static final char[] charArray_a = new char[] { 'a' }, charArray_b = new char[] { 'b' }, charArray_c = new char[] { 'c' },
 
 120       charArray_d = new char[] { 'd' }, charArray_e = new char[] { 'e' }, charArray_f = new char[] { 'f' },
 
 121       charArray_g = new char[] { 'g' }, charArray_h = new char[] { 'h' }, charArray_i = new char[] { 'i' },
 
 122       charArray_j = new char[] { 'j' }, charArray_k = new char[] { 'k' }, charArray_l = new char[] { 'l' },
 
 123       charArray_m = new char[] { 'm' }, charArray_n = new char[] { 'n' }, charArray_o = new char[] { 'o' },
 
 124       charArray_p = new char[] { 'p' }, charArray_q = new char[] { 'q' }, charArray_r = new char[] { 'r' },
 
 125       charArray_s = new char[] { 's' }, charArray_t = new char[] { 't' }, charArray_u = new char[] { 'u' },
 
 126       charArray_v = new char[] { 'v' }, charArray_w = new char[] { 'w' }, charArray_x = new char[] { 'x' },
 
 127       charArray_y = new char[] { 'y' }, charArray_z = new char[] { 'z' };
 
 129   static final char[] charArray_va = new char[] { '$', 'a' }, charArray_vb = new char[] { '$', 'b' }, charArray_vc = new char[] {
 
 131       'c' }, charArray_vd = new char[] { '$', 'd' }, charArray_ve = new char[] { '$', 'e' },
 
 132       charArray_vf = new char[] { '$', 'f' }, charArray_vg = new char[] { '$', 'g' }, charArray_vh = new char[] { '$', 'h' },
 
 133       charArray_vi = new char[] { '$', 'i' }, charArray_vj = new char[] { '$', 'j' }, charArray_vk = new char[] { '$', 'k' },
 
 134       charArray_vl = new char[] { '$', 'l' }, charArray_vm = new char[] { '$', 'm' }, charArray_vn = new char[] { '$', 'n' },
 
 135       charArray_vo = new char[] { '$', 'o' }, charArray_vp = new char[] { '$', 'p' }, charArray_vq = new char[] { '$', 'q' },
 
 136       charArray_vr = new char[] { '$', 'r' }, charArray_vs = new char[] { '$', 's' }, charArray_vt = new char[] { '$', 't' },
 
 137       charArray_vu = new char[] { '$', 'u' }, charArray_vv = new char[] { '$', 'v' }, charArray_vw = new char[] { '$', 'w' },
 
 138       charArray_vx = new char[] { '$', 'x' }, charArray_vy = new char[] { '$', 'y' }, charArray_vz = new char[] { '$', 'z' };
 
 140   static final char[] initCharArray = new char[] { '\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000' };
 
 142   static final int TableSize = 30, InternalTableSize = 6;
 
 145   public static final int OptimizedLength = 6;
 
 148   final char[][][][] charArray_length = new char[OptimizedLength][TableSize][InternalTableSize][];
 
 150   // support for detecting non-externalized string literals
 
 151   int currentLineNr = -1;
 
 153   int previousLineNr = -1;
 
 155   NLSLine currentLine = null;
 
 157   List lines = new ArrayList();
 
 159   public static final String TAG_PREFIX = "//$NON-NLS-"; //$NON-NLS-1$
 
 161   public static final int TAG_PREFIX_LENGTH = TAG_PREFIX.length();
 
 163   public static final String TAG_POSTFIX = "$"; //$NON-NLS-1$
 
 165   public static final int TAG_POSTFIX_LENGTH = TAG_POSTFIX.length();
 
 167   public StringLiteral[] nonNLSStrings = null;
 
 169   public boolean checkNonExternalizedStringLiterals = true;
 
 171   public boolean wasNonExternalizedStringLiteral = false;
 
 173     for (int i = 0; i < 6; i++) {
 
 174       for (int j = 0; j < TableSize; j++) {
 
 175         for (int k = 0; k < InternalTableSize; k++) {
 
 176           charArray_length[i][j][k] = initCharArray;
 
 182   static int newEntry2 = 0, newEntry3 = 0, newEntry4 = 0, newEntry5 = 0, newEntry6 = 0;
 
 184   public static final int RoundBracket = 0;
 
 186   public static final int SquareBracket = 1;
 
 188   public static final int CurlyBracket = 2;
 
 190   public static final int BracketKinds = 3;
 
 193   public char[][] foundTaskTags = null;
 
 195   public char[][] foundTaskMessages;
 
 197   public char[][] foundTaskPriorities = null;
 
 199   public int[][] foundTaskPositions;
 
 201   public int foundTaskCount = 0;
 
 203   public char[][] taskTags = null;
 
 205   public char[][] taskPriorities = null;
 
 207   public boolean isTaskCaseSensitive = true;
 
 209   public static final boolean DEBUG = false;
 
 211   public static final boolean TRACE = false;
 
 213   public ICompilationUnit compilationUnit = null;
 
 216    * Determines if the specified character is permissible as the first character in a PHP identifier or variable
 
 218    * The '$' character for PHP variables is regarded as a correct first character !
 
 221   public static boolean isPHPIdentOrVarStart(char ch) {
 
 222     return Character.isLetter(ch) || (ch == '$') || (ch == '_') || (0x7F <= ch && ch <= 0xFF);
 
 226    * Determines if the specified character is permissible as the first character in a PHP identifier.
 
 228    * The '$' character for PHP variables isn't regarded as the first character !
 
 230   public static boolean isPHPIdentifierStart(char ch) {
 
 231     return Character.isLetter(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF);
 
 235    * Determines if the specified character may be part of a PHP identifier as other than the first character
 
 237   public static boolean isPHPIdentifierPart(char ch) {
 
 238     return Character.isLetterOrDigit(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF);
 
 241   public final boolean atEnd() {
 
 242     // This code is not relevant if source is
 
 243     // Only a part of the real stream input
 
 244     return source.length == currentPosition;
 
 247   public char[] getCurrentIdentifierSource() {
 
 248     //return the token REAL source (aka unicodes are precomputed)
 
 250     //    if (withoutUnicodePtr != 0)
 
 251     //      //0 is used as a fast test flag so the real first char is in position 1
 
 253     //        withoutUnicodeBuffer,
 
 255     //        result = new char[withoutUnicodePtr],
 
 257     //        withoutUnicodePtr);
 
 259     int length = currentPosition - startPosition;
 
 260     switch (length) { // see OptimizedLength
 
 262       return optimizedCurrentTokenSource1();
 
 264       return optimizedCurrentTokenSource2();
 
 266       return optimizedCurrentTokenSource3();
 
 268       return optimizedCurrentTokenSource4();
 
 270       return optimizedCurrentTokenSource5();
 
 272       return optimizedCurrentTokenSource6();
 
 275     System.arraycopy(source, startPosition, result = new char[length], 0, length);
 
 280   public int getCurrentTokenEndPosition() {
 
 281     return this.currentPosition - 1;
 
 284   public final char[] getCurrentTokenSource() {
 
 285     // Return the token REAL source (aka unicodes are precomputed)
 
 287     //    if (withoutUnicodePtr != 0)
 
 288     //      // 0 is used as a fast test flag so the real first char is in position 1
 
 290     //        withoutUnicodeBuffer,
 
 292     //        result = new char[withoutUnicodePtr],
 
 294     //        withoutUnicodePtr);
 
 297     System.arraycopy(source, startPosition, result = new char[length = currentPosition - startPosition], 0, length);
 
 302   public final char[] getCurrentTokenSource(int startPos) {
 
 303     // Return the token REAL source (aka unicodes are precomputed)
 
 305     //    if (withoutUnicodePtr != 0)
 
 306     //      // 0 is used as a fast test flag so the real first char is in position 1
 
 308     //        withoutUnicodeBuffer,
 
 310     //        result = new char[withoutUnicodePtr],
 
 312     //        withoutUnicodePtr);
 
 315     System.arraycopy(source, startPos, result = new char[length = currentPosition - startPos], 0, length);
 
 320   public final char[] getCurrentTokenSourceString() {
 
 321     //return the token REAL source (aka unicodes are precomputed).
 
 322     //REMOVE the two " that are at the beginning and the end.
 
 324     if (withoutUnicodePtr != 0)
 
 325       //0 is used as a fast test flag so the real first char is in position 1
 
 326       System.arraycopy(withoutUnicodeBuffer, 2,
 
 327       //2 is 1 (real start) + 1 (to jump over the ")
 
 328           result = new char[withoutUnicodePtr - 2], 0, withoutUnicodePtr - 2);
 
 331       System.arraycopy(source, startPosition + 1, result = new char[length = currentPosition - startPosition - 2], 0, length);
 
 336   public final char[] getRawTokenSourceEnd() {
 
 337     int length = this.eofPosition - this.currentPosition - 1;
 
 338     char[] sourceEnd = new char[length];
 
 339     System.arraycopy(this.source, this.currentPosition, sourceEnd, 0, length);
 
 343   public int getCurrentTokenStartPosition() {
 
 344     return this.startPosition;
 
 347   public final char[] getCurrentStringLiteralSource() {
 
 348     // Return the token REAL source (aka unicodes are precomputed)
 
 349     if (startPosition + 1 >= currentPosition) {
 
 354     System.arraycopy(source, startPosition + 1, result = new char[length = currentPosition - startPosition - 2], 0, length);
 
 359   public final char[] getCurrentStringLiteralSource(int startPos) {
 
 360     // Return the token REAL source (aka unicodes are precomputed)
 
 363     System.arraycopy(source, startPos + 1, result = new char[length = currentPosition - startPos - 2], 0, length);
 
 369    * Search the source position corresponding to the end of a given line number
 
 371    * Line numbers are 1-based, and relative to the scanner initialPosition. Character positions are 0-based.
 
 373    * In case the given line number is inconsistent, answers -1.
 
 375   public final int getLineEnd(int lineNumber) {
 
 376     if (lineEnds == null)
 
 378     if (lineNumber >= lineEnds.length)
 
 382     if (lineNumber == lineEnds.length - 1)
 
 384     return lineEnds[lineNumber - 1];
 
 385     // next line start one character behind the lineEnd of the previous line
 
 389    * Search the source position corresponding to the beginning of a given line number
 
 391    * Line numbers are 1-based, and relative to the scanner initialPosition. Character positions are 0-based.
 
 393    * e.g. getLineStart(1) --> 0 i.e. first line starts at character 0.
 
 395    * In case the given line number is inconsistent, answers -1.
 
 397   public final int getLineStart(int lineNumber) {
 
 398     if (lineEnds == null)
 
 400     if (lineNumber >= lineEnds.length)
 
 405       return initialPosition;
 
 406     return lineEnds[lineNumber - 2] + 1;
 
 407     // next line start one character behind the lineEnd of the previous line
 
 410   public final boolean getNextChar(char testedChar) {
 
 412     //handle the case of unicode.
 
 413     //when a unicode appears then we must use a buffer that holds char
 
 415     //At the end of this method currentCharacter holds the new visited char
 
 416     //and currentPosition points right next after it
 
 417     //Both previous lines are true if the currentCharacter is == to the
 
 419     //On false, no side effect has occured.
 
 420     //ALL getNextChar.... ARE OPTIMIZED COPIES
 
 421     int temp = currentPosition;
 
 423       currentCharacter = source[currentPosition++];
 
 424       //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
 425       //        && (source[currentPosition] == 'u')) {
 
 426       //        //-------------unicode traitement ------------
 
 427       //        int c1, c2, c3, c4;
 
 428       //        int unicodeSize = 6;
 
 429       //        currentPosition++;
 
 430       //        while (source[currentPosition] == 'u') {
 
 431       //          currentPosition++;
 
 435       //        if (((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
 437       //          || ((c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
 439       //          || ((c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
 441       //          || ((c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
 443       //          currentPosition = temp;
 
 447       //        currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
 448       //        if (currentCharacter != testedChar) {
 
 449       //          currentPosition = temp;
 
 452       //        unicodeAsBackSlash = currentCharacter == '\\';
 
 454       //        //need the unicode buffer
 
 455       //        if (withoutUnicodePtr == 0) {
 
 456       //          //buffer all the entries that have been left aside....
 
 457       //          withoutUnicodePtr = currentPosition - unicodeSize - startPosition;
 
 461       //            withoutUnicodeBuffer,
 
 463       //            withoutUnicodePtr);
 
 465       //        //fill the buffer with the char
 
 466       //        withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 469       //      } //-------------end unicode traitement--------------
 
 471       if (currentCharacter != testedChar) {
 
 472         currentPosition = temp;
 
 475       unicodeAsBackSlash = false;
 
 476       //        if (withoutUnicodePtr != 0)
 
 477       //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 480     } catch (IndexOutOfBoundsException e) {
 
 481       unicodeAsBackSlash = false;
 
 482       currentPosition = temp;
 
 487   public final int getNextChar(char testedChar1, char testedChar2) {
 
 488     //INT 0 : testChar1 \\\\///\\\\ 1 : testedChar2 \\\\///\\\\ -1 : others
 
 489     //test can be done with (x==0) for the first and (x>0) for the second
 
 490     //handle the case of unicode.
 
 491     //when a unicode appears then we must use a buffer that holds char
 
 493     //At the end of this method currentCharacter holds the new visited char
 
 494     //and currentPosition points right next after it
 
 495     //Both previous lines are true if the currentCharacter is == to the
 
 497     //On false, no side effect has occured.
 
 498     //ALL getNextChar.... ARE OPTIMIZED COPIES
 
 499     int temp = currentPosition;
 
 502       currentCharacter = source[currentPosition++];
 
 503       //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
 504       //        && (source[currentPosition] == 'u')) {
 
 505       //        //-------------unicode traitement ------------
 
 506       //        int c1, c2, c3, c4;
 
 507       //        int unicodeSize = 6;
 
 508       //        currentPosition++;
 
 509       //        while (source[currentPosition] == 'u') {
 
 510       //          currentPosition++;
 
 514       //        if (((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
 516       //          || ((c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
 518       //          || ((c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
 520       //          || ((c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
 522       //          currentPosition = temp;
 
 526       //        currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
 527       //        if (currentCharacter == testedChar1)
 
 529       //        else if (currentCharacter == testedChar2)
 
 532       //          currentPosition = temp;
 
 536       //        //need the unicode buffer
 
 537       //        if (withoutUnicodePtr == 0) {
 
 538       //          //buffer all the entries that have been left aside....
 
 539       //          withoutUnicodePtr = currentPosition - unicodeSize - startPosition;
 
 543       //            withoutUnicodeBuffer,
 
 545       //            withoutUnicodePtr);
 
 547       //        //fill the buffer with the char
 
 548       //        withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 550       //      } //-------------end unicode traitement--------------
 
 552       if (currentCharacter == testedChar1)
 
 554       else if (currentCharacter == testedChar2)
 
 557         currentPosition = temp;
 
 560       //        if (withoutUnicodePtr != 0)
 
 561       //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 564     } catch (IndexOutOfBoundsException e) {
 
 565       currentPosition = temp;
 
 570   public final boolean getNextCharAsDigit() {
 
 572     //handle the case of unicode.
 
 573     //when a unicode appears then we must use a buffer that holds char
 
 575     //At the end of this method currentCharacter holds the new visited char
 
 576     //and currentPosition points right next after it
 
 577     //Both previous lines are true if the currentCharacter is a digit
 
 578     //On false, no side effect has occured.
 
 579     //ALL getNextChar.... ARE OPTIMIZED COPIES
 
 580     int temp = currentPosition;
 
 582       currentCharacter = source[currentPosition++];
 
 583       //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
 584       //        && (source[currentPosition] == 'u')) {
 
 585       //        //-------------unicode traitement ------------
 
 586       //        int c1, c2, c3, c4;
 
 587       //        int unicodeSize = 6;
 
 588       //        currentPosition++;
 
 589       //        while (source[currentPosition] == 'u') {
 
 590       //          currentPosition++;
 
 594       //        if (((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
 596       //          || ((c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
 598       //          || ((c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
 600       //          || ((c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
 602       //          currentPosition = temp;
 
 606       //        currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
 607       //        if (!Character.isDigit(currentCharacter)) {
 
 608       //          currentPosition = temp;
 
 612       //        //need the unicode buffer
 
 613       //        if (withoutUnicodePtr == 0) {
 
 614       //          //buffer all the entries that have been left aside....
 
 615       //          withoutUnicodePtr = currentPosition - unicodeSize - startPosition;
 
 619       //            withoutUnicodeBuffer,
 
 621       //            withoutUnicodePtr);
 
 623       //        //fill the buffer with the char
 
 624       //        withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 626       //      } //-------------end unicode traitement--------------
 
 628       if (!Character.isDigit(currentCharacter)) {
 
 629         currentPosition = temp;
 
 632       //        if (withoutUnicodePtr != 0)
 
 633       //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 636     } catch (IndexOutOfBoundsException e) {
 
 637       currentPosition = temp;
 
 642   public final boolean getNextCharAsDigit(int radix) {
 
 644     //handle the case of unicode.
 
 645     //when a unicode appears then we must use a buffer that holds char
 
 647     //At the end of this method currentCharacter holds the new visited char
 
 648     //and currentPosition points right next after it
 
 649     //Both previous lines are true if the currentCharacter is a digit base on
 
 651     //On false, no side effect has occured.
 
 652     //ALL getNextChar.... ARE OPTIMIZED COPIES
 
 653     int temp = currentPosition;
 
 655       currentCharacter = source[currentPosition++];
 
 656       //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
 657       //        && (source[currentPosition] == 'u')) {
 
 658       //        //-------------unicode traitement ------------
 
 659       //        int c1, c2, c3, c4;
 
 660       //        int unicodeSize = 6;
 
 661       //        currentPosition++;
 
 662       //        while (source[currentPosition] == 'u') {
 
 663       //          currentPosition++;
 
 667       //        if (((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
 669       //          || ((c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
 671       //          || ((c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
 673       //          || ((c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
 675       //          currentPosition = temp;
 
 679       //        currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
 680       //        if (Character.digit(currentCharacter, radix) == -1) {
 
 681       //          currentPosition = temp;
 
 685       //        //need the unicode buffer
 
 686       //        if (withoutUnicodePtr == 0) {
 
 687       //          //buffer all the entries that have been left aside....
 
 688       //          withoutUnicodePtr = currentPosition - unicodeSize - startPosition;
 
 692       //            withoutUnicodeBuffer,
 
 694       //            withoutUnicodePtr);
 
 696       //        //fill the buffer with the char
 
 697       //        withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 699       //      } //-------------end unicode traitement--------------
 
 701       if (Character.digit(currentCharacter, radix) == -1) {
 
 702         currentPosition = temp;
 
 705       //        if (withoutUnicodePtr != 0)
 
 706       //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 709     } catch (IndexOutOfBoundsException e) {
 
 710       currentPosition = temp;
 
 715   public boolean getNextCharAsJavaIdentifierPart() {
 
 717     //handle the case of unicode.
 
 718     //when a unicode appears then we must use a buffer that holds char
 
 720     //At the end of this method currentCharacter holds the new visited char
 
 721     //and currentPosition points right next after it
 
 722     //Both previous lines are true if the currentCharacter is a
 
 723     // JavaIdentifierPart
 
 724     //On false, no side effect has occured.
 
 725     //ALL getNextChar.... ARE OPTIMIZED COPIES
 
 726     int temp = currentPosition;
 
 728       currentCharacter = source[currentPosition++];
 
 729       //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
 730       //        && (source[currentPosition] == 'u')) {
 
 731       //        //-------------unicode traitement ------------
 
 732       //        int c1, c2, c3, c4;
 
 733       //        int unicodeSize = 6;
 
 734       //        currentPosition++;
 
 735       //        while (source[currentPosition] == 'u') {
 
 736       //          currentPosition++;
 
 740       //        if (((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
 742       //          || ((c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
 744       //          || ((c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
 746       //          || ((c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
 748       //          currentPosition = temp;
 
 752       //        currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
 753       //        if (!isPHPIdentifierPart(currentCharacter)) {
 
 754       //          currentPosition = temp;
 
 758       //        //need the unicode buffer
 
 759       //        if (withoutUnicodePtr == 0) {
 
 760       //          //buffer all the entries that have been left aside....
 
 761       //          withoutUnicodePtr = currentPosition - unicodeSize - startPosition;
 
 765       //            withoutUnicodeBuffer,
 
 767       //            withoutUnicodePtr);
 
 769       //        //fill the buffer with the char
 
 770       //        withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 772       //      } //-------------end unicode traitement--------------
 
 774       if (!isPHPIdentifierPart(currentCharacter)) {
 
 775         currentPosition = temp;
 
 778       //        if (withoutUnicodePtr != 0)
 
 779       //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 782     } catch (IndexOutOfBoundsException e) {
 
 783       currentPosition = temp;
 
 788   public int getCastOrParen() {
 
 789     int tempPosition = currentPosition;
 
 790     char tempCharacter = currentCharacter;
 
 791     int tempToken = TokenNameLPAREN;
 
 792     boolean found = false;
 
 793     StringBuffer buf = new StringBuffer();
 
 796         currentCharacter = source[currentPosition++];
 
 797       } while (currentCharacter == ' ' || currentCharacter == '\t');
 
 798       while ((currentCharacter >= 'a' && currentCharacter <= 'z') || (currentCharacter >= 'A' && currentCharacter <= 'Z')) {
 
 799         buf.append(currentCharacter);
 
 800         currentCharacter = source[currentPosition++];
 
 802       if (buf.length() >= 3 && buf.length() <= 7) {
 
 803         char[] data = buf.toString().toCharArray();
 
 805         switch (data.length) {
 
 808           if ((data[index] == 'i') && (data[++index] == 'n') && (data[++index] == 't')) {
 
 810             tempToken = TokenNameintCAST;
 
 815           if ((data[index] == 'b') && (data[++index] == 'o') && (data[++index] == 'o') && (data[++index] == 'l')) {
 
 817             tempToken = TokenNameboolCAST;
 
 820             if ((data[index] == 'r') && (data[++index] == 'e') && (data[++index] == 'a') && (data[++index] == 'l')) {
 
 822               tempToken = TokenNamedoubleCAST;
 
 828           if ((data[index] == 'a') && (data[++index] == 'r') && (data[++index] == 'r') && (data[++index] == 'a')
 
 829               && (data[++index] == 'y')) {
 
 831             tempToken = TokenNamearrayCAST;
 
 834             if ((data[index] == 'u') && (data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 'e')
 
 835                 && (data[++index] == 't')) {
 
 837               tempToken = TokenNameunsetCAST;
 
 840               if ((data[index] == 'f') && (data[++index] == 'l') && (data[++index] == 'o') && (data[++index] == 'a')
 
 841                   && (data[++index] == 't')) {
 
 843                 tempToken = TokenNamedoubleCAST;
 
 849           // object string double
 
 850           if ((data[index] == 'o') && (data[++index] == 'b') && (data[++index] == 'j') && (data[++index] == 'e')
 
 851               && (data[++index] == 'c') && (data[++index] == 't')) {
 
 853             tempToken = TokenNameobjectCAST;
 
 856             if ((data[index] == 's') && (data[++index] == 't') && (data[++index] == 'r') && (data[++index] == 'i')
 
 857                 && (data[++index] == 'n') && (data[++index] == 'g')) {
 
 859               tempToken = TokenNamestringCAST;
 
 862               if ((data[index] == 'd') && (data[++index] == 'o') && (data[++index] == 'u') && (data[++index] == 'b')
 
 863                   && (data[++index] == 'l') && (data[++index] == 'e')) {
 
 865                 tempToken = TokenNamedoubleCAST;
 
 872           if ((data[index] == 'b') && (data[++index] == 'o') && (data[++index] == 'o') && (data[++index] == 'l')
 
 873               && (data[++index] == 'e') && (data[++index] == 'a') && (data[++index] == 'n')) {
 
 875             tempToken = TokenNameboolCAST;
 
 878             if ((data[index] == 'i') && (data[++index] == 'n') && (data[++index] == 't') && (data[++index] == 'e')
 
 879                 && (data[++index] == 'g') && (data[++index] == 'e') && (data[++index] == 'r')) {
 
 881               tempToken = TokenNameintCAST;
 
 887           while (currentCharacter == ' ' || currentCharacter == '\t') {
 
 888             currentCharacter = source[currentPosition++];
 
 890           if (currentCharacter == ')') {
 
 895     } catch (IndexOutOfBoundsException e) {
 
 897     currentCharacter = tempCharacter;
 
 898     currentPosition = tempPosition;
 
 899     return TokenNameLPAREN;
 
 902   public void consumeStringInterpolated() throws InvalidInputException {
 
 904       // consume next character
 
 905       unicodeAsBackSlash = false;
 
 906       currentCharacter = source[currentPosition++];
 
 907       //                if (((currentCharacter = source[currentPosition++]) == '\\')
 
 908       //                  && (source[currentPosition] == 'u')) {
 
 909       //                  getNextUnicodeChar();
 
 911       //                  if (withoutUnicodePtr != 0) {
 
 912       //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
 
 916       while (currentCharacter != '`') {
 
 917         /** ** in PHP \r and \n are valid in string literals *** */
 
 918         //                if ((currentCharacter == '\n')
 
 919         //                  || (currentCharacter == '\r')) {
 
 920         //                  // relocate if finding another quote fairly close: thus unicode
 
 921         // '/u000D' will be fully consumed
 
 922         //                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
 
 923         //                    if (currentPosition + lookAhead == source.length)
 
 925         //                    if (source[currentPosition + lookAhead] == '\n')
 
 927         //                    if (source[currentPosition + lookAhead] == '\"') {
 
 928         //                      currentPosition += lookAhead + 1;
 
 932         //                  throw new InvalidInputException(INVALID_CHAR_IN_STRING);
 
 934         if (currentCharacter == '\\') {
 
 935           int escapeSize = currentPosition;
 
 936           boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
 
 937           //scanEscapeCharacter make a side effect on this value and we need
 
 938           // the previous value few lines down this one
 
 939           scanDoubleQuotedEscapeCharacter();
 
 940           escapeSize = currentPosition - escapeSize;
 
 941           if (withoutUnicodePtr == 0) {
 
 942             //buffer all the entries that have been left aside....
 
 943             withoutUnicodePtr = currentPosition - escapeSize - 1 - startPosition;
 
 944             System.arraycopy(source, startPosition, withoutUnicodeBuffer, 1, withoutUnicodePtr);
 
 945             withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 946           } else { //overwrite the / in the buffer
 
 947             withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
 
 948             if (backSlashAsUnicodeInString) { //there are TWO \ in the stream
 
 949               // where only one is correct
 
 953         } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
 954           if (recordLineSeparator) {
 
 958         // consume next character
 
 959         unicodeAsBackSlash = false;
 
 960         currentCharacter = source[currentPosition++];
 
 961         //                  if (((currentCharacter = source[currentPosition++]) == '\\')
 
 962         //                    && (source[currentPosition] == 'u')) {
 
 963         //                    getNextUnicodeChar();
 
 965         if (withoutUnicodePtr != 0) {
 
 966           withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
 970     } catch (IndexOutOfBoundsException e) {
 
 971       //    reset end position for error reporting
 
 972       currentPosition -= 2;
 
 973       throw new InvalidInputException(UNTERMINATED_STRING);
 
 974     } catch (InvalidInputException e) {
 
 975       if (e.getMessage().equals(INVALID_ESCAPE)) {
 
 976         // relocate if finding another quote fairly close: thus unicode
 
 977         // '/u000D' will be fully consumed
 
 978         for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
 
 979           if (currentPosition + lookAhead == source.length)
 
 981           if (source[currentPosition + lookAhead] == '\n')
 
 983           if (source[currentPosition + lookAhead] == '`') {
 
 984             currentPosition += lookAhead + 1;
 
 991     if (checkNonExternalizedStringLiterals) { // check for presence of NLS tags
 
 992       // //$NON-NLS-?$ where ? is an
 
 994       if (currentLine == null) {
 
 995         currentLine = new NLSLine();
 
 996         lines.add(currentLine);
 
 998       currentLine.add(new StringLiteral(getCurrentTokenSourceString(), startPosition, currentPosition - 1));
 
1002   public void consumeStringConstant() throws InvalidInputException {
 
1004       // consume next character
 
1005       unicodeAsBackSlash = false;
 
1006       currentCharacter = source[currentPosition++];
 
1007       //                if (((currentCharacter = source[currentPosition++]) == '\\')
 
1008       //                  && (source[currentPosition] == 'u')) {
 
1009       //                  getNextUnicodeChar();
 
1011       //                  if (withoutUnicodePtr != 0) {
 
1012       //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
 
1013       //                      currentCharacter;
 
1016       while (currentCharacter != '\'') {
 
1017         /** ** in PHP \r and \n are valid in string literals *** */
 
1018         //                  if ((currentCharacter == '\n')
 
1019         //                    || (currentCharacter == '\r')) {
 
1020         //                    // relocate if finding another quote fairly close: thus unicode
 
1021         // '/u000D' will be fully consumed
 
1022         //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
 
1023         //                      if (currentPosition + lookAhead == source.length)
 
1025         //                      if (source[currentPosition + lookAhead] == '\n')
 
1027         //                      if (source[currentPosition + lookAhead] == '\"') {
 
1028         //                        currentPosition += lookAhead + 1;
 
1032         //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
 
1034         if (currentCharacter == '\\') {
 
1035           int escapeSize = currentPosition;
 
1036           boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
 
1037           //scanEscapeCharacter make a side effect on this value and we need
 
1038           // the previous value few lines down this one
 
1039           scanSingleQuotedEscapeCharacter();
 
1040           escapeSize = currentPosition - escapeSize;
 
1041           if (withoutUnicodePtr == 0) {
 
1042             //buffer all the entries that have been left aside....
 
1043             withoutUnicodePtr = currentPosition - escapeSize - 1 - startPosition;
 
1044             System.arraycopy(source, startPosition, withoutUnicodeBuffer, 1, withoutUnicodePtr);
 
1045             withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
1046           } else { //overwrite the / in the buffer
 
1047             withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
 
1048             if (backSlashAsUnicodeInString) { //there are TWO \ in the stream
 
1049               // where only one is correct
 
1050               withoutUnicodePtr--;
 
1053         } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1054           if (recordLineSeparator) {
 
1055             pushLineSeparator();
 
1058         // consume next character
 
1059         unicodeAsBackSlash = false;
 
1060         currentCharacter = source[currentPosition++];
 
1061         //                  if (((currentCharacter = source[currentPosition++]) == '\\')
 
1062         //                    && (source[currentPosition] == 'u')) {
 
1063         //                    getNextUnicodeChar();
 
1065         if (withoutUnicodePtr != 0) {
 
1066           withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
1070     } catch (IndexOutOfBoundsException e) {
 
1071       // reset end position for error reporting
 
1072       currentPosition -= 2;
 
1073       throw new InvalidInputException(UNTERMINATED_STRING);
 
1074     } catch (InvalidInputException e) {
 
1075       if (e.getMessage().equals(INVALID_ESCAPE)) {
 
1076         // relocate if finding another quote fairly close: thus unicode
 
1077         // '/u000D' will be fully consumed
 
1078         for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
 
1079           if (currentPosition + lookAhead == source.length)
 
1081           if (source[currentPosition + lookAhead] == '\n')
 
1083           if (source[currentPosition + lookAhead] == '\'') {
 
1084             currentPosition += lookAhead + 1;
 
1091     if (checkNonExternalizedStringLiterals) { // check for presence of NLS tags
 
1092       // //$NON-NLS-?$ where ? is an
 
1094       if (currentLine == null) {
 
1095         currentLine = new NLSLine();
 
1096         lines.add(currentLine);
 
1098       currentLine.add(new StringLiteral(getCurrentTokenSourceString(), startPosition, currentPosition - 1));
 
1102   public void consumeStringLiteral() throws InvalidInputException {
 
1104       // consume next character
 
1105       unicodeAsBackSlash = false;
 
1106       currentCharacter = source[currentPosition++];
 
1107       //                if (((currentCharacter = source[currentPosition++]) == '\\')
 
1108       //                  && (source[currentPosition] == 'u')) {
 
1109       //                  getNextUnicodeChar();
 
1111       //                  if (withoutUnicodePtr != 0) {
 
1112       //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
 
1113       //                      currentCharacter;
 
1116       while (currentCharacter != '"') {
 
1117         /** ** in PHP \r and \n are valid in string literals *** */
 
1118         //                  if ((currentCharacter == '\n')
 
1119         //                    || (currentCharacter == '\r')) {
 
1120         //                    // relocate if finding another quote fairly close: thus unicode
 
1121         // '/u000D' will be fully consumed
 
1122         //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
 
1123         //                      if (currentPosition + lookAhead == source.length)
 
1125         //                      if (source[currentPosition + lookAhead] == '\n')
 
1127         //                      if (source[currentPosition + lookAhead] == '\"') {
 
1128         //                        currentPosition += lookAhead + 1;
 
1132         //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
 
1134         if (currentCharacter == '\\') {
 
1135           int escapeSize = currentPosition;
 
1136           boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
 
1137           //scanEscapeCharacter make a side effect on this value and we need
 
1138           // the previous value few lines down this one
 
1139           scanDoubleQuotedEscapeCharacter();
 
1140           escapeSize = currentPosition - escapeSize;
 
1141           if (withoutUnicodePtr == 0) {
 
1142             //buffer all the entries that have been left aside....
 
1143             withoutUnicodePtr = currentPosition - escapeSize - 1 - startPosition;
 
1144             System.arraycopy(source, startPosition, withoutUnicodeBuffer, 1, withoutUnicodePtr);
 
1145             withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
1146           } else { //overwrite the / in the buffer
 
1147             withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
 
1148             if (backSlashAsUnicodeInString) { //there are TWO \ in the stream
 
1149               // where only one is correct
 
1150               withoutUnicodePtr--;
 
1153         } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1154           if (recordLineSeparator) {
 
1155             pushLineSeparator();
 
1158         // consume next character
 
1159         unicodeAsBackSlash = false;
 
1160         currentCharacter = source[currentPosition++];
 
1161         //                  if (((currentCharacter = source[currentPosition++]) == '\\')
 
1162         //                    && (source[currentPosition] == 'u')) {
 
1163         //                    getNextUnicodeChar();
 
1165         if (withoutUnicodePtr != 0) {
 
1166           withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
1170     } catch (IndexOutOfBoundsException e) {
 
1171       //    reset end position for error reporting
 
1172       currentPosition -= 2;
 
1173       throw new InvalidInputException(UNTERMINATED_STRING);
 
1174     } catch (InvalidInputException e) {
 
1175       if (e.getMessage().equals(INVALID_ESCAPE)) {
 
1176         // relocate if finding another quote fairly close: thus unicode
 
1177         // '/u000D' will be fully consumed
 
1178         for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
 
1179           if (currentPosition + lookAhead == source.length)
 
1181           if (source[currentPosition + lookAhead] == '\n')
 
1183           if (source[currentPosition + lookAhead] == '\"') {
 
1184             currentPosition += lookAhead + 1;
 
1191     if (checkNonExternalizedStringLiterals) { // check for presence of NLS tags
 
1192       // //$NON-NLS-?$ where ? is an
 
1194       if (currentLine == null) {
 
1195         currentLine = new NLSLine();
 
1196         lines.add(currentLine);
 
1198       currentLine.add(new StringLiteral(getCurrentTokenSourceString(), startPosition, currentPosition - 1));
 
1202   public int getNextToken() throws InvalidInputException {
 
1204       return getInlinedHTML(currentPosition);
 
1207       this.wasAcr = false;
 
1209         jumpOverMethodBody();
 
1211         return currentPosition > source.length ? TokenNameEOF : TokenNameRBRACE;
 
1215           withoutUnicodePtr = 0;
 
1216           //start with a new token
 
1217           char encapsedChar = ' ';
 
1218           if (!encapsedStringStack.isEmpty()) {
 
1219             encapsedChar = ((Character) encapsedStringStack.peek()).charValue();
 
1221           if (encapsedChar != '$' && encapsedChar != ' ') {
 
1222             currentCharacter = source[currentPosition++];
 
1223             if (currentCharacter == encapsedChar) {
 
1224               switch (currentCharacter) {
 
1226                 return TokenNameEncapsedString0;
 
1228                 return TokenNameEncapsedString1;
 
1230                 return TokenNameEncapsedString2;
 
1233             while (currentCharacter != encapsedChar) {
 
1234               /** ** in PHP \r and \n are valid in string literals *** */
 
1235               switch (currentCharacter) {
 
1237                 int escapeSize = currentPosition;
 
1238                 boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
 
1239                 //scanEscapeCharacter make a side effect on this value and
 
1240                 // we need the previous value few lines down this one
 
1241                 scanDoubleQuotedEscapeCharacter();
 
1242                 escapeSize = currentPosition - escapeSize;
 
1243                 if (withoutUnicodePtr == 0) {
 
1244                   //buffer all the entries that have been left aside....
 
1245                   withoutUnicodePtr = currentPosition - escapeSize - 1 - startPosition;
 
1246                   System.arraycopy(source, startPosition, withoutUnicodeBuffer, 1, withoutUnicodePtr);
 
1247                   withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
1248                 } else { //overwrite the / in the buffer
 
1249                   withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
 
1250                   if (backSlashAsUnicodeInString) { //there are TWO \ in
 
1251                     withoutUnicodePtr--;
 
1257                 if (recordLineSeparator) {
 
1258                   pushLineSeparator();
 
1262                 if (isPHPIdentifierStart(source[currentPosition]) || source[currentPosition] == '{') {
 
1264                   encapsedStringStack.push(new Character('$'));
 
1265                   return TokenNameSTRING;
 
1269                 if (source[currentPosition] == '$') { // CURLY_OPEN
 
1271                   encapsedStringStack.push(new Character('$'));
 
1272                   return TokenNameSTRING;
 
1275               // consume next character
 
1276               unicodeAsBackSlash = false;
 
1277               currentCharacter = source[currentPosition++];
 
1278               if (withoutUnicodePtr != 0) {
 
1279                 withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
1284             return TokenNameSTRING;
 
1286           // ---------Consume white space and handles startPosition---------
 
1287           int whiteStart = currentPosition;
 
1288           startPosition = currentPosition;
 
1289           currentCharacter = source[currentPosition++];
 
1290           if (encapsedChar == '$') {
 
1291             switch (currentCharacter) {
 
1293               currentCharacter = source[currentPosition++];
 
1294               return TokenNameSTRING;
 
1296               if (encapsedChar == '$') {
 
1297                 if (getNextChar('$'))
 
1298                   return TokenNameLBRACE_DOLLAR;
 
1300               return TokenNameLBRACE;
 
1302               return TokenNameRBRACE;
 
1304               return TokenNameLBRACKET;
 
1306               return TokenNameRBRACKET;
 
1308               if (tokenizeStrings) {
 
1309                 consumeStringConstant();
 
1310                 return TokenNameStringSingleQuote;
 
1312               return TokenNameEncapsedString1;
 
1314               return TokenNameEncapsedString2;
 
1316               if (tokenizeStrings) {
 
1317                 consumeStringInterpolated();
 
1318                 return TokenNameStringInterpolated;
 
1320               return TokenNameEncapsedString0;
 
1322               if (getNextChar('>'))
 
1323                 return TokenNameMINUS_GREATER;
 
1324               return TokenNameSTRING;
 
1326               if (currentCharacter == '$') {
 
1327                 int oldPosition = currentPosition;
 
1329                   currentCharacter = source[currentPosition++];
 
1330                   if (currentCharacter == '{') {
 
1331                     return TokenNameDOLLAR_LBRACE;
 
1333                   if (isPHPIdentifierStart(currentCharacter)) {
 
1334                     return scanIdentifierOrKeyword(true);
 
1336                     currentPosition = oldPosition;
 
1337                     return TokenNameSTRING;
 
1339                 } catch (IndexOutOfBoundsException e) {
 
1340                   currentPosition = oldPosition;
 
1341                   return TokenNameSTRING;
 
1344               if (isPHPIdentifierStart(currentCharacter))
 
1345                 return scanIdentifierOrKeyword(false);
 
1346               if (Character.isDigit(currentCharacter))
 
1347                 return scanNumber(false);
 
1348               return TokenNameERROR;
 
1351           //          boolean isWhiteSpace;
 
1353           while ((currentCharacter == ' ') || Character.isWhitespace(currentCharacter)) {
 
1354             startPosition = currentPosition;
 
1355             currentCharacter = source[currentPosition++];
 
1356             //            if (((currentCharacter = source[currentPosition++]) == '\\')
 
1357             //              && (source[currentPosition] == 'u')) {
 
1358             //              isWhiteSpace = jumpOverUnicodeWhiteSpace();
 
1360             if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1361               checkNonExternalizeString();
 
1362               if (recordLineSeparator) {
 
1363                 pushLineSeparator();
 
1368             //            isWhiteSpace = (currentCharacter == ' ')
 
1369             //                || Character.isWhitespace(currentCharacter);
 
1372           if (tokenizeWhiteSpace && (whiteStart != currentPosition - 1)) {
 
1373             // reposition scanner in case we are interested by spaces as tokens
 
1375             startPosition = whiteStart;
 
1376             return TokenNameWHITESPACE;
 
1378           //little trick to get out in the middle of a source compuation
 
1379           if (currentPosition > eofPosition)
 
1380             return TokenNameEOF;
 
1381           // ---------Identify the next token-------------
 
1382           switch (currentCharacter) {
 
1384             return getCastOrParen();
 
1386             return TokenNameRPAREN;
 
1388             return TokenNameLBRACE;
 
1390             return TokenNameRBRACE;
 
1392             return TokenNameLBRACKET;
 
1394             return TokenNameRBRACKET;
 
1396             return TokenNameSEMICOLON;
 
1398             return TokenNameCOMMA;
 
1400             if (getNextChar('='))
 
1401               return TokenNameDOT_EQUAL;
 
1402             if (getNextCharAsDigit())
 
1403               return scanNumber(true);
 
1404             return TokenNameDOT;
 
1407             if ((test = getNextChar('+', '=')) == 0)
 
1408               return TokenNamePLUS_PLUS;
 
1410               return TokenNamePLUS_EQUAL;
 
1411             return TokenNamePLUS;
 
1415             if ((test = getNextChar('-', '=')) == 0)
 
1416               return TokenNameMINUS_MINUS;
 
1418               return TokenNameMINUS_EQUAL;
 
1419             if (getNextChar('>'))
 
1420               return TokenNameMINUS_GREATER;
 
1421             return TokenNameMINUS;
 
1424             if (getNextChar('='))
 
1425               return TokenNameTWIDDLE_EQUAL;
 
1426             return TokenNameTWIDDLE;
 
1428             if (getNextChar('=')) {
 
1429               if (getNextChar('=')) {
 
1430                 return TokenNameNOT_EQUAL_EQUAL;
 
1432               return TokenNameNOT_EQUAL;
 
1434             return TokenNameNOT;
 
1436             if (getNextChar('='))
 
1437               return TokenNameMULTIPLY_EQUAL;
 
1438             return TokenNameMULTIPLY;
 
1440             if (getNextChar('='))
 
1441               return TokenNameREMAINDER_EQUAL;
 
1442             return TokenNameREMAINDER;
 
1444             int oldPosition = currentPosition;
 
1446               currentCharacter = source[currentPosition++];
 
1447             } catch (IndexOutOfBoundsException e) {
 
1448               currentPosition = oldPosition;
 
1449               return TokenNameLESS;
 
1451             switch (currentCharacter) {
 
1453               return TokenNameLESS_EQUAL;
 
1455               return TokenNameNOT_EQUAL;
 
1457               if (getNextChar('='))
 
1458                 return TokenNameLEFT_SHIFT_EQUAL;
 
1459               if (getNextChar('<')) {
 
1460                 currentCharacter = source[currentPosition++];
 
1461                 while (Character.isWhitespace(currentCharacter)) {
 
1462                   currentCharacter = source[currentPosition++];
 
1464                 int heredocStart = currentPosition - 1;
 
1465                 int heredocLength = 0;
 
1466                 if (isPHPIdentifierStart(currentCharacter)) {
 
1467                   currentCharacter = source[currentPosition++];
 
1469                   return TokenNameERROR;
 
1471                 while (isPHPIdentifierPart(currentCharacter)) {
 
1472                   currentCharacter = source[currentPosition++];
 
1474                 heredocLength = currentPosition - heredocStart - 1;
 
1475                 // heredoc end-tag determination
 
1476                 boolean endTag = true;
 
1479                   ch = source[currentPosition++];
 
1480                   if (ch == '\r' || ch == '\n') {
 
1481                     if (recordLineSeparator) {
 
1482                       pushLineSeparator();
 
1486                     for (int i = 0; i < heredocLength; i++) {
 
1487                       if (source[currentPosition + i] != source[heredocStart + i]) {
 
1493                       currentPosition += heredocLength - 1;
 
1494                       currentCharacter = source[currentPosition++];
 
1495                       break; // do...while loop
 
1501                 return TokenNameHEREDOC;
 
1503               return TokenNameLEFT_SHIFT;
 
1505             currentPosition = oldPosition;
 
1506             return TokenNameLESS;
 
1510             if ((test = getNextChar('=', '>')) == 0)
 
1511               return TokenNameGREATER_EQUAL;
 
1513               if ((test = getNextChar('=', '>')) == 0)
 
1514                 return TokenNameRIGHT_SHIFT_EQUAL;
 
1515               return TokenNameRIGHT_SHIFT;
 
1517             return TokenNameGREATER;
 
1520             if (getNextChar('=')) {
 
1521               if (getNextChar('=')) {
 
1522                 return TokenNameEQUAL_EQUAL_EQUAL;
 
1524               return TokenNameEQUAL_EQUAL;
 
1526             if (getNextChar('>'))
 
1527               return TokenNameEQUAL_GREATER;
 
1528             return TokenNameEQUAL;
 
1531             if ((test = getNextChar('&', '=')) == 0)
 
1532               return TokenNameAND_AND;
 
1534               return TokenNameAND_EQUAL;
 
1535             return TokenNameAND;
 
1539             if ((test = getNextChar('|', '=')) == 0)
 
1540               return TokenNameOR_OR;
 
1542               return TokenNameOR_EQUAL;
 
1546             if (getNextChar('='))
 
1547               return TokenNameXOR_EQUAL;
 
1548             return TokenNameXOR;
 
1550             if (getNextChar('>')) {
 
1552               if (currentPosition == source.length) {
 
1554                 return TokenNameINLINE_HTML;
 
1556               return getInlinedHTML(currentPosition - 2);
 
1558             return TokenNameQUESTION;
 
1560             if (getNextChar(':'))
 
1561               return TokenNamePAAMAYIM_NEKUDOTAYIM;
 
1562             return TokenNameCOLON;
 
1566             consumeStringConstant();
 
1567             return TokenNameStringSingleQuote;
 
1569             if (tokenizeStrings) {
 
1570               consumeStringLiteral();
 
1571               return TokenNameStringDoubleQuote;
 
1573             return TokenNameEncapsedString2;
 
1575             if (tokenizeStrings) {
 
1576               consumeStringInterpolated();
 
1577               return TokenNameStringInterpolated;
 
1579             return TokenNameEncapsedString0;
 
1582             char startChar = currentCharacter;
 
1583             if (getNextChar('=') && startChar == '/') {
 
1584               return TokenNameDIVIDE_EQUAL;
 
1587             if ((startChar == '#') || (test = getNextChar('/', '*')) == 0) {
 
1589               this.lastCommentLinePosition = this.currentPosition;
 
1590               int endPositionForLineComment = 0;
 
1591               try { //get the next char
 
1592                 currentCharacter = source[currentPosition++];
 
1593                 //                    if (((currentCharacter = source[currentPosition++])
 
1595                 //                      && (source[currentPosition] == 'u')) {
 
1596                 //                      //-------------unicode traitement ------------
 
1597                 //                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
1598                 //                      currentPosition++;
 
1599                 //                      while (source[currentPosition] == 'u') {
 
1600                 //                        currentPosition++;
 
1603                 //                        Character.getNumericValue(source[currentPosition++]))
 
1607                 //                          Character.getNumericValue(source[currentPosition++]))
 
1611                 //                          Character.getNumericValue(source[currentPosition++]))
 
1615                 //                          Character.getNumericValue(source[currentPosition++]))
 
1619                 // InvalidInputException(INVALID_UNICODE_ESCAPE);
 
1621                 //                        currentCharacter =
 
1622                 //                          (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
1625                 //handle the \\u case manually into comment
 
1626                 //                    if (currentCharacter == '\\') {
 
1627                 //                      if (source[currentPosition] == '\\')
 
1628                 //                        currentPosition++;
 
1629                 //                    } //jump over the \\
 
1630                 boolean isUnicode = false;
 
1631                 while (currentCharacter != '\r' && currentCharacter != '\n') {
 
1632                   this.lastCommentLinePosition = this.currentPosition;
 
1633                   if (currentCharacter == '?') {
 
1634                     if (getNextChar('>')) {
 
1635                       startPosition = currentPosition - 2;
 
1637                       return TokenNameINLINE_HTML;
 
1642                   currentCharacter = source[currentPosition++];
 
1643                   //                      if (((currentCharacter = source[currentPosition++])
 
1645                   //                        && (source[currentPosition] == 'u')) {
 
1646                   //                        isUnicode = true;
 
1647                   //                        //-------------unicode traitement ------------
 
1648                   //                        int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
1649                   //                        currentPosition++;
 
1650                   //                        while (source[currentPosition] == 'u') {
 
1651                   //                          currentPosition++;
 
1654                   //                          Character.getNumericValue(source[currentPosition++]))
 
1658                   //                            Character.getNumericValue(
 
1659                   //                              source[currentPosition++]))
 
1663                   //                            Character.getNumericValue(
 
1664                   //                              source[currentPosition++]))
 
1668                   //                            Character.getNumericValue(
 
1669                   //                              source[currentPosition++]))
 
1673                   // InvalidInputException(INVALID_UNICODE_ESCAPE);
 
1675                   //                          currentCharacter =
 
1676                   //                            (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
1679                   //handle the \\u case manually into comment
 
1680                   //                      if (currentCharacter == '\\') {
 
1681                   //                        if (source[currentPosition] == '\\')
 
1682                   //                          currentPosition++;
 
1683                   //                      } //jump over the \\
 
1686                   endPositionForLineComment = currentPosition - 6;
 
1688                   endPositionForLineComment = currentPosition - 1;
 
1690                 //                    recordComment(false);
 
1691                 recordComment(TokenNameCOMMENT_LINE);
 
1692                 if (this.taskTags != null)
 
1693                   checkTaskTag(this.startPosition, this.currentPosition);
 
1694                 if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1695                   checkNonExternalizeString();
 
1696                   if (recordLineSeparator) {
 
1698                       pushUnicodeLineSeparator();
 
1700                       pushLineSeparator();
 
1706                 if (tokenizeComments) {
 
1708                     currentPosition = endPositionForLineComment;
 
1709                     // reset one character behind
 
1711                   return TokenNameCOMMENT_LINE;
 
1713               } catch (IndexOutOfBoundsException e) { //an eof will them
 
1715                 if (tokenizeComments) {
 
1717                   // reset one character behind
 
1718                   return TokenNameCOMMENT_LINE;
 
1724               //traditional and annotation comment
 
1725               boolean isJavadoc = false, star = false;
 
1726               // consume next character
 
1727               unicodeAsBackSlash = false;
 
1728               currentCharacter = source[currentPosition++];
 
1729               //                  if (((currentCharacter = source[currentPosition++]) ==
 
1731               //                    && (source[currentPosition] == 'u')) {
 
1732               //                    getNextUnicodeChar();
 
1734               //                    if (withoutUnicodePtr != 0) {
 
1735               //                      withoutUnicodeBuffer[++withoutUnicodePtr] =
 
1736               //                        currentCharacter;
 
1739               if (currentCharacter == '*') {
 
1743               if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1744                 checkNonExternalizeString();
 
1745                 if (recordLineSeparator) {
 
1746                   pushLineSeparator();
 
1751               try { //get the next char
 
1752                 currentCharacter = source[currentPosition++];
 
1753                 //                    if (((currentCharacter = source[currentPosition++])
 
1755                 //                      && (source[currentPosition] == 'u')) {
 
1756                 //                      //-------------unicode traitement ------------
 
1757                 //                      getNextUnicodeChar();
 
1759                 //handle the \\u case manually into comment
 
1760                 //                    if (currentCharacter == '\\') {
 
1761                 //                      if (source[currentPosition] == '\\')
 
1762                 //                        currentPosition++;
 
1763                 //                      //jump over the \\
 
1765                 // empty comment is not a javadoc /**/
 
1766                 if (currentCharacter == '/') {
 
1769                 //loop until end of comment */
 
1770                 while ((currentCharacter != '/') || (!star)) {
 
1771                   if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1772                     checkNonExternalizeString();
 
1773                     if (recordLineSeparator) {
 
1774                       pushLineSeparator();
 
1779                   star = currentCharacter == '*';
 
1781                   currentCharacter = source[currentPosition++];
 
1782                   //                      if (((currentCharacter = source[currentPosition++])
 
1784                   //                        && (source[currentPosition] == 'u')) {
 
1785                   //                        //-------------unicode traitement ------------
 
1786                   //                        getNextUnicodeChar();
 
1788                   //handle the \\u case manually into comment
 
1789                   //                      if (currentCharacter == '\\') {
 
1790                   //                        if (source[currentPosition] == '\\')
 
1791                   //                          currentPosition++;
 
1792                   //                      } //jump over the \\
 
1794                 //recordComment(isJavadoc);
 
1796                   recordComment(TokenNameCOMMENT_PHPDOC);
 
1798                   recordComment(TokenNameCOMMENT_BLOCK);
 
1801                 if (tokenizeComments) {
 
1803                     return TokenNameCOMMENT_PHPDOC;
 
1804                   return TokenNameCOMMENT_BLOCK;
 
1807                 if (this.taskTags != null) {
 
1808                   checkTaskTag(this.startPosition, this.currentPosition);
 
1810               } catch (IndexOutOfBoundsException e) {
 
1811                 //                  reset end position for error reporting
 
1812                 currentPosition -= 2;
 
1813                 throw new InvalidInputException(UNTERMINATED_COMMENT);
 
1817             return TokenNameDIVIDE;
 
1821               return TokenNameEOF;
 
1822             //the atEnd may not be <currentPosition == source.length> if
 
1823             // source is only some part of a real (external) stream
 
1824             throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
 
1826             if (currentCharacter == '$') {
 
1827               int oldPosition = currentPosition;
 
1829                 currentCharacter = source[currentPosition++];
 
1830                 if (isPHPIdentifierStart(currentCharacter)) {
 
1831                   return scanIdentifierOrKeyword(true);
 
1833                   currentPosition = oldPosition;
 
1834                   return TokenNameDOLLAR;
 
1836               } catch (IndexOutOfBoundsException e) {
 
1837                 currentPosition = oldPosition;
 
1838                 return TokenNameDOLLAR;
 
1841             if (isPHPIdentifierStart(currentCharacter))
 
1842               return scanIdentifierOrKeyword(false);
 
1843             if (Character.isDigit(currentCharacter))
 
1844               return scanNumber(false);
 
1845             return TokenNameERROR;
 
1848       } //-----------------end switch while try--------------------
 
1849       catch (IndexOutOfBoundsException e) {
 
1852     return TokenNameEOF;
 
1855   private int getInlinedHTML(int start) throws InvalidInputException {
 
1856     int token = getInlinedHTMLToken(start);
 
1857     if (token == TokenNameINLINE_HTML) {
 
1858       //                Stack stack = new Stack();
 
1859       //                // scan html for errors
 
1860       //                Source inlinedHTMLSource = new Source(new String(source, startPosition, currentPosition - startPosition));
 
1861       //                int lastPHPEndPos=0;
 
1862       //                for (Iterator i=inlinedHTMLSource.getNextTagIterator(0); i.hasNext();) {
 
1863       //                    Tag tag=(Tag)i.next();
 
1865       //                    if (tag instanceof StartTag) {
 
1866       //                        StartTag startTag=(StartTag)tag;
 
1867       //                      // System.out.println("startTag: "+tag);
 
1868       //                        if (startTag.isServerTag()) {
 
1869       //                          // TODO : what to do with a server tag ?
 
1871       //                            // do whatever with HTML start tag
 
1872       //                            // use startTag.getElement() to find the element corresponding
 
1873       //                            // to this start tag which may be useful if you implement code
 
1875       //                                stack.push(startTag);
 
1878       //                        EndTag endTag=(EndTag)tag;
 
1879       //                        StartTag stag = (StartTag) stack.peek();
 
1880       //// System.out.println("endTag: "+tag);
 
1881       //                        // do whatever with HTML end tag.
 
1890    * @throws InvalidInputException
 
1892   private int getInlinedHTMLToken(int start) throws InvalidInputException {
 
1893     if (currentPosition > source.length) {
 
1894       currentPosition = source.length;
 
1895       return TokenNameEOF;
 
1897     startPosition = start;
 
1900         currentCharacter = source[currentPosition++];
 
1901         if (currentCharacter == '<') {
 
1902           if (getNextChar('?')) {
 
1903             currentCharacter = source[currentPosition++];
 
1904             if ((currentCharacter != 'P') && (currentCharacter != 'p')) {
 
1906               // (currentCharacter == ' ') || Character.isWhitespace(currentCharacter)) {
 
1908               if (ignorePHPOneLiner) {
 
1909                 if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
 
1911                   return TokenNameINLINE_HTML;
 
1915                 return TokenNameINLINE_HTML;
 
1918               //              boolean phpStart = (currentCharacter == 'P') || (currentCharacter == 'p');
 
1920               int test = getNextChar('H', 'h');
 
1922                 test = getNextChar('P', 'p');
 
1925                   if (ignorePHPOneLiner) {
 
1926                     if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
 
1928                       return TokenNameINLINE_HTML;
 
1932                     return TokenNameINLINE_HTML;
 
1940         if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
 
1941           if (recordLineSeparator) {
 
1942             pushLineSeparator();
 
1947       } //-----------------while--------------------
 
1949       return TokenNameINLINE_HTML;
 
1950     } //-----------------try--------------------
 
1951     catch (IndexOutOfBoundsException e) {
 
1952       startPosition = start;
 
1956     return TokenNameINLINE_HTML;
 
1962   private int lookAheadLinePHPTag() {
 
1963     // check if the PHP is only in this line (for CodeFormatter)
 
1964     int currentPositionInLine = currentPosition;
 
1965     char previousCharInLine = ' ';
 
1966     char currentCharInLine = ' ';
 
1967     boolean singleQuotedStringActive = false;
 
1968     boolean doubleQuotedStringActive = false;
 
1971       // look ahead in this line
 
1973         previousCharInLine = currentCharInLine;
 
1974         currentCharInLine = source[currentPositionInLine++];
 
1975         switch (currentCharInLine) {
 
1977           if (previousCharInLine == '?') {
 
1978             // update the scanner's current Position in the source
 
1979             currentPosition = currentPositionInLine;
 
1980             // use as "dummy" token
 
1981             return TokenNameEOF;
 
1985           if (doubleQuotedStringActive) {
 
1986             if (previousCharInLine != '\\') {
 
1987               doubleQuotedStringActive = false;
 
1990             if (!singleQuotedStringActive) {
 
1991               doubleQuotedStringActive = true;
 
1996           if (singleQuotedStringActive) {
 
1997             if (previousCharInLine != '\\') {
 
1998               singleQuotedStringActive = false;
 
2001             if (!doubleQuotedStringActive) {
 
2002               singleQuotedStringActive = true;
 
2008           return TokenNameINLINE_HTML;
 
2010           if (!singleQuotedStringActive && !doubleQuotedStringActive) {
 
2012             return TokenNameINLINE_HTML;
 
2016           if (previousCharInLine == '/' && !singleQuotedStringActive && !doubleQuotedStringActive) {
 
2018             return TokenNameINLINE_HTML;
 
2022           if (previousCharInLine == '/' && !singleQuotedStringActive && !doubleQuotedStringActive) {
 
2024             return TokenNameINLINE_HTML;
 
2029     } catch (IndexOutOfBoundsException e) {
 
2031       currentPosition = currentPositionInLine;
 
2032       return TokenNameINLINE_HTML;
 
2036   //  public final void getNextUnicodeChar()
 
2037   //    throws IndexOutOfBoundsException, InvalidInputException {
 
2039   //    //handle the case of unicode.
 
2040   //    //when a unicode appears then we must use a buffer that holds char
 
2042   //    //At the end of this method currentCharacter holds the new visited char
 
2043   //    //and currentPosition points right next after it
 
2045   //    //ALL getNextChar.... ARE OPTIMIZED COPIES
 
2047   //    int c1 = 0, c2 = 0, c3 = 0, c4 = 0, unicodeSize = 6;
 
2048   //    currentPosition++;
 
2049   //    while (source[currentPosition] == 'u') {
 
2050   //      currentPosition++;
 
2054   //    if ((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
2056   //      || (c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
2058   //      || (c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
2060   //      || (c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
2062   //      throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
 
2064   //      currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
2065   //      //need the unicode buffer
 
2066   //      if (withoutUnicodePtr == 0) {
 
2067   //        //buffer all the entries that have been left aside....
 
2068   //        withoutUnicodePtr = currentPosition - unicodeSize - startPosition;
 
2069   //        System.arraycopy(
 
2072   //          withoutUnicodeBuffer,
 
2074   //          withoutUnicodePtr);
 
2076   //      //fill the buffer with the char
 
2077   //      withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2079   //    unicodeAsBackSlash = currentCharacter == '\\';
 
2082    * Tokenize a method body, assuming that curly brackets are properly balanced.
 
2084   public final void jumpOverMethodBody() {
 
2085     this.wasAcr = false;
 
2088       while (true) { //loop for jumping over comments
 
2089         // ---------Consume white space and handles startPosition---------
 
2090         boolean isWhiteSpace;
 
2092           startPosition = currentPosition;
 
2093           currentCharacter = source[currentPosition++];
 
2094           //          if (((currentCharacter = source[currentPosition++]) == '\\')
 
2095           //            && (source[currentPosition] == 'u')) {
 
2096           //            isWhiteSpace = jumpOverUnicodeWhiteSpace();
 
2098           if (recordLineSeparator && ((currentCharacter == '\r') || (currentCharacter == '\n')))
 
2099             pushLineSeparator();
 
2100           isWhiteSpace = Character.isWhitespace(currentCharacter);
 
2102         } while (isWhiteSpace);
 
2103         // -------consume token until } is found---------
 
2104         switch (currentCharacter) {
 
2115           test = getNextChar('\\');
 
2118               scanDoubleQuotedEscapeCharacter();
 
2119             } catch (InvalidInputException ex) {
 
2123             //                try { // consume next character
 
2124             unicodeAsBackSlash = false;
 
2125             currentCharacter = source[currentPosition++];
 
2126             //                  if (((currentCharacter = source[currentPosition++]) == '\\')
 
2127             //                    && (source[currentPosition] == 'u')) {
 
2128             //                    getNextUnicodeChar();
 
2130             if (withoutUnicodePtr != 0) {
 
2131               withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2134             //                } catch (InvalidInputException ex) {
 
2142             //              try { // consume next character
 
2143             unicodeAsBackSlash = false;
 
2144             currentCharacter = source[currentPosition++];
 
2145             //                if (((currentCharacter = source[currentPosition++]) == '\\')
 
2146             //                  && (source[currentPosition] == 'u')) {
 
2147             //                  getNextUnicodeChar();
 
2149             if (withoutUnicodePtr != 0) {
 
2150               withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2153             //              } catch (InvalidInputException ex) {
 
2155             while (currentCharacter != '"') {
 
2156               if (currentCharacter == '\r') {
 
2157                 if (source[currentPosition] == '\n')
 
2160                 // the string cannot go further that the line
 
2162               if (currentCharacter == '\n') {
 
2164                 // the string cannot go further that the line
 
2166               if (currentCharacter == '\\') {
 
2168                   scanDoubleQuotedEscapeCharacter();
 
2169                 } catch (InvalidInputException ex) {
 
2173               //                try { // consume next character
 
2174               unicodeAsBackSlash = false;
 
2175               currentCharacter = source[currentPosition++];
 
2176               //                  if (((currentCharacter = source[currentPosition++]) == '\\')
 
2177               //                    && (source[currentPosition] == 'u')) {
 
2178               //                    getNextUnicodeChar();
 
2180               if (withoutUnicodePtr != 0) {
 
2181                 withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2184               //                } catch (InvalidInputException ex) {
 
2187           } catch (IndexOutOfBoundsException e) {
 
2193           if ((test = getNextChar('/', '*')) == 0) {
 
2197               currentCharacter = source[currentPosition++];
 
2198               //                  if (((currentCharacter = source[currentPosition++]) ==
 
2200               //                    && (source[currentPosition] == 'u')) {
 
2201               //                    //-------------unicode traitement ------------
 
2202               //                    int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
2203               //                    currentPosition++;
 
2204               //                    while (source[currentPosition] == 'u') {
 
2205               //                      currentPosition++;
 
2208               //                      Character.getNumericValue(source[currentPosition++]))
 
2212               //                        Character.getNumericValue(source[currentPosition++]))
 
2216               //                        Character.getNumericValue(source[currentPosition++]))
 
2220               //                        Character.getNumericValue(source[currentPosition++]))
 
2223               //                      //error don't care of the value
 
2224               //                      currentCharacter = 'A';
 
2225               //                    } //something different from \n and \r
 
2227               //                      currentCharacter =
 
2228               //                        (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
2231               while (currentCharacter != '\r' && currentCharacter != '\n') {
 
2233                 currentCharacter = source[currentPosition++];
 
2234                 //                    if (((currentCharacter = source[currentPosition++])
 
2236                 //                      && (source[currentPosition] == 'u')) {
 
2237                 //                      //-------------unicode traitement ------------
 
2238                 //                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
2239                 //                      currentPosition++;
 
2240                 //                      while (source[currentPosition] == 'u') {
 
2241                 //                        currentPosition++;
 
2244                 //                        Character.getNumericValue(source[currentPosition++]))
 
2248                 //                          Character.getNumericValue(source[currentPosition++]))
 
2252                 //                          Character.getNumericValue(source[currentPosition++]))
 
2256                 //                          Character.getNumericValue(source[currentPosition++]))
 
2259                 //                        //error don't care of the value
 
2260                 //                        currentCharacter = 'A';
 
2261                 //                      } //something different from \n and \r
 
2263                 //                        currentCharacter =
 
2264                 //                          (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
2268               if (recordLineSeparator && ((currentCharacter == '\r') || (currentCharacter == '\n')))
 
2269                 pushLineSeparator();
 
2270             } catch (IndexOutOfBoundsException e) {
 
2271             } //an eof will them be generated
 
2275             //traditional and annotation comment
 
2276             boolean star = false;
 
2277             //                try { // consume next character
 
2278             unicodeAsBackSlash = false;
 
2279             currentCharacter = source[currentPosition++];
 
2280             //                  if (((currentCharacter = source[currentPosition++]) == '\\')
 
2281             //                    && (source[currentPosition] == 'u')) {
 
2282             //                    getNextUnicodeChar();
 
2284             if (withoutUnicodePtr != 0) {
 
2285               withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2288             //                } catch (InvalidInputException ex) {
 
2290             if (currentCharacter == '*') {
 
2293             if (recordLineSeparator && ((currentCharacter == '\r') || (currentCharacter == '\n')))
 
2294               pushLineSeparator();
 
2295             try { //get the next char
 
2296               currentCharacter = source[currentPosition++];
 
2297               //                  if (((currentCharacter = source[currentPosition++]) ==
 
2299               //                    && (source[currentPosition] == 'u')) {
 
2300               //                    //-------------unicode traitement ------------
 
2301               //                    int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
2302               //                    currentPosition++;
 
2303               //                    while (source[currentPosition] == 'u') {
 
2304               //                      currentPosition++;
 
2307               //                      Character.getNumericValue(source[currentPosition++]))
 
2311               //                        Character.getNumericValue(source[currentPosition++]))
 
2315               //                        Character.getNumericValue(source[currentPosition++]))
 
2319               //                        Character.getNumericValue(source[currentPosition++]))
 
2322               //                      //error don't care of the value
 
2323               //                      currentCharacter = 'A';
 
2324               //                    } //something different from * and /
 
2326               //                      currentCharacter =
 
2327               //                        (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
2330               //loop until end of comment */
 
2331               while ((currentCharacter != '/') || (!star)) {
 
2332                 if (recordLineSeparator && ((currentCharacter == '\r') || (currentCharacter == '\n')))
 
2333                   pushLineSeparator();
 
2334                 star = currentCharacter == '*';
 
2336                 currentCharacter = source[currentPosition++];
 
2337                 //                    if (((currentCharacter = source[currentPosition++])
 
2339                 //                      && (source[currentPosition] == 'u')) {
 
2340                 //                      //-------------unicode traitement ------------
 
2341                 //                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
2342                 //                      currentPosition++;
 
2343                 //                      while (source[currentPosition] == 'u') {
 
2344                 //                        currentPosition++;
 
2347                 //                        Character.getNumericValue(source[currentPosition++]))
 
2351                 //                          Character.getNumericValue(source[currentPosition++]))
 
2355                 //                          Character.getNumericValue(source[currentPosition++]))
 
2359                 //                          Character.getNumericValue(source[currentPosition++]))
 
2362                 //                        //error don't care of the value
 
2363                 //                        currentCharacter = 'A';
 
2364                 //                      } //something different from * and /
 
2366                 //                        currentCharacter =
 
2367                 //                          (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
2371             } catch (IndexOutOfBoundsException e) {
 
2379           if (isPHPIdentifierStart(currentCharacter) || currentCharacter == '$') {
 
2381               scanIdentifierOrKeyword((currentCharacter == '$'));
 
2382             } catch (InvalidInputException ex) {
 
2387           if (Character.isDigit(currentCharacter)) {
 
2390             } catch (InvalidInputException ex) {
 
2397       //-----------------end switch while try--------------------
 
2398     } catch (IndexOutOfBoundsException e) {
 
2399     } catch (InvalidInputException e) {
 
2404   //  public final boolean jumpOverUnicodeWhiteSpace()
 
2405   //    throws InvalidInputException {
 
2407   //    //handle the case of unicode. Jump over the next whiteSpace
 
2408   //    //making startPosition pointing on the next available char
 
2409   //    //On false, the currentCharacter is filled up with a potential
 
2413   //      this.wasAcr = false;
 
2414   //      int c1, c2, c3, c4;
 
2415   //      int unicodeSize = 6;
 
2416   //      currentPosition++;
 
2417   //      while (source[currentPosition] == 'u') {
 
2418   //        currentPosition++;
 
2422   //      if (((c1 = Character.getNumericValue(source[currentPosition++])) > 15
 
2424   //        || ((c2 = Character.getNumericValue(source[currentPosition++])) > 15
 
2426   //        || ((c3 = Character.getNumericValue(source[currentPosition++])) > 15
 
2428   //        || ((c4 = Character.getNumericValue(source[currentPosition++])) > 15
 
2430   //        throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
 
2433   //      currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
2434   //      if (recordLineSeparator
 
2435   //        && ((currentCharacter == '\r') || (currentCharacter == '\n')))
 
2436   //        pushLineSeparator();
 
2437   //      if (Character.isWhitespace(currentCharacter))
 
2440   //      //buffer the new char which is not a white space
 
2441   //      withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2442   //      //withoutUnicodePtr == 1 is true here
 
2444   //    } catch (IndexOutOfBoundsException e) {
 
2445   //      throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
 
2448   public final int[] getLineEnds() {
 
2449     //return a bounded copy of this.lineEnds
 
2451     System.arraycopy(lineEnds, 0, copy = new int[linePtr + 1], 0, linePtr + 1);
 
2455   public char[] getSource() {
 
2459   public static boolean isIdentifierOrKeyword(int token) {
 
2460     return (token == TokenNameIdentifier) || (token > TokenNameKEYWORD);
 
2463   final char[] optimizedCurrentTokenSource1() {
 
2464     //return always the same char[] build only once
 
2465     //optimization at no speed cost of 99.5 % of the singleCharIdentifier
 
2466     char charOne = source[startPosition];
 
2521       return new char[] { charOne };
 
2525   final char[] optimizedCurrentTokenSource2() {
 
2527     c0 = source[startPosition];
 
2528     c1 = source[startPosition + 1];
 
2530       //return always the same char[] build only once
 
2531       //optimization at no speed cost of 99.5 % of the singleCharIdentifier
 
2534         return charArray_va;
 
2536         return charArray_vb;
 
2538         return charArray_vc;
 
2540         return charArray_vd;
 
2542         return charArray_ve;
 
2544         return charArray_vf;
 
2546         return charArray_vg;
 
2548         return charArray_vh;
 
2550         return charArray_vi;
 
2552         return charArray_vj;
 
2554         return charArray_vk;
 
2556         return charArray_vl;
 
2558         return charArray_vm;
 
2560         return charArray_vn;
 
2562         return charArray_vo;
 
2564         return charArray_vp;
 
2566         return charArray_vq;
 
2568         return charArray_vr;
 
2570         return charArray_vs;
 
2572         return charArray_vt;
 
2574         return charArray_vu;
 
2576         return charArray_vv;
 
2578         return charArray_vw;
 
2580         return charArray_vx;
 
2582         return charArray_vy;
 
2584         return charArray_vz;
 
2587     //try to return the same char[] build only once
 
2588     int hash = ((c0 << 6) + c1) % TableSize;
 
2589     char[][] table = charArray_length[0][hash];
 
2591     while (++i < InternalTableSize) {
 
2592       char[] charArray = table[i];
 
2593       if ((c0 == charArray[0]) && (c1 == charArray[1]))
 
2596     //---------other side---------
 
2598     int max = newEntry2;
 
2599     while (++i <= max) {
 
2600       char[] charArray = table[i];
 
2601       if ((c0 == charArray[0]) && (c1 == charArray[1]))
 
2604     //--------add the entry-------
 
2605     if (++max >= InternalTableSize)
 
2608     table[max] = (r = new char[] { c0, c1 });
 
2613   final char[] optimizedCurrentTokenSource3() {
 
2614     //try to return the same char[] build only once
 
2616     int hash = (((c0 = source[startPosition]) << 12) + ((c1 = source[startPosition + 1]) << 6) + (c2 = source[startPosition + 2]))
 
2618     char[][] table = charArray_length[1][hash];
 
2620     while (++i < InternalTableSize) {
 
2621       char[] charArray = table[i];
 
2622       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
 
2625     //---------other side---------
 
2627     int max = newEntry3;
 
2628     while (++i <= max) {
 
2629       char[] charArray = table[i];
 
2630       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
 
2633     //--------add the entry-------
 
2634     if (++max >= InternalTableSize)
 
2637     table[max] = (r = new char[] { c0, c1, c2 });
 
2642   final char[] optimizedCurrentTokenSource4() {
 
2643     //try to return the same char[] build only once
 
2644     char c0, c1, c2, c3;
 
2645     long hash = ((((long) (c0 = source[startPosition])) << 18) + ((c1 = source[startPosition + 1]) << 12)
 
2646         + ((c2 = source[startPosition + 2]) << 6) + (c3 = source[startPosition + 3]))
 
2648     char[][] table = charArray_length[2][(int) hash];
 
2650     while (++i < InternalTableSize) {
 
2651       char[] charArray = table[i];
 
2652       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]) && (c3 == charArray[3]))
 
2655     //---------other side---------
 
2657     int max = newEntry4;
 
2658     while (++i <= max) {
 
2659       char[] charArray = table[i];
 
2660       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]) && (c3 == charArray[3]))
 
2663     //--------add the entry-------
 
2664     if (++max >= InternalTableSize)
 
2667     table[max] = (r = new char[] { c0, c1, c2, c3 });
 
2672   final char[] optimizedCurrentTokenSource5() {
 
2673     //try to return the same char[] build only once
 
2674     char c0, c1, c2, c3, c4;
 
2675     long hash = ((((long) (c0 = source[startPosition])) << 24) + (((long) (c1 = source[startPosition + 1])) << 18)
 
2676         + ((c2 = source[startPosition + 2]) << 12) + ((c3 = source[startPosition + 3]) << 6) + (c4 = source[startPosition + 4]))
 
2678     char[][] table = charArray_length[3][(int) hash];
 
2680     while (++i < InternalTableSize) {
 
2681       char[] charArray = table[i];
 
2682       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]) && (c3 == charArray[3]) && (c4 == charArray[4]))
 
2685     //---------other side---------
 
2687     int max = newEntry5;
 
2688     while (++i <= max) {
 
2689       char[] charArray = table[i];
 
2690       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]) && (c3 == charArray[3]) && (c4 == charArray[4]))
 
2693     //--------add the entry-------
 
2694     if (++max >= InternalTableSize)
 
2697     table[max] = (r = new char[] { c0, c1, c2, c3, c4 });
 
2702   final char[] optimizedCurrentTokenSource6() {
 
2703     //try to return the same char[] build only once
 
2704     char c0, c1, c2, c3, c4, c5;
 
2705     long hash = ((((long) (c0 = source[startPosition])) << 32) + (((long) (c1 = source[startPosition + 1])) << 24)
 
2706         + (((long) (c2 = source[startPosition + 2])) << 18) + ((c3 = source[startPosition + 3]) << 12)
 
2707         + ((c4 = source[startPosition + 4]) << 6) + (c5 = source[startPosition + 5]))
 
2709     char[][] table = charArray_length[4][(int) hash];
 
2711     while (++i < InternalTableSize) {
 
2712       char[] charArray = table[i];
 
2713       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]) && (c3 == charArray[3]) && (c4 == charArray[4])
 
2714           && (c5 == charArray[5]))
 
2717     //---------other side---------
 
2719     int max = newEntry6;
 
2720     while (++i <= max) {
 
2721       char[] charArray = table[i];
 
2722       if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]) && (c3 == charArray[3]) && (c4 == charArray[4])
 
2723           && (c5 == charArray[5]))
 
2726     //--------add the entry-------
 
2727     if (++max >= InternalTableSize)
 
2730     table[max] = (r = new char[] { c0, c1, c2, c3, c4, c5 });
 
2735   public final void pushLineSeparator() throws InvalidInputException {
 
2736     //see comment on isLineDelimiter(char) for the use of '\n' and '\r'
 
2737     final int INCREMENT = 250;
 
2738     if (this.checkNonExternalizedStringLiterals) {
 
2739       // reinitialize the current line for non externalize strings purpose
 
2742     //currentCharacter is at position currentPosition-1
 
2744     if (currentCharacter == '\r') {
 
2745       int separatorPos = currentPosition - 1;
 
2746       if ((linePtr > 0) && (lineEnds[linePtr] >= separatorPos))
 
2748       //System.out.println("CR-" + separatorPos);
 
2750         lineEnds[++linePtr] = separatorPos;
 
2751       } catch (IndexOutOfBoundsException e) {
 
2752         //linePtr value is correct
 
2753         int oldLength = lineEnds.length;
 
2754         int[] old = lineEnds;
 
2755         lineEnds = new int[oldLength + INCREMENT];
 
2756         System.arraycopy(old, 0, lineEnds, 0, oldLength);
 
2757         lineEnds[linePtr] = separatorPos;
 
2759       // look-ahead for merged cr+lf
 
2761         if (source[currentPosition] == '\n') {
 
2762           //System.out.println("look-ahead LF-" + currentPosition);
 
2763           lineEnds[linePtr] = currentPosition;
 
2769       } catch (IndexOutOfBoundsException e) {
 
2774       if (currentCharacter == '\n') {
 
2775         //must merge eventual cr followed by lf
 
2776         if (wasAcr && (lineEnds[linePtr] == (currentPosition - 2))) {
 
2777           //System.out.println("merge LF-" + (currentPosition - 1));
 
2778           lineEnds[linePtr] = currentPosition - 1;
 
2780           int separatorPos = currentPosition - 1;
 
2781           if ((linePtr > 0) && (lineEnds[linePtr] >= separatorPos))
 
2783           // System.out.println("LF-" + separatorPos);
 
2785             lineEnds[++linePtr] = separatorPos;
 
2786           } catch (IndexOutOfBoundsException e) {
 
2787             //linePtr value is correct
 
2788             int oldLength = lineEnds.length;
 
2789             int[] old = lineEnds;
 
2790             lineEnds = new int[oldLength + INCREMENT];
 
2791             System.arraycopy(old, 0, lineEnds, 0, oldLength);
 
2792             lineEnds[linePtr] = separatorPos;
 
2800   public final void pushUnicodeLineSeparator() {
 
2801     // isUnicode means that the \r or \n has been read as a unicode character
 
2802     //see comment on isLineDelimiter(char) for the use of '\n' and '\r'
 
2803     final int INCREMENT = 250;
 
2804     //currentCharacter is at position currentPosition-1
 
2805     if (this.checkNonExternalizedStringLiterals) {
 
2806       // reinitialize the current line for non externalize strings purpose
 
2810     if (currentCharacter == '\r') {
 
2811       int separatorPos = currentPosition - 6;
 
2812       if ((linePtr > 0) && (lineEnds[linePtr] >= separatorPos))
 
2814       //System.out.println("CR-" + separatorPos);
 
2816         lineEnds[++linePtr] = separatorPos;
 
2817       } catch (IndexOutOfBoundsException e) {
 
2818         //linePtr value is correct
 
2819         int oldLength = lineEnds.length;
 
2820         int[] old = lineEnds;
 
2821         lineEnds = new int[oldLength + INCREMENT];
 
2822         System.arraycopy(old, 0, lineEnds, 0, oldLength);
 
2823         lineEnds[linePtr] = separatorPos;
 
2825       // look-ahead for merged cr+lf
 
2826       if (source[currentPosition] == '\n') {
 
2827         //System.out.println("look-ahead LF-" + currentPosition);
 
2828         lineEnds[linePtr] = currentPosition;
 
2836       if (currentCharacter == '\n') {
 
2837         //must merge eventual cr followed by lf
 
2838         if (wasAcr && (lineEnds[linePtr] == (currentPosition - 7))) {
 
2839           //System.out.println("merge LF-" + (currentPosition - 1));
 
2840           lineEnds[linePtr] = currentPosition - 6;
 
2842           int separatorPos = currentPosition - 6;
 
2843           if ((linePtr > 0) && (lineEnds[linePtr] >= separatorPos))
 
2845           // System.out.println("LF-" + separatorPos);
 
2847             lineEnds[++linePtr] = separatorPos;
 
2848           } catch (IndexOutOfBoundsException e) {
 
2849             //linePtr value is correct
 
2850             int oldLength = lineEnds.length;
 
2851             int[] old = lineEnds;
 
2852             lineEnds = new int[oldLength + INCREMENT];
 
2853             System.arraycopy(old, 0, lineEnds, 0, oldLength);
 
2854             lineEnds[linePtr] = separatorPos;
 
2862   public void recordComment(int token) {
 
2864     int stopPosition = this.currentPosition;
 
2866     case TokenNameCOMMENT_LINE:
 
2867       stopPosition = -this.lastCommentLinePosition;
 
2869     case TokenNameCOMMENT_BLOCK:
 
2870       stopPosition = -this.currentPosition;
 
2874     // a new comment is recorded
 
2875     int length = this.commentStops.length;
 
2876     if (++this.commentPtr >= length) {
 
2877       System.arraycopy(this.commentStops, 0, this.commentStops = new int[length + 30], 0, length);
 
2878       //grows the positions buffers too
 
2879       System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[length + 30], 0, length);
 
2881     this.commentStops[this.commentPtr] = stopPosition;
 
2882     this.commentStarts[this.commentPtr] = this.startPosition;
 
2885   //  public final void recordComment(boolean isJavadoc) {
 
2886   //    // a new annotation comment is recorded
 
2888   //      commentStops[++commentPtr] = isJavadoc
 
2889   //          ? currentPosition
 
2890   //          : -currentPosition;
 
2891   //    } catch (IndexOutOfBoundsException e) {
 
2892   //      int oldStackLength = commentStops.length;
 
2893   //      int[] oldStack = commentStops;
 
2894   //      commentStops = new int[oldStackLength + 30];
 
2895   //      System.arraycopy(oldStack, 0, commentStops, 0, oldStackLength);
 
2896   //      commentStops[commentPtr] = isJavadoc ? currentPosition : -currentPosition;
 
2897   //      //grows the positions buffers too
 
2898   //      int[] old = commentStarts;
 
2899   //      commentStarts = new int[oldStackLength + 30];
 
2900   //      System.arraycopy(old, 0, commentStarts, 0, oldStackLength);
 
2902   //    //the buffer is of a correct size here
 
2903   //    commentStarts[commentPtr] = startPosition;
 
2905   public void resetTo(int begin, int end) {
 
2906     //reset the scanner to a given position where it may rescan again
 
2908     initialPosition = startPosition = currentPosition = begin;
 
2909     eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
 
2910     commentPtr = -1; // reset comment stack
 
2913   public final void scanSingleQuotedEscapeCharacter() throws InvalidInputException {
 
2914     // the string with "\\u" is a legal string of two chars \ and u
 
2915     //thus we use a direct access to the source (for regular cases).
 
2916     //    if (unicodeAsBackSlash) {
 
2917     //      // consume next character
 
2918     //      unicodeAsBackSlash = false;
 
2919     //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
2920     //        && (source[currentPosition] == 'u')) {
 
2921     //        getNextUnicodeChar();
 
2923     //        if (withoutUnicodePtr != 0) {
 
2924     //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2928     currentCharacter = source[currentPosition++];
 
2929     switch (currentCharacter) {
 
2931       currentCharacter = '\'';
 
2934       currentCharacter = '\\';
 
2937       currentCharacter = '\\';
 
2942   public final void scanDoubleQuotedEscapeCharacter() throws InvalidInputException {
 
2943     // the string with "\\u" is a legal string of two chars \ and u
 
2944     //thus we use a direct access to the source (for regular cases).
 
2945     //    if (unicodeAsBackSlash) {
 
2946     //      // consume next character
 
2947     //      unicodeAsBackSlash = false;
 
2948     //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
2949     //        && (source[currentPosition] == 'u')) {
 
2950     //        getNextUnicodeChar();
 
2952     //        if (withoutUnicodePtr != 0) {
 
2953     //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
2957     currentCharacter = source[currentPosition++];
 
2958     switch (currentCharacter) {
 
2960     //        currentCharacter = '\b';
 
2963       currentCharacter = '\t';
 
2966       currentCharacter = '\n';
 
2969     //        currentCharacter = '\f';
 
2972       currentCharacter = '\r';
 
2975       currentCharacter = '\"';
 
2978       currentCharacter = '\'';
 
2981       currentCharacter = '\\';
 
2984       currentCharacter = '$';
 
2987       // -----------octal escape--------------
 
2989       // OctalDigit OctalDigit
 
2990       // ZeroToThree OctalDigit OctalDigit
 
2991       int number = Character.getNumericValue(currentCharacter);
 
2992       if (number >= 0 && number <= 7) {
 
2993         boolean zeroToThreeNot = number > 3;
 
2994         if (Character.isDigit(currentCharacter = source[currentPosition++])) {
 
2995           int digit = Character.getNumericValue(currentCharacter);
 
2996           if (digit >= 0 && digit <= 7) {
 
2997             number = (number * 8) + digit;
 
2998             if (Character.isDigit(currentCharacter = source[currentPosition++])) {
 
2999               if (zeroToThreeNot) { // has read \NotZeroToThree OctalDigit
 
3000                 // Digit --> ignore last character
 
3003                 digit = Character.getNumericValue(currentCharacter);
 
3004                 if (digit >= 0 && digit <= 7) {
 
3005                   // has read \ZeroToThree OctalDigit OctalDigit
 
3006                   number = (number * 8) + digit;
 
3007                 } else { // has read \ZeroToThree OctalDigit NonOctalDigit
 
3008                   // --> ignore last character
 
3012             } else { // has read \OctalDigit NonDigit--> ignore last
 
3016           } else { // has read \OctalDigit NonOctalDigit--> ignore last
 
3020         } else { // has read \OctalDigit --> ignore last character
 
3024           throw new InvalidInputException(INVALID_ESCAPE);
 
3025         currentCharacter = (char) number;
 
3028     //     throw new InvalidInputException(INVALID_ESCAPE);
 
3032   //  public int scanIdentifierOrKeyword() throws InvalidInputException {
 
3033   //    return scanIdentifierOrKeyword( false );
 
3035   public int scanIdentifierOrKeyword(boolean isVariable) throws InvalidInputException {
 
3037     //first dispatch on the first char.
 
3038     //then the length. If there are several
 
3039     //keywors with the same length AND the same first char, then do another
 
3040     //disptach on the second char :-)...cool....but fast !
 
3041     useAssertAsAnIndentifier = false;
 
3042     while (getNextCharAsJavaIdentifierPart()) {
 
3046       //      if (new String(getCurrentTokenSource()).equals("$this")) {
 
3047       //        return TokenNamethis;
 
3049       return TokenNameVariable;
 
3054     //    if (withoutUnicodePtr == 0)
 
3055     //quick test on length == 1 but not on length > 12 while most identifier
 
3056     //have a length which is <= 12...but there are lots of identifier with
 
3059     if ((length = currentPosition - startPosition) == 1)
 
3060       return TokenNameIdentifier;
 
3062     data = new char[length];
 
3063     index = startPosition;
 
3064     for (int i = 0; i < length; i++) {
 
3065       data[i] = Character.toLowerCase(source[index + i]);
 
3069     //      if ((length = withoutUnicodePtr) == 1)
 
3070     //        return TokenNameIdentifier;
 
3071     //      // data = withoutUnicodeBuffer;
 
3072     //      data = new char[withoutUnicodeBuffer.length];
 
3073     //      for (int i = 0; i < withoutUnicodeBuffer.length; i++) {
 
3074     //        data[i] = Character.toLowerCase(withoutUnicodeBuffer[i]);
 
3078     firstLetter = data[index];
 
3079     switch (firstLetter) {
 
3084         if ((data[++index] == '_') && (data[++index] == 'f') && (data[++index] == 'i') && (data[++index] == 'l')
 
3085             && (data[++index] == 'e') && (data[++index] == '_') && (data[++index] == '_'))
 
3086           return TokenNameFILE;
 
3087         index = 0; //__LINE__
 
3088         if ((data[++index] == '_') && (data[++index] == 'l') && (data[++index] == 'i') && (data[++index] == 'n')
 
3089             && (data[++index] == 'e') && (data[++index] == '_') && (data[++index] == '_'))
 
3090           return TokenNameLINE;
 
3094         if ((data[++index] == '_') && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'a')
 
3095             && (data[++index] == 's') && (data[++index] == 's') && (data[++index] == '_') && (data[++index] == '_'))
 
3096           return TokenNameCLASS_C;
 
3100         if ((data[++index] == '_') && (data[++index] == 'm') && (data[++index] == 'e') && (data[++index] == 't')
 
3101             && (data[++index] == 'h') && (data[++index] == 'o') && (data[++index] == 'd') && (data[++index] == '_')
 
3102             && (data[++index] == '_'))
 
3103           return TokenNameMETHOD_C;
 
3107         if ((data[++index] == '_') && (data[++index] == 'f') && (data[++index] == 'u') && (data[++index] == 'n')
 
3108             && (data[++index] == 'c') && (data[++index] == 't') && (data[++index] == 'i') && (data[++index] == 'o')
 
3109             && (data[++index] == 'n') && (data[++index] == '_') && (data[++index] == '_'))
 
3110           return TokenNameFUNC_C;
 
3113       return TokenNameIdentifier;
 
3115       // as and array abstract
 
3119         if ((data[++index] == 's')) {
 
3122           return TokenNameIdentifier;
 
3126         if ((data[++index] == 'n') && (data[++index] == 'd')) {
 
3127           return TokenNameand;
 
3129           return TokenNameIdentifier;
 
3133         if ((data[++index] == 'r') && (data[++index] == 'r') && (data[++index] == 'a') && (data[++index] == 'y'))
 
3134           return TokenNamearray;
 
3136           return TokenNameIdentifier;
 
3138         if ((data[++index] == 'b') && (data[++index] == 's') && (data[++index] == 't') && (data[++index] == 'r')
 
3139             && (data[++index] == 'a') && (data[++index] == 'c') && (data[++index] == 't'))
 
3140           return TokenNameabstract;
 
3142           return TokenNameIdentifier;
 
3144         return TokenNameIdentifier;
 
3150         if ((data[++index] == 'r') && (data[++index] == 'e') && (data[++index] == 'a') && (data[++index] == 'k'))
 
3151           return TokenNamebreak;
 
3153           return TokenNameIdentifier;
 
3155         return TokenNameIdentifier;
 
3158       //case catch class clone const continue
 
3161         if ((data[++index] == 'a') && (data[++index] == 's') && (data[++index] == 'e'))
 
3162           return TokenNamecase;
 
3164           return TokenNameIdentifier;
 
3166         if ((data[++index] == 'a') && (data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
 
3167           return TokenNamecatch;
 
3169         if ((data[++index] == 'l') && (data[++index] == 'a') && (data[++index] == 's') && (data[++index] == 's'))
 
3170           return TokenNameclass;
 
3172         if ((data[++index] == 'l') && (data[++index] == 'o') && (data[++index] == 'n') && (data[++index] == 'e'))
 
3173           return TokenNameclone;
 
3175         if ((data[++index] == 'o') && (data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 't'))
 
3176           return TokenNameconst;
 
3178           return TokenNameIdentifier;
 
3180         if ((data[++index] == 'o') && (data[++index] == 'n') && (data[++index] == 't') && (data[++index] == 'i')
 
3181             && (data[++index] == 'n') && (data[++index] == 'u') && (data[++index] == 'e'))
 
3182           return TokenNamecontinue;
 
3184           return TokenNameIdentifier;
 
3186         return TokenNameIdentifier;
 
3189       // declare default do die
 
3190       // TODO delete define ==> no keyword !
 
3193         if ((data[++index] == 'o'))
 
3196           return TokenNameIdentifier;
 
3198       //            if ((data[++index] == 'e')
 
3199       //              && (data[++index] == 'f')
 
3200       //              && (data[++index] == 'i')
 
3201       //              && (data[++index] == 'n')
 
3202       //              && (data[++index] == 'e'))
 
3203       //              return TokenNamedefine;
 
3205       //              return TokenNameIdentifier;
 
3207         if ((data[++index] == 'e') && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'a')
 
3208             && (data[++index] == 'r') && (data[++index] == 'e'))
 
3209           return TokenNamedeclare;
 
3211         if ((data[++index] == 'e') && (data[++index] == 'f') && (data[++index] == 'a') && (data[++index] == 'u')
 
3212             && (data[++index] == 'l') && (data[++index] == 't'))
 
3213           return TokenNamedefault;
 
3215           return TokenNameIdentifier;
 
3217         return TokenNameIdentifier;
 
3220       //echo else exit elseif extends eval
 
3223         if ((data[++index] == 'c') && (data[++index] == 'h') && (data[++index] == 'o'))
 
3224           return TokenNameecho;
 
3225         else if ((data[index] == 'l') && (data[++index] == 's') && (data[++index] == 'e'))
 
3226           return TokenNameelse;
 
3227         else if ((data[index] == 'x') && (data[++index] == 'i') && (data[++index] == 't'))
 
3228           return TokenNameexit;
 
3229         else if ((data[index] == 'v') && (data[++index] == 'a') && (data[++index] == 'l'))
 
3230           return TokenNameeval;
 
3232           return TokenNameIdentifier;
 
3235         if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'i') && (data[++index] == 'f'))
 
3236           return TokenNameendif;
 
3237         if ((data[index] == 'm') && (data[++index] == 'p') && (data[++index] == 't') && (data[++index] == 'y'))
 
3238           return TokenNameempty;
 
3240           return TokenNameIdentifier;
 
3243         if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'f') && (data[++index] == 'o')
 
3244             && (data[++index] == 'r'))
 
3245           return TokenNameendfor;
 
3246         else if ((data[index] == 'l') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 'i')
 
3247             && (data[++index] == 'f'))
 
3248           return TokenNameelseif;
 
3250           return TokenNameIdentifier;
 
3252         if ((data[++index] == 'x') && (data[++index] == 't') && (data[++index] == 'e') && (data[++index] == 'n')
 
3253             && (data[++index] == 'd') && (data[++index] == 's'))
 
3254           return TokenNameextends;
 
3256           return TokenNameIdentifier;
 
3259         if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'w') && (data[++index] == 'h')
 
3260             && (data[++index] == 'i') && (data[++index] == 'l') && (data[++index] == 'e'))
 
3261           return TokenNameendwhile;
 
3263           return TokenNameIdentifier;
 
3266         if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 's') && (data[++index] == 'w')
 
3267             && (data[++index] == 'i') && (data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
 
3268           return TokenNameendswitch;
 
3270           return TokenNameIdentifier;
 
3273         if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'd') && (data[++index] == 'e')
 
3274             && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'a') && (data[++index] == 'r')
 
3275             && (data[++index] == 'e'))
 
3276           return TokenNameenddeclare;
 
3278         if ((data[++index] == 'n') // endforeach
 
3279             && (data[++index] == 'd') && (data[++index] == 'f') && (data[++index] == 'o') && (data[++index] == 'r')
 
3280             && (data[++index] == 'e') && (data[++index] == 'a') && (data[++index] == 'c') && (data[++index] == 'h'))
 
3281           return TokenNameendforeach;
 
3283           return TokenNameIdentifier;
 
3285         return TokenNameIdentifier;
 
3288       //for false final function
 
3291         if ((data[++index] == 'o') && (data[++index] == 'r'))
 
3292           return TokenNamefor;
 
3294           return TokenNameIdentifier;
 
3296         //            if ((data[++index] == 'a') && (data[++index] == 'l')
 
3297         //                && (data[++index] == 's') && (data[++index] == 'e'))
 
3298         //              return TokenNamefalse;
 
3299         if ((data[++index] == 'i') && (data[++index] == 'n') && (data[++index] == 'a') && (data[++index] == 'l'))
 
3300           return TokenNamefinal;
 
3302           return TokenNameIdentifier;
 
3305         if ((data[++index] == 'o') && (data[++index] == 'r') && (data[++index] == 'e') && (data[++index] == 'a')
 
3306             && (data[++index] == 'c') && (data[++index] == 'h'))
 
3307           return TokenNameforeach;
 
3309           return TokenNameIdentifier;
 
3312         if ((data[++index] == 'u') && (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 't')
 
3313             && (data[++index] == 'i') && (data[++index] == 'o') && (data[++index] == 'n'))
 
3314           return TokenNamefunction;
 
3316           return TokenNameIdentifier;
 
3318         return TokenNameIdentifier;
 
3323         if ((data[++index] == 'l') && (data[++index] == 'o') && (data[++index] == 'b') && (data[++index] == 'a')
 
3324             && (data[++index] == 'l')) {
 
3325           return TokenNameglobal;
 
3328       return TokenNameIdentifier;
 
3330       //if int isset include include_once instanceof interface implements
 
3333         if (data[++index] == 'f')
 
3336           return TokenNameIdentifier;
 
3338       //            if ((data[++index] == 'n') && (data[++index] == 't'))
 
3339       //              return TokenNameint;
 
3341       //              return TokenNameIdentifier;
 
3343         if ((data[++index] == 's') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 't'))
 
3344           return TokenNameisset;
 
3346           return TokenNameIdentifier;
 
3348         if ((data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'u')
 
3349             && (data[++index] == 'd') && (data[++index] == 'e'))
 
3350           return TokenNameinclude;
 
3352           return TokenNameIdentifier;
 
3355         if ((data[++index] == 'n') && (data[++index] == 't') && (data[++index] == 'e') && (data[++index] == 'r')
 
3356             && (data[++index] == 'f') && (data[++index] == 'a') && (data[++index] == 'c') && (data[++index] == 'e'))
 
3357           return TokenNameinterface;
 
3359           return TokenNameIdentifier;
 
3362         if ((data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 't') && (data[++index] == 'a')
 
3363             && (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'e') && (data[++index] == 'o')
 
3364             && (data[++index] == 'f'))
 
3365           return TokenNameinstanceof;
 
3366         if ((data[index] == 'm') && (data[++index] == 'p') && (data[++index] == 'l') && (data[++index] == 'e')
 
3367             && (data[++index] == 'm') && (data[++index] == 'e') && (data[++index] == 'n') && (data[++index] == 't')
 
3368             && (data[++index] == 's'))
 
3369           return TokenNameimplements;
 
3371           return TokenNameIdentifier;
 
3373         if ((data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'u')
 
3374             && (data[++index] == 'd') && (data[++index] == 'e') && (data[++index] == '_') && (data[++index] == 'o')
 
3375             && (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'e'))
 
3376           return TokenNameinclude_once;
 
3378           return TokenNameIdentifier;
 
3380         return TokenNameIdentifier;
 
3385         if ((data[++index] == 'i') && (data[++index] == 's') && (data[++index] == 't')) {
 
3386           return TokenNamelist;
 
3389       return TokenNameIdentifier;
 
3394         if ((data[++index] == 'e') && (data[++index] == 'w'))
 
3395           return TokenNamenew;
 
3397           return TokenNameIdentifier;
 
3399       //            if ((data[++index] == 'u') && (data[++index] == 'l')
 
3400       //                && (data[++index] == 'l'))
 
3401       //              return TokenNamenull;
 
3403       //              return TokenNameIdentifier;
 
3405         return TokenNameIdentifier;
 
3410         if (data[++index] == 'r') {
 
3414       //        if (length == 12) {
 
3415       //          if ((data[++index] == 'l')
 
3416       //            && (data[++index] == 'd')
 
3417       //            && (data[++index] == '_')
 
3418       //            && (data[++index] == 'f')
 
3419       //            && (data[++index] == 'u')
 
3420       //            && (data[++index] == 'n')
 
3421       //            && (data[++index] == 'c')
 
3422       //            && (data[++index] == 't')
 
3423       //            && (data[++index] == 'i')
 
3424       //            && (data[++index] == 'o')
 
3425       //            && (data[++index] == 'n')) {
 
3426       //            return TokenNameold_function;
 
3429       return TokenNameIdentifier;
 
3431       // print public private protected
 
3434         if ((data[++index] == 'r') && (data[++index] == 'i') && (data[++index] == 'n') && (data[++index] == 't')) {
 
3435           return TokenNameprint;
 
3437           return TokenNameIdentifier;
 
3439         if ((data[++index] == 'u') && (data[++index] == 'b') && (data[++index] == 'l') && (data[++index] == 'i')
 
3440             && (data[++index] == 'c')) {
 
3441           return TokenNamepublic;
 
3443           return TokenNameIdentifier;
 
3445         if ((data[++index] == 'r') && (data[++index] == 'i') && (data[++index] == 'v') && (data[++index] == 'a')
 
3446             && (data[++index] == 't') && (data[++index] == 'e')) {
 
3447           return TokenNameprivate;
 
3449           return TokenNameIdentifier;
 
3451         if ((data[++index] == 'r') && (data[++index] == 'o') && (data[++index] == 't') && (data[++index] == 'e')
 
3452             && (data[++index] == 'c') && (data[++index] == 't') && (data[++index] == 'e') && (data[++index] == 'd')) {
 
3453           return TokenNameprotected;
 
3455           return TokenNameIdentifier;
 
3457       return TokenNameIdentifier;
 
3459       //return require require_once
 
3461         if ((data[++index] == 'e') && (data[++index] == 't') && (data[++index] == 'u') && (data[++index] == 'r')
 
3462             && (data[++index] == 'n')) {
 
3463           return TokenNamereturn;
 
3465       } else if (length == 7) {
 
3466         if ((data[++index] == 'e') && (data[++index] == 'q') && (data[++index] == 'u') && (data[++index] == 'i')
 
3467             && (data[++index] == 'r') && (data[++index] == 'e')) {
 
3468           return TokenNamerequire;
 
3470       } else if (length == 12) {
 
3471         if ((data[++index] == 'e') && (data[++index] == 'q') && (data[++index] == 'u') && (data[++index] == 'i')
 
3472             && (data[++index] == 'r') && (data[++index] == 'e') && (data[++index] == '_') && (data[++index] == 'o')
 
3473             && (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'e')) {
 
3474           return TokenNamerequire_once;
 
3477         return TokenNameIdentifier;
 
3482         if (data[++index] == 't')
 
3483           if ((data[++index] == 'a') && (data[++index] == 't') && (data[++index] == 'i') && (data[++index] == 'c')) {
 
3484             return TokenNamestatic;
 
3486             return TokenNameIdentifier;
 
3487         else if ((data[index] == 'w') && (data[++index] == 'i') && (data[++index] == 't') && (data[++index] == 'c')
 
3488             && (data[++index] == 'h'))
 
3489           return TokenNameswitch;
 
3491           return TokenNameIdentifier;
 
3493         return TokenNameIdentifier;
 
3499         if ((data[++index] == 'r') && (data[++index] == 'y'))
 
3500           return TokenNametry;
 
3502           return TokenNameIdentifier;
 
3504       //            if ((data[++index] == 'r') && (data[++index] == 'u')
 
3505       //                && (data[++index] == 'e'))
 
3506       //              return TokenNametrue;
 
3508       //              return TokenNameIdentifier;
 
3510         if ((data[++index] == 'h') && (data[++index] == 'r') && (data[++index] == 'o') && (data[++index] == 'w'))
 
3511           return TokenNamethrow;
 
3513           return TokenNameIdentifier;
 
3515         return TokenNameIdentifier;
 
3521         if ((data[++index] == 's') && (data[++index] == 'e'))
 
3522           return TokenNameuse;
 
3524           return TokenNameIdentifier;
 
3526         if ((data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 't'))
 
3527           return TokenNameunset;
 
3529           return TokenNameIdentifier;
 
3531         return TokenNameIdentifier;
 
3537         if ((data[++index] == 'a') && (data[++index] == 'r'))
 
3538           return TokenNamevar;
 
3540           return TokenNameIdentifier;
 
3542         return TokenNameIdentifier;
 
3548         if ((data[++index] == 'h') && (data[++index] == 'i') && (data[++index] == 'l') && (data[++index] == 'e'))
 
3549           return TokenNamewhile;
 
3551           return TokenNameIdentifier;
 
3552       //case 6:if ( (data[++index] =='i') && (data[++index]=='d') &&
 
3553       // (data[++index]=='e') && (data[++index]=='f')&&
 
3554       // (data[++index]=='p'))
 
3555       //return TokenNamewidefp ;
 
3557       //return TokenNameIdentifier;
 
3559         return TokenNameIdentifier;
 
3565         if ((data[++index] == 'o') && (data[++index] == 'r'))
 
3566           return TokenNamexor;
 
3568           return TokenNameIdentifier;
 
3570         return TokenNameIdentifier;
 
3573       return TokenNameIdentifier;
 
3577   public int scanNumber(boolean dotPrefix) throws InvalidInputException {
 
3578     //when entering this method the currentCharacter is the firt
 
3579     //digit of the number , i.e. it may be preceeded by a . when
 
3581     boolean floating = dotPrefix;
 
3582     if ((!dotPrefix) && (currentCharacter == '0')) {
 
3583       if (getNextChar('x', 'X') >= 0) { //----------hexa-----------------
 
3584         //force the first char of the hexa number do exist...
 
3585         // consume next character
 
3586         unicodeAsBackSlash = false;
 
3587         currentCharacter = source[currentPosition++];
 
3588         //        if (((currentCharacter = source[currentPosition++]) == '\\')
 
3589         //          && (source[currentPosition] == 'u')) {
 
3590         //          getNextUnicodeChar();
 
3592         //          if (withoutUnicodePtr != 0) {
 
3593         //            withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
3596         if (Character.digit(currentCharacter, 16) == -1)
 
3597           throw new InvalidInputException(INVALID_HEXA);
 
3599         while (getNextCharAsDigit(16)) {
 
3602         //        if (getNextChar('l', 'L') >= 0)
 
3603         //          return TokenNameLongLiteral;
 
3605         return TokenNameIntegerLiteral;
 
3607       //there is x or X in the number
 
3608       //potential octal ! ... some one may write 000099.0 ! thus 00100 <
 
3609       // 00078.0 is true !!!!! crazy language
 
3610       if (getNextCharAsDigit()) {
 
3611         //-------------potential octal-----------------
 
3612         while (getNextCharAsDigit()) {
 
3615         //        if (getNextChar('l', 'L') >= 0) {
 
3616         //          return TokenNameLongLiteral;
 
3619         //        if (getNextChar('f', 'F') >= 0) {
 
3620         //          return TokenNameFloatingPointLiteral;
 
3622         if (getNextChar('d', 'D') >= 0) {
 
3623           return TokenNameDoubleLiteral;
 
3624         } else { //make the distinction between octal and float ....
 
3625           if (getNextChar('.')) { //bingo ! ....
 
3626             while (getNextCharAsDigit()) {
 
3629             if (getNextChar('e', 'E') >= 0) {
 
3630               // consume next character
 
3631               unicodeAsBackSlash = false;
 
3632               currentCharacter = source[currentPosition++];
 
3633               //              if (((currentCharacter = source[currentPosition++]) == '\\')
 
3634               //                && (source[currentPosition] == 'u')) {
 
3635               //                getNextUnicodeChar();
 
3637               //                if (withoutUnicodePtr != 0) {
 
3638               //                  withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
3641               if ((currentCharacter == '-') || (currentCharacter == '+')) {
 
3642                 // consume next character
 
3643                 unicodeAsBackSlash = false;
 
3644                 currentCharacter = source[currentPosition++];
 
3645                 //                if (((currentCharacter = source[currentPosition++]) == '\\')
 
3646                 //                  && (source[currentPosition] == 'u')) {
 
3647                 //                  getNextUnicodeChar();
 
3649                 //                  if (withoutUnicodePtr != 0) {
 
3650                 //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
 
3651                 //                      currentCharacter;
 
3655               if (!Character.isDigit(currentCharacter))
 
3656                 throw new InvalidInputException(INVALID_FLOAT);
 
3657               while (getNextCharAsDigit()) {
 
3661             //            if (getNextChar('f', 'F') >= 0)
 
3662             //              return TokenNameFloatingPointLiteral;
 
3663             getNextChar('d', 'D'); //jump over potential d or D
 
3664             return TokenNameDoubleLiteral;
 
3666             return TokenNameIntegerLiteral;
 
3673     while (getNextCharAsDigit()) {
 
3676     //    if ((!dotPrefix) && (getNextChar('l', 'L') >= 0))
 
3677     //      return TokenNameLongLiteral;
 
3678     if ((!dotPrefix) && (getNextChar('.'))) { //decimal part that can be empty
 
3679       while (getNextCharAsDigit()) {
 
3684     //if floating is true both exponant and suffix may be optional
 
3685     if (getNextChar('e', 'E') >= 0) {
 
3687       // consume next character
 
3688       unicodeAsBackSlash = false;
 
3689       currentCharacter = source[currentPosition++];
 
3690       //      if (((currentCharacter = source[currentPosition++]) == '\\')
 
3691       //        && (source[currentPosition] == 'u')) {
 
3692       //        getNextUnicodeChar();
 
3694       //        if (withoutUnicodePtr != 0) {
 
3695       //          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
3698       if ((currentCharacter == '-') || (currentCharacter == '+')) { // consume
 
3701         unicodeAsBackSlash = false;
 
3702         currentCharacter = source[currentPosition++];
 
3703         //        if (((currentCharacter = source[currentPosition++]) == '\\')
 
3704         //          && (source[currentPosition] == 'u')) {
 
3705         //          getNextUnicodeChar();
 
3707         //          if (withoutUnicodePtr != 0) {
 
3708         //            withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
3712       if (!Character.isDigit(currentCharacter))
 
3713         throw new InvalidInputException(INVALID_FLOAT);
 
3714       while (getNextCharAsDigit()) {
 
3718     if (getNextChar('d', 'D') >= 0)
 
3719       return TokenNameDoubleLiteral;
 
3720     //    if (getNextChar('f', 'F') >= 0)
 
3721     //      return TokenNameFloatingPointLiteral;
 
3722     //the long flag has been tested before
 
3723     return floating ? TokenNameDoubleLiteral : TokenNameIntegerLiteral;
 
3727    * Search the line number corresponding to a specific position
 
3730   public final int getLineNumber(int position) {
 
3731     if (lineEnds == null)
 
3733     int length = linePtr + 1;
 
3736     int g = 0, d = length - 1;
 
3740       if (position < lineEnds[m]) {
 
3742       } else if (position > lineEnds[m]) {
 
3748     if (position < lineEnds[m]) {
 
3754   public void setPHPMode(boolean mode) {
 
3758   public final void setSource(char[] source) {
 
3759     setSource(null, source);
 
3762   public final void setSource(ICompilationUnit compilationUnit, char[] source) {
 
3763     //the source-buffer is set to sourceString
 
3764     this.compilationUnit = compilationUnit;
 
3765     if (source == null) {
 
3766       this.source = new char[0];
 
3768       this.source = source;
 
3771     initialPosition = currentPosition = 0;
 
3772     containsAssertKeyword = false;
 
3773     withoutUnicodeBuffer = new char[this.source.length];
 
3774     encapsedStringStack = new Stack();
 
3777   public String toString() {
 
3778     if (startPosition == source.length)
 
3779       return "EOF\n\n" + new String(source); //$NON-NLS-1$
 
3780     if (currentPosition > source.length)
 
3781       return "behind the EOF :-( ....\n\n" + new String(source); //$NON-NLS-1$
 
3782     char front[] = new char[startPosition];
 
3783     System.arraycopy(source, 0, front, 0, startPosition);
 
3784     int middleLength = (currentPosition - 1) - startPosition + 1;
 
3786     if (middleLength > -1) {
 
3787       middle = new char[middleLength];
 
3788       System.arraycopy(source, startPosition, middle, 0, middleLength);
 
3790       middle = new char[0];
 
3792     char end[] = new char[source.length - (currentPosition - 1)];
 
3793     System.arraycopy(source, (currentPosition - 1) + 1, end, 0, source.length - (currentPosition - 1) - 1);
 
3794     return new String(front) + "\n===============================\nStarts here -->" //$NON-NLS-1$
 
3795         + new String(middle) + "<-- Ends here\n===============================\n" //$NON-NLS-1$
 
3799   public final String toStringAction(int act) {
 
3801     case TokenNameERROR:
 
3802       return "ScannerError"; // + new String(getCurrentTokenSource()) + ")";
 
3804     case TokenNameINLINE_HTML:
 
3805       return "Inline-HTML(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3806     case TokenNameIdentifier:
 
3807       return "Identifier(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3808     case TokenNameVariable:
 
3809       return "Variable(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3810     case TokenNameabstract:
 
3811       return "abstract"; //$NON-NLS-1$
 
3813       return "AND"; //$NON-NLS-1$
 
3814     case TokenNamearray:
 
3815       return "array"; //$NON-NLS-1$
 
3817       return "as"; //$NON-NLS-1$
 
3818     case TokenNamebreak:
 
3819       return "break"; //$NON-NLS-1$
 
3821       return "case"; //$NON-NLS-1$
 
3822     case TokenNameclass:
 
3823       return "class"; //$NON-NLS-1$
 
3824     case TokenNamecatch:
 
3825       return "catch"; //$NON-NLS-1$
 
3826     case TokenNameclone:
 
3829     case TokenNameconst:
 
3832     case TokenNamecontinue:
 
3833       return "continue"; //$NON-NLS-1$
 
3834     case TokenNamedefault:
 
3835       return "default"; //$NON-NLS-1$
 
3836     //      case TokenNamedefine :
 
3837     //        return "define"; //$NON-NLS-1$
 
3839       return "do"; //$NON-NLS-1$
 
3841       return "echo"; //$NON-NLS-1$
 
3843       return "else"; //$NON-NLS-1$
 
3844     case TokenNameelseif:
 
3845       return "elseif"; //$NON-NLS-1$
 
3846     case TokenNameendfor:
 
3847       return "endfor"; //$NON-NLS-1$
 
3848     case TokenNameendforeach:
 
3849       return "endforeach"; //$NON-NLS-1$
 
3850     case TokenNameendif:
 
3851       return "endif"; //$NON-NLS-1$
 
3852     case TokenNameendswitch:
 
3853       return "endswitch"; //$NON-NLS-1$
 
3854     case TokenNameendwhile:
 
3855       return "endwhile"; //$NON-NLS-1$
 
3858     case TokenNameextends:
 
3859       return "extends"; //$NON-NLS-1$
 
3860     //      case TokenNamefalse :
 
3861     //        return "false"; //$NON-NLS-1$
 
3862     case TokenNamefinal:
 
3863       return "final"; //$NON-NLS-1$
 
3865       return "for"; //$NON-NLS-1$
 
3866     case TokenNameforeach:
 
3867       return "foreach"; //$NON-NLS-1$
 
3868     case TokenNamefunction:
 
3869       return "function"; //$NON-NLS-1$
 
3870     case TokenNameglobal:
 
3871       return "global"; //$NON-NLS-1$
 
3873       return "if"; //$NON-NLS-1$
 
3874     case TokenNameimplements:
 
3875       return "implements"; //$NON-NLS-1$
 
3876     case TokenNameinclude:
 
3877       return "include"; //$NON-NLS-1$
 
3878     case TokenNameinclude_once:
 
3879       return "include_once"; //$NON-NLS-1$
 
3880     case TokenNameinstanceof:
 
3881       return "instanceof"; //$NON-NLS-1$
 
3882     case TokenNameinterface:
 
3883       return "interface"; //$NON-NLS-1$
 
3884     case TokenNameisset:
 
3885       return "isset"; //$NON-NLS-1$
 
3887       return "list"; //$NON-NLS-1$
 
3889       return "new"; //$NON-NLS-1$
 
3890     //      case TokenNamenull :
 
3891     //        return "null"; //$NON-NLS-1$
 
3893       return "OR"; //$NON-NLS-1$
 
3894     case TokenNameprint:
 
3895       return "print"; //$NON-NLS-1$
 
3896     case TokenNameprivate:
 
3897       return "private"; //$NON-NLS-1$
 
3898     case TokenNameprotected:
 
3899       return "protected"; //$NON-NLS-1$
 
3900     case TokenNamepublic:
 
3901       return "public"; //$NON-NLS-1$
 
3902     case TokenNamerequire:
 
3903       return "require"; //$NON-NLS-1$
 
3904     case TokenNamerequire_once:
 
3905       return "require_once"; //$NON-NLS-1$
 
3906     case TokenNamereturn:
 
3907       return "return"; //$NON-NLS-1$
 
3908     case TokenNamestatic:
 
3909       return "static"; //$NON-NLS-1$
 
3910     case TokenNameswitch:
 
3911       return "switch"; //$NON-NLS-1$
 
3912     //      case TokenNametrue :
 
3913     //        return "true"; //$NON-NLS-1$
 
3914     case TokenNameunset:
 
3915       return "unset"; //$NON-NLS-1$
 
3917       return "var"; //$NON-NLS-1$
 
3918     case TokenNamewhile:
 
3919       return "while"; //$NON-NLS-1$
 
3921       return "XOR"; //$NON-NLS-1$
 
3922     //      case TokenNamethis :
 
3923     //        return "$this"; //$NON-NLS-1$
 
3924     case TokenNameIntegerLiteral:
 
3925       return "Integer(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3926     case TokenNameDoubleLiteral:
 
3927       return "Double(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3928     case TokenNameStringDoubleQuote:
 
3929       return "StringLiteral(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3930     case TokenNameStringSingleQuote:
 
3931       return "StringConstant(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3932     case TokenNameStringInterpolated:
 
3933       return "StringInterpolated(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3934     case TokenNameEncapsedString0:
 
3935       return "`"; //$NON-NLS-1$  
 
3936     case TokenNameEncapsedString1:
 
3937       return "\'"; //$NON-NLS-1$  
 
3938     case TokenNameEncapsedString2:
 
3939       return "\""; //$NON-NLS-1$  
 
3940     case TokenNameSTRING:
 
3941       return "STRING(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 
3942     case TokenNameHEREDOC:
 
3943       return "HEREDOC(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
 
3944     case TokenNamePLUS_PLUS:
 
3945       return "++"; //$NON-NLS-1$
 
3946     case TokenNameMINUS_MINUS:
 
3947       return "--"; //$NON-NLS-1$
 
3948     case TokenNameEQUAL_EQUAL:
 
3949       return "=="; //$NON-NLS-1$
 
3950     case TokenNameEQUAL_EQUAL_EQUAL:
 
3951       return "==="; //$NON-NLS-1$
 
3952     case TokenNameEQUAL_GREATER:
 
3953       return "=>"; //$NON-NLS-1$
 
3954     case TokenNameLESS_EQUAL:
 
3955       return "<="; //$NON-NLS-1$
 
3956     case TokenNameGREATER_EQUAL:
 
3957       return ">="; //$NON-NLS-1$
 
3958     case TokenNameNOT_EQUAL:
 
3959       return "!="; //$NON-NLS-1$
 
3960     case TokenNameNOT_EQUAL_EQUAL:
 
3961       return "!=="; //$NON-NLS-1$
 
3962     case TokenNameLEFT_SHIFT:
 
3963       return "<<"; //$NON-NLS-1$
 
3964     case TokenNameRIGHT_SHIFT:
 
3965       return ">>"; //$NON-NLS-1$
 
3966     case TokenNamePLUS_EQUAL:
 
3967       return "+="; //$NON-NLS-1$
 
3968     case TokenNameMINUS_EQUAL:
 
3969       return "-="; //$NON-NLS-1$
 
3970     case TokenNameMULTIPLY_EQUAL:
 
3971       return "*="; //$NON-NLS-1$
 
3972     case TokenNameDIVIDE_EQUAL:
 
3973       return "/="; //$NON-NLS-1$
 
3974     case TokenNameAND_EQUAL:
 
3975       return "&="; //$NON-NLS-1$
 
3976     case TokenNameOR_EQUAL:
 
3977       return "|="; //$NON-NLS-1$
 
3978     case TokenNameXOR_EQUAL:
 
3979       return "^="; //$NON-NLS-1$
 
3980     case TokenNameREMAINDER_EQUAL:
 
3981       return "%="; //$NON-NLS-1$
 
3982     case TokenNameDOT_EQUAL:
 
3983       return ".="; //$NON-NLS-1$
 
3984     case TokenNameLEFT_SHIFT_EQUAL:
 
3985       return "<<="; //$NON-NLS-1$
 
3986     case TokenNameRIGHT_SHIFT_EQUAL:
 
3987       return ">>="; //$NON-NLS-1$
 
3988     case TokenNameOR_OR:
 
3989       return "||"; //$NON-NLS-1$
 
3990     case TokenNameAND_AND:
 
3991       return "&&"; //$NON-NLS-1$
 
3993       return "+"; //$NON-NLS-1$
 
3994     case TokenNameMINUS:
 
3995       return "-"; //$NON-NLS-1$
 
3996     case TokenNameMINUS_GREATER:
 
3999       return "!"; //$NON-NLS-1$
 
4000     case TokenNameREMAINDER:
 
4001       return "%"; //$NON-NLS-1$
 
4003       return "^"; //$NON-NLS-1$
 
4005       return "&"; //$NON-NLS-1$
 
4006     case TokenNameMULTIPLY:
 
4007       return "*"; //$NON-NLS-1$
 
4009       return "|"; //$NON-NLS-1$
 
4010     case TokenNameTWIDDLE:
 
4011       return "~"; //$NON-NLS-1$
 
4012     case TokenNameTWIDDLE_EQUAL:
 
4013       return "~="; //$NON-NLS-1$
 
4014     case TokenNameDIVIDE:
 
4015       return "/"; //$NON-NLS-1$
 
4016     case TokenNameGREATER:
 
4017       return ">"; //$NON-NLS-1$
 
4019       return "<"; //$NON-NLS-1$
 
4020     case TokenNameLPAREN:
 
4021       return "("; //$NON-NLS-1$
 
4022     case TokenNameRPAREN:
 
4023       return ")"; //$NON-NLS-1$
 
4024     case TokenNameLBRACE:
 
4025       return "{"; //$NON-NLS-1$
 
4026     case TokenNameRBRACE:
 
4027       return "}"; //$NON-NLS-1$
 
4028     case TokenNameLBRACKET:
 
4029       return "["; //$NON-NLS-1$
 
4030     case TokenNameRBRACKET:
 
4031       return "]"; //$NON-NLS-1$
 
4032     case TokenNameSEMICOLON:
 
4033       return ";"; //$NON-NLS-1$
 
4034     case TokenNameQUESTION:
 
4035       return "?"; //$NON-NLS-1$
 
4036     case TokenNameCOLON:
 
4037       return ":"; //$NON-NLS-1$
 
4038     case TokenNameCOMMA:
 
4039       return ","; //$NON-NLS-1$
 
4041       return "."; //$NON-NLS-1$
 
4042     case TokenNameEQUAL:
 
4043       return "="; //$NON-NLS-1$
 
4046     case TokenNameDOLLAR:
 
4048     case TokenNameDOLLAR_LBRACE:
 
4050     case TokenNameLBRACE_DOLLAR:
 
4053       return "EOF"; //$NON-NLS-1$
 
4054     case TokenNameWHITESPACE:
 
4055       return "WHITESPACE(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
 
4056     case TokenNameCOMMENT_LINE:
 
4057       return "COMMENT_LINE(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
 
4058     case TokenNameCOMMENT_BLOCK:
 
4059       return "COMMENT_BLOCK(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
 
4060     case TokenNameCOMMENT_PHPDOC:
 
4061       return "COMMENT_PHPDOC(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
 
4062     //      case TokenNameHTML :
 
4063     //        return "HTML(" + new String(getCurrentTokenSource()) + ")";
 
4066       return "__FILE__"; //$NON-NLS-1$
 
4068       return "__LINE__"; //$NON-NLS-1$
 
4069     case TokenNameCLASS_C:
 
4070       return "__CLASS__"; //$NON-NLS-1$
 
4071     case TokenNameMETHOD_C:
 
4072       return "__METHOD__"; //$NON-NLS-1$
 
4073     case TokenNameFUNC_C:
 
4074       return "__FUNCTION__"; //$NON-NLS-1
 
4075     case TokenNameboolCAST:
 
4076       return "( bool )"; //$NON-NLS-1$
 
4077     case TokenNameintCAST:
 
4078       return "( int )"; //$NON-NLS-1$
 
4079     case TokenNamedoubleCAST:
 
4080       return "( double )"; //$NON-NLS-1$
 
4081     case TokenNameobjectCAST:
 
4082       return "( object )"; //$NON-NLS-1$
 
4083     case TokenNamestringCAST:
 
4084       return "( string )"; //$NON-NLS-1$
 
4086       return "not-a-token(" + (new Integer(act)) + ") " + new String(getCurrentTokenSource()); //$NON-NLS-1$
 
4094   public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace) {
 
4095     this(tokenizeComments, tokenizeWhiteSpace, false);
 
4098   public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean checkNonExternalizedStringLiterals) {
 
4099     this(tokenizeComments, tokenizeWhiteSpace, checkNonExternalizedStringLiterals, false);
 
4102   public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean checkNonExternalizedStringLiterals,
 
4103       boolean assertMode) {
 
4104     this(tokenizeComments, tokenizeWhiteSpace, checkNonExternalizedStringLiterals, assertMode, false, null, null, true);
 
4107   public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean checkNonExternalizedStringLiterals,
 
4108       boolean assertMode, boolean tokenizeStrings, char[][] taskTags, char[][] taskPriorities, boolean isTaskCaseSensitive) {
 
4109     this.eofPosition = Integer.MAX_VALUE;
 
4110     this.tokenizeComments = tokenizeComments;
 
4111     this.tokenizeWhiteSpace = tokenizeWhiteSpace;
 
4112     this.tokenizeStrings = tokenizeStrings;
 
4113     this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
 
4114     this.assertMode = assertMode;
 
4115     this.encapsedStringStack = null;
 
4116     this.taskTags = taskTags;
 
4117     this.taskPriorities = taskPriorities;
 
4120   private void checkNonExternalizeString() throws InvalidInputException {
 
4121     if (currentLine == null)
 
4123     parseTags(currentLine);
 
4126   private void parseTags(NLSLine line) throws InvalidInputException {
 
4127     String s = new String(getCurrentTokenSource());
 
4128     int pos = s.indexOf(TAG_PREFIX);
 
4129     int lineLength = line.size();
 
4131       int start = pos + TAG_PREFIX_LENGTH;
 
4132       int end = s.indexOf(TAG_POSTFIX, start);
 
4133       String index = s.substring(start, end);
 
4136         i = Integer.parseInt(index) - 1;
 
4137         // Tags are one based not zero based.
 
4138       } catch (NumberFormatException e) {
 
4139         i = -1; // we don't want to consider this as a valid NLS tag
 
4141       if (line.exists(i)) {
 
4144       pos = s.indexOf(TAG_PREFIX, start);
 
4146     this.nonNLSStrings = new StringLiteral[lineLength];
 
4147     int nonNLSCounter = 0;
 
4148     for (Iterator iterator = line.iterator(); iterator.hasNext();) {
 
4149       StringLiteral literal = (StringLiteral) iterator.next();
 
4150       if (literal != null) {
 
4151         this.nonNLSStrings[nonNLSCounter++] = literal;
 
4154     if (nonNLSCounter == 0) {
 
4155       this.nonNLSStrings = null;
 
4159     this.wasNonExternalizedStringLiteral = true;
 
4160     if (nonNLSCounter != lineLength) {
 
4161       System.arraycopy(this.nonNLSStrings, 0, (this.nonNLSStrings = new StringLiteral[nonNLSCounter]), 0, nonNLSCounter);
 
4166   public final void scanEscapeCharacter() throws InvalidInputException {
 
4167     // the string with "\\u" is a legal string of two chars \ and u
 
4168     //thus we use a direct access to the source (for regular cases).
 
4169     if (unicodeAsBackSlash) {
 
4170       // consume next character
 
4171       unicodeAsBackSlash = false;
 
4172       //                        if (((currentCharacter = source[currentPosition++]) == '\\') &&
 
4173       // (source[currentPosition] == 'u')) {
 
4174       //                                getNextUnicodeChar();
 
4176       if (withoutUnicodePtr != 0) {
 
4177         withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
 
4181       currentCharacter = source[currentPosition++];
 
4182     switch (currentCharacter) {
 
4184       currentCharacter = '\b';
 
4187       currentCharacter = '\t';
 
4190       currentCharacter = '\n';
 
4193       currentCharacter = '\f';
 
4196       currentCharacter = '\r';
 
4199       currentCharacter = '\"';
 
4202       currentCharacter = '\'';
 
4205       currentCharacter = '\\';
 
4208       // -----------octal escape--------------
 
4210       // OctalDigit OctalDigit
 
4211       // ZeroToThree OctalDigit OctalDigit
 
4212       int number = Character.getNumericValue(currentCharacter);
 
4213       if (number >= 0 && number <= 7) {
 
4214         boolean zeroToThreeNot = number > 3;
 
4215         if (Character.isDigit(currentCharacter = source[currentPosition++])) {
 
4216           int digit = Character.getNumericValue(currentCharacter);
 
4217           if (digit >= 0 && digit <= 7) {
 
4218             number = (number * 8) + digit;
 
4219             if (Character.isDigit(currentCharacter = source[currentPosition++])) {
 
4220               if (zeroToThreeNot) { // has read \NotZeroToThree OctalDigit
 
4221                 // Digit --> ignore last character
 
4224                 digit = Character.getNumericValue(currentCharacter);
 
4225                 if (digit >= 0 && digit <= 7) { // has read \ZeroToThree
 
4226                   // OctalDigit OctalDigit
 
4227                   number = (number * 8) + digit;
 
4228                 } else { // has read \ZeroToThree OctalDigit NonOctalDigit
 
4229                   // --> ignore last character
 
4233             } else { // has read \OctalDigit NonDigit--> ignore last
 
4237           } else { // has read \OctalDigit NonOctalDigit--> ignore last
 
4241         } else { // has read \OctalDigit --> ignore last character
 
4245           throw new InvalidInputException(INVALID_ESCAPE);
 
4246         currentCharacter = (char) number;
 
4248         throw new InvalidInputException(INVALID_ESCAPE);
 
4252   //chech presence of task: tags
 
4253   //TODO (frederic) see if we need to take unicode characters into account...
 
4254   public void checkTaskTag(int commentStart, int commentEnd) {
 
4255     char[] src = this.source;
 
4257     // only look for newer task: tags
 
4258     if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) {
 
4261     int foundTaskIndex = this.foundTaskCount;
 
4262     char previous = src[commentStart + 1]; // should be '*' or '/'
 
4263     nextChar: for (int i = commentStart + 2; i < commentEnd && i < this.eofPosition; i++) {
 
4265       char[] priority = null;
 
4266       // check for tag occurrence only if not ambiguous with javadoc tag
 
4267       if (previous != '@') {
 
4268         nextTag: for (int itag = 0; itag < this.taskTags.length; itag++) {
 
4269           tag = this.taskTags[itag];
 
4270           int tagLength = tag.length;
 
4274           // ensure tag is not leaded with letter if tag starts with a letter
 
4275           if (Scanner.isPHPIdentifierStart(tag[0])) {
 
4276             if (Scanner.isPHPIdentifierPart(previous)) {
 
4281           for (int t = 0; t < tagLength; t++) {
 
4284             if (x >= this.eofPosition || x >= commentEnd)
 
4286             if ((sc = src[i + t]) != (tc = tag[t])) { // case sensitive check
 
4287               if (this.isTaskCaseSensitive || (Character.toLowerCase(sc) != Character.toLowerCase(tc))) { // case insensitive check
 
4292           // ensure tag is not followed with letter if tag finishes with a letter
 
4293           if (i + tagLength < commentEnd && Scanner.isPHPIdentifierPart(src[i + tagLength - 1])) {
 
4294             if (Scanner.isPHPIdentifierPart(src[i + tagLength]))
 
4297           if (this.foundTaskTags == null) {
 
4298             this.foundTaskTags = new char[5][];
 
4299             this.foundTaskMessages = new char[5][];
 
4300             this.foundTaskPriorities = new char[5][];
 
4301             this.foundTaskPositions = new int[5][];
 
4302           } else if (this.foundTaskCount == this.foundTaskTags.length) {
 
4303             System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0,
 
4304                 this.foundTaskCount);
 
4305             System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0,
 
4306                 this.foundTaskCount);
 
4307             System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0,
 
4308                 this.foundTaskCount);
 
4309             System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0,
 
4310                 this.foundTaskCount);
 
4313           priority = this.taskPriorities != null && itag < this.taskPriorities.length ? this.taskPriorities[itag] : null;
 
4315           this.foundTaskTags[this.foundTaskCount] = tag;
 
4316           this.foundTaskPriorities[this.foundTaskCount] = priority;
 
4317           this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 };
 
4318           this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR;
 
4319           this.foundTaskCount++;
 
4320           i += tagLength - 1; // will be incremented when looping
 
4326     for (int i = foundTaskIndex; i < this.foundTaskCount; i++) {
 
4327       // retrieve message start and end positions
 
4328       int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length;
 
4329       int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd - 1;
 
4330       // at most beginning of next task
 
4331       if (max_value < msgStart) {
 
4332         max_value = msgStart; // would only occur if tag is before EOF.
 
4336       for (int j = msgStart; j < max_value; j++) {
 
4337         if ((c = src[j]) == '\n' || c == '\r') {
 
4343         for (int j = max_value; j > msgStart; j--) {
 
4344           if ((c = src[j]) == '*') {
 
4352       if (msgStart == end)
 
4355       while (CharOperation.isWhitespace(src[end]) && msgStart <= end)
 
4357       while (CharOperation.isWhitespace(src[msgStart]) && msgStart <= end)
 
4359       // update the end position of the task
 
4360       this.foundTaskPositions[i][1] = end;
 
4361       // get the message source
 
4362       final int messageLength = end - msgStart + 1;
 
4363       char[] message = new char[messageLength];
 
4364       System.arraycopy(src, msgStart, message, 0, messageLength);
 
4365       this.foundTaskMessages[i] = message;
 
4369   // chech presence of task: tags
 
4370   //  public void checkTaskTag(int commentStart, int commentEnd) {
 
4371   //    // only look for newer task: tags
 
4372   //    if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) {
 
4375   //    int foundTaskIndex = this.foundTaskCount;
 
4376   //    nextChar: for (int i = commentStart; i < commentEnd && i < this.eofPosition; i++) {
 
4377   //      char[] tag = null;
 
4378   //      char[] priority = null;
 
4379   //      // check for tag occurrence
 
4380   //      nextTag: for (int itag = 0; itag < this.taskTags.length; itag++) {
 
4381   //        tag = this.taskTags[itag];
 
4382   //        priority = this.taskPriorities != null && itag < this.taskPriorities.length ? this.taskPriorities[itag] : null;
 
4383   //        int tagLength = tag.length;
 
4384   //        for (int t = 0; t < tagLength; t++) {
 
4385   //          if (this.source[i + t] != tag[t])
 
4386   //            continue nextTag;
 
4388   //        if (this.foundTaskTags == null) {
 
4389   //          this.foundTaskTags = new char[5][];
 
4390   //          this.foundTaskMessages = new char[5][];
 
4391   //          this.foundTaskPriorities = new char[5][];
 
4392   //          this.foundTaskPositions = new int[5][];
 
4393   //        } else if (this.foundTaskCount == this.foundTaskTags.length) {
 
4394   //          System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
 
4395   //          System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0,
 
4396   //              this.foundTaskCount);
 
4397   //          System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0,
 
4398   //              this.foundTaskCount);
 
4399   //          System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0,
 
4400   //              this.foundTaskCount);
 
4402   //        this.foundTaskTags[this.foundTaskCount] = tag;
 
4403   //        this.foundTaskPriorities[this.foundTaskCount] = priority;
 
4404   //        this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 };
 
4405   //        this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR;
 
4406   //        this.foundTaskCount++;
 
4407   //        i += tagLength - 1; // will be incremented when looping
 
4410   //    for (int i = foundTaskIndex; i < this.foundTaskCount; i++) {
 
4411   //      // retrieve message start and end positions
 
4412   //      int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length;
 
4413   //      int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd - 1;
 
4414   //      // at most beginning of next task
 
4415   //      if (max_value < msgStart)
 
4416   //        max_value = msgStart; // would only occur if tag is before EOF.
 
4419   //      for (int j = msgStart; j < max_value; j++) {
 
4420   //        if ((c = this.source[j]) == '\n' || c == '\r') {
 
4426   //        for (int j = max_value; j > msgStart; j--) {
 
4427   //          if ((c = this.source[j]) == '*') {
 
4435   //      if (msgStart == end)
 
4436   //        continue; // empty
 
4437   //      // trim the message
 
4438   //      while (CharOperation.isWhitespace(source[end]) && msgStart <= end)
 
4440   //      while (CharOperation.isWhitespace(source[msgStart]) && msgStart <= end)
 
4442   //      // update the end position of the task
 
4443   //      this.foundTaskPositions[i][1] = end;
 
4444   //      // get the message source
 
4445   //      final int messageLength = end - msgStart + 1;
 
4446   //      char[] message = new char[messageLength];
 
4447   //      System.arraycopy(source, msgStart, message, 0, messageLength);
 
4448   //      this.foundTaskMessages[i] = message;