Index: editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/functions/FastDartPartitionScanner.java |
=================================================================== |
--- editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/functions/FastDartPartitionScanner.java (revision 2344) |
+++ editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/functions/FastDartPartitionScanner.java (working copy) |
@@ -1,16 +1,14 @@ |
/* |
* Copyright (c) 2011, the Dart project authors. |
- * |
- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not |
- * use this file except in compliance with the License. You may obtain a copy of |
- * the License at |
- * |
+ * |
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except |
+ * in compliance with the License. You may obtain a copy of the License at |
+ * |
* http://www.eclipse.org/legal/epl-v10.html |
- * |
- * Unless required by applicable law or agreed to in writing, software |
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
- * License for the specific language governing permissions and limitations under |
+ * |
+ * Unless required by applicable law or agreed to in writing, software distributed under the License |
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
+ * or implied. See the License for the specific language governing permissions and limitations under |
* the License. |
*/ |
package com.google.dart.tools.ui.internal.text.functions; |
@@ -26,70 +24,71 @@ |
/** |
* This scanner recognizes doc comments, multi-line comments, single-line comments, strings, and |
* multi-line strings, in addition to the default. |
- * <p> |
- * TODO Do string partitions include their delimiters? |
*/ |
public class FastDartPartitionScanner implements IPartitionTokenScanner, DartPartitions { |
+ private static class StringState { |
+ /** |
+ * The state that was current before this state. |
+ */ |
+ private StringState previous; |
- // states |
- private static final int CODE = 0; |
- private static final int SINGLE_LINE_COMMENT = 1; |
- private static final int MULTI_LINE_COMMENT = 2; |
- private static final int DOC_COMMENT = 3; |
- private static final int STRING = 4; |
- private static final int MULTI_LINE_STRING = 5; |
+ /** |
+ * A flag indicating whether this string is a raw string. |
+ */ |
+ private boolean raw; |
- // beginning of prefixes and postfixes |
- private static final int NONE = 0; |
- // postfix for STRING and CHARACTER |
- private static final int BACKSLASH = 1; |
- // prefix for SINGLE_LINE or MULTI_LINE or DOC_COMMENT |
- private static final int SLASH = 2; |
- // prefix for MULTI_LINE_COMMENT or DOC_COMMENT |
- private static final int SLASH_STAR = 3; |
- // prefix for MULTI_LINE_COMMENT or DOC_COMMENT |
- private static final int SLASH_STAR_STAR = 4; |
- // postfix for MULTI_LINE_COMMENT or DOC_COMMENT |
- private static final int STAR = 5; |
- // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT |
- private static final int CARRIAGE_RETURN = 6; |
- // anti-postfix for STRING, CHARACTER |
- private static final int BACKSLASH_CARRIAGE_RETURN = 7; |
- private static final int DOUBLE_QUOTE = 8; |
- private static final int DOUBLE_QUOTE_QUOTE = 9; |
- private static final int DOUBLE_QUOTE_QUOTE_QUOTE = 10; |
- private static final int SINGLE_QUOTE = 11; |
- private static final int SINGLE_QUOTE_QUOTE = 12; |
- private static final int SINGLE_QUOTE_QUOTE_QUOTE = 13; |
+ /** |
+ * The quote character used to start this string. |
+ */ |
+ private int quote; |
- private static final int getLastLength(int last) { |
- switch (last) { |
- default: |
- return -1; |
+ /** |
+ * The number of quote characters (1 or 3) used to start this string. |
+ */ |
+ private int quoteCount; |
- case NONE: |
- return 0; |
+ /** |
+ * The number of unclosed braces that have been encountered in the current string interpolation. |
+ */ |
+ private int braceCount; |
- case CARRIAGE_RETURN: |
- case BACKSLASH: |
- case SLASH: |
- case STAR: |
- case DOUBLE_QUOTE: |
- case SINGLE_QUOTE: |
- return 1; |
- |
- case SLASH_STAR: |
- case DOUBLE_QUOTE_QUOTE: |
- case SINGLE_QUOTE_QUOTE: |
- return 2; |
- |
- case SLASH_STAR_STAR: |
- case DOUBLE_QUOTE_QUOTE_QUOTE: |
- case SINGLE_QUOTE_QUOTE_QUOTE: |
- return 3; |
+ /** |
+ * Initialize a newly created string state to supersede the previous state. |
+ * |
+ * @param previous the state that was current before this state |
+ * @param raw a flag indicating whether this string is a raw string |
+ * @param quote the quote character used to start this string |
+ * @param quoteCount the number of quote characters (1 or 3) used to start this string |
+ */ |
+ public StringState(StringState previous, boolean raw, int quote, int quoteCount) { |
+ this.previous = previous; |
+ this.raw = raw; |
+ this.quote = quote; |
+ this.quoteCount = quoteCount; |
+ this.braceCount = 0; |
} |
} |
+ // states corresponding to partitions (used to do lookup in tokens) |
+ private static final int CODE = 0; |
+ private static final int SINGLE_LINE_COMMENT = 1; |
+ private static final int MULTI_LINE_COMMENT = 2; |
+ private static final int DOC_COMMENT = 3; |
+ private static final int STRING = 4; |
+ private static final int MULTI_LINE_STRING = 5; |
+ // other states |
+ private static final int SINGLE_LINE_COMMENT_PREFIX = 6; |
+ private static final int MULTI_LINE_COMMENT_PREFIX = 7; |
+ private static final int DOC_COMMENT_PREFIX = 8; |
+ private static final int RAW_STRING_PREFIX = 9; |
+ private static final int STRING_PREFIX = 10; |
+ private static final int RAW_MULTI_LINE_STRING_PREFIX = 11; |
+ private static final int MULTI_LINE_STRING_PREFIX = 12; |
+ private static final int SIMPLE_INTERPOLATION_PREFIX = 13; |
+ private static final int SIMPLE_INTERPOLATION = 14; |
+ private static final int BLOCK_INTERPOLATION_PREFIX = 15; |
+ private static final int BLOCK_INTERPOLATION = 16; |
+ |
private static int getState(String contentType) { |
if (contentType == null) { |
@@ -109,21 +108,32 @@ |
} |
} |
- /** The scanner. */ |
+ /** |
+ * The scanner used to read characters from the document. |
+ */ |
private final BufferedDocumentScanner scanner = new BufferedDocumentScanner(1000); // faster implementation |
- /** The offset of the last returned token. */ |
+ |
+ /** |
+ * The offset of the last returned token. |
+ */ |
private int tokenOffset; |
- /** The length of the last returned token. */ |
+ |
+ /** |
+ * The length of the last returned token. |
+ */ |
private int tokenLength; |
- /** The state of the scanner. */ |
+ |
+ /** |
+ * The state of the scanner. |
+ */ |
private int scannerState; |
- /** The last significant characters read. */ |
- private int lastChar; |
- /** The amount of characters already read on first call to nextToken(). */ |
- private int prefixLength; |
- /** The active string delimiter while scanning a STRING or MULTI_LINE_STRING */ |
- private int activeStringDelimiter; |
+ /** |
+ * The state of the string that we are currently parsing, or <code>null</code> if we are not |
+ * inside a string. |
+ */ |
+ private StringState stringState = null; |
+ |
private final IToken[] tokens = new IToken[] { |
new Token(null), new Token(DART_SINGLE_LINE_COMMENT), new Token(DART_MULTI_LINE_COMMENT), |
new Token(DART_DOC), new Token(DART_STRING), new Token(DART_MULTI_LINE_STRING)}; |
@@ -132,342 +142,242 @@ |
// create the scanner |
} |
- /* |
- * @see ITokenScanner#getTokenLength() |
- */ |
@Override |
public int getTokenLength() { |
return tokenLength; |
} |
- /* |
- * @see ITokenScanner#getTokenOffset() |
- */ |
@Override |
public int getTokenOffset() { |
return tokenOffset; |
} |
- /* |
- * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() |
- */ |
@Override |
public IToken nextToken() { |
tokenOffset += tokenLength; |
- tokenLength = prefixLength; |
- |
- // int lastNonWhitespaceChar = NONE; |
- int currentChar = NONE; |
- |
- while (true) { |
- // if (!Character.isWhitespace((char) currentChar)) |
- // lastNonWhitespaceChar = currentChar; |
- |
- // read in the next char |
- currentChar = scanner.read(); |
- |
- // characters |
- switch (currentChar) { |
- case ICharacterScanner.EOF: |
- if (tokenLength > 0) { |
- lastChar = NONE; // ignore last |
- return preFix(scannerState, CODE, NONE, 0); |
- |
+ tokenLength = 0; |
+ int currentChar = scanner.peek(0); |
+ while (currentChar != ICharacterScanner.EOF) { |
+ switch (scannerState) { |
+ case SINGLE_LINE_COMMENT_PREFIX: |
+ advance(); |
+ advance(); |
+ scannerState = SINGLE_LINE_COMMENT; |
+ break; |
+ case SINGLE_LINE_COMMENT: |
+ if (isEol(currentChar)) { |
+ scannerState = CODE; |
+ return tokens[SINGLE_LINE_COMMENT]; |
+ } |
+ advance(); |
+ break; |
+ case MULTI_LINE_COMMENT_PREFIX: |
+ advance(); |
+ advance(); |
+ scannerState = MULTI_LINE_COMMENT; |
+ break; |
+ case MULTI_LINE_COMMENT: |
+ if (currentChar == '*') { |
+ advance(); |
+ if (scanner.peek(0) == '/') { |
+ advance(); |
+ scannerState = CODE; |
+ return tokens[MULTI_LINE_COMMENT]; |
+ } |
} else { |
- lastChar = NONE; |
- prefixLength = 0; |
- return Token.EOF; |
+ advance(); |
} |
- |
- case '\r': |
- if (scannerState == STRING && lastChar == BACKSLASH) { |
- lastChar = BACKSLASH_CARRIAGE_RETURN; |
- tokenLength++; |
- continue; |
+ break; |
+ case DOC_COMMENT_PREFIX: |
+ advance(); |
+ advance(); |
+ advance(); |
+ scannerState = DOC_COMMENT; |
+ break; |
+ case DOC_COMMENT: |
+ if (currentChar == '*') { |
+ advance(); |
+ if (scanner.peek(0) == '/') { |
+ advance(); |
+ scannerState = CODE; |
+ return tokens[DOC_COMMENT]; |
+ } |
+ } else { |
+ advance(); |
} |
- if (lastChar != CARRIAGE_RETURN) { |
- lastChar = CARRIAGE_RETURN; |
- tokenLength++; |
- continue; |
- |
+ break; |
+ case RAW_STRING_PREFIX: |
+ advance(); |
+ case STRING_PREFIX: |
+ advance(); |
+ scannerState = STRING; |
+ break; |
+ case STRING: |
+ if (isEol(currentChar)) { |
+ stringState = stringState.previous; |
+ if (stringState == null) { |
+ scannerState = CODE; |
+ } else { |
+ scannerState = BLOCK_INTERPOLATION; |
+ } |
+ return tokens[STRING]; |
+ } else if (currentChar == stringState.quote) { |
+ advance(); |
+ stringState = stringState.previous; |
+ if (stringState == null) { |
+ scannerState = CODE; |
+ } else { |
+ scannerState = BLOCK_INTERPOLATION; |
+ } |
+ return tokens[STRING]; |
+ } else if (currentChar == '\\') { |
+ advance(); |
+ if (scanner.peek(0) == stringState.quote) { |
+ advance(); |
+ } |
+ } else if (!stringState.raw && currentChar == '$') { |
+ if (scanner.peek(1) == '{') { |
+ scannerState = BLOCK_INTERPOLATION_PREFIX; |
+ } else { |
+ scannerState = SIMPLE_INTERPOLATION_PREFIX; |
+ } |
+ return tokens[STRING]; |
} else { |
- switch (scannerState) { |
- case SINGLE_LINE_COMMENT: |
- case STRING: |
- if (tokenLength > 0) { |
- IToken token = tokens[scannerState]; |
- |
- lastChar = CARRIAGE_RETURN; |
- prefixLength = 1; |
- |
+ advance(); |
+ } |
+ break; |
+ case RAW_MULTI_LINE_STRING_PREFIX: |
+ advance(); |
+ case MULTI_LINE_STRING_PREFIX: |
+ advance(); |
+ advance(); |
+ advance(); |
+ scannerState = MULTI_LINE_STRING; |
+ break; |
+ case MULTI_LINE_STRING: |
+ if (currentChar == stringState.quote) { |
+ advance(); |
+ if (scanner.peek(0) == stringState.quote) { |
+ advance(); |
+ if (scanner.peek(0) == stringState.quote) { |
+ advance(); |
+ stringState = stringState.previous; |
+ if (stringState == null) { |
scannerState = CODE; |
- return token; |
- |
} else { |
- consume(); |
- continue; |
+ scannerState = BLOCK_INTERPOLATION; |
} |
- |
- default: |
- consume(); |
- continue; |
- } |
- } |
- |
- case '\n': |
- case '\u2028': |
- case '\u2029': |
- switch (scannerState) { |
- case STRING: |
- if (lastChar == BACKSLASH || lastChar == BACKSLASH_CARRIAGE_RETURN) { |
- consume(); |
- continue; |
+ return tokens[MULTI_LINE_STRING]; |
} |
- case SINGLE_LINE_COMMENT: |
- return postFix(scannerState); |
- |
- default: |
- consume(); |
- continue; |
- } |
- |
- default: |
- if (lastChar == CARRIAGE_RETURN) { |
- switch (scannerState) { |
- case SINGLE_LINE_COMMENT: |
- case STRING: |
- |
- int last; |
- int newState; |
- switch (currentChar) { |
- case '/': |
- last = SLASH; |
- newState = CODE; |
- break; |
- |
- case '*': |
- last = STAR; |
- newState = CODE; |
- break; |
- |
- case '\'': |
- case '"': |
- last = NONE; |
- newState = STRING; |
- break; |
- |
- case '\r': |
- last = CARRIAGE_RETURN; |
- newState = CODE; |
- break; |
- |
- case '\\': |
- last = BACKSLASH; |
- newState = CODE; |
- break; |
- |
- default: |
- last = NONE; |
- newState = CODE; |
- break; |
- } |
- |
- lastChar = NONE; // ignore lastChar |
- return preFix(scannerState, newState, last, 1); |
- |
- default: |
- break; |
} |
+ } else if (currentChar == '\\') { |
+ advance(); |
+ if (scanner.peek(0) == stringState.quote) { |
+ advance(); |
+ } |
+ } else if (!stringState.raw && currentChar == '$') { |
+ if (scanner.peek(1) == '{') { |
+ scannerState = BLOCK_INTERPOLATION_PREFIX; |
+ } else { |
+ scannerState = SIMPLE_INTERPOLATION_PREFIX; |
+ } |
+ return tokens[MULTI_LINE_STRING]; |
+ } else { |
+ advance(); |
} |
- } |
- |
- // states |
- switch (scannerState) { |
- case CODE: |
- switch (currentChar) { |
- case '/': |
- if (lastChar == SLASH) { |
- if (tokenLength - getLastLength(lastChar) > 0) { |
- return preFix(CODE, SINGLE_LINE_COMMENT, NONE, 2); |
- } else { |
- preFix(CODE, SINGLE_LINE_COMMENT, NONE, 2); |
- tokenOffset += tokenLength; |
- tokenLength = prefixLength; |
- break; |
- } |
- |
- } else { |
- tokenLength++; |
- lastChar = SLASH; |
- break; |
- } |
- |
- case '*': |
- if (lastChar == SLASH) { |
- if (tokenLength - getLastLength(lastChar) > 0) { |
- return preFix(CODE, MULTI_LINE_COMMENT, SLASH_STAR, 2); |
- } else { |
- preFix(CODE, MULTI_LINE_COMMENT, SLASH_STAR, 2); |
- tokenOffset += tokenLength; |
- tokenLength = prefixLength; |
- break; |
- } |
- |
- } else { |
- consume(); |
- break; |
- } |
- |
- case '\'': |
- case '\"': |
- activeStringDelimiter = currentChar; |
- lastChar = NONE; // ignore lastChar |
- if (tokenLength > 0) { |
- // set lastChar = currentChar |
- return preFix(CODE, STRING, currentChar, 1); |
- } else { |
- // set lastChar = currentChar |
- preFix(CODE, STRING, currentChar, 1); |
- tokenOffset += tokenLength; |
- tokenLength = prefixLength; |
- break; |
- } |
- |
- default: |
- consume(); |
- break; |
- } |
break; |
- |
- case SINGLE_LINE_COMMENT: |
- consume(); |
+ case SIMPLE_INTERPOLATION_PREFIX: |
+ advance(); |
+ scannerState = SIMPLE_INTERPOLATION; |
break; |
- |
- case DOC_COMMENT: |
- switch (currentChar) { |
- case '/': |
- switch (lastChar) { |
- case SLASH_STAR_STAR: |
- return postFix(MULTI_LINE_COMMENT); |
- |
- case STAR: |
- return postFix(DOC_COMMENT); |
- |
- default: |
- consume(); |
- break; |
- } |
- break; |
- |
- case '*': |
- tokenLength++; |
- lastChar = STAR; |
- break; |
- |
- default: |
- consume(); |
- break; |
+ case SIMPLE_INTERPOLATION: |
+ if (!isIdentifierChar(currentChar)) { |
+ if (stringState.quoteCount == 1) { |
+ scannerState = STRING; |
+ } else { |
+ scannerState = MULTI_LINE_STRING; |
+ } |
+ return tokens[CODE]; |
} |
+ advance(); |
break; |
- |
- case MULTI_LINE_COMMENT: |
- switch (currentChar) { |
- case '*': |
- if (lastChar == SLASH_STAR) { |
- lastChar = SLASH_STAR_STAR; |
- tokenLength++; |
- scannerState = DOC_COMMENT; |
- } else { |
- tokenLength++; |
- lastChar = STAR; |
- } |
- break; |
- |
- case '/': |
- if (lastChar == STAR) { |
- return postFix(MULTI_LINE_COMMENT); |
- } else { |
- consume(); |
- break; |
- } |
- |
- default: |
- consume(); |
- break; |
- } |
+ case BLOCK_INTERPOLATION_PREFIX: |
+ advance(); |
+ advance(); |
+ scannerState = BLOCK_INTERPOLATION; |
break; |
- |
- case STRING: |
- switch (currentChar) { |
- case '\\': |
- lastChar = (lastChar == BACKSLASH) ? NONE : BACKSLASH; |
- tokenLength++; |
- break; |
- |
- case '\'': |
- case '\"': |
- if (currentChar != activeStringDelimiter) { |
- consume(); |
- break; |
- } |
- if (lastChar == currentChar) { |
- int ch = scanner.read(); |
- if (ch == currentChar) { |
- tokenLength++; |
- lastChar = activeStringDelimiter == '\"' ? DOUBLE_QUOTE_QUOTE |
- : SINGLE_QUOTE_QUOTE; |
- return preFix(CODE, MULTI_LINE_STRING, NONE, 3); |
- } |
- scanner.unread(); |
- } |
- if (lastChar != BACKSLASH) { |
- return postFix(STRING); |
- |
+ case BLOCK_INTERPOLATION: |
+ if (currentChar == '}') { |
+ if (stringState.braceCount == 0) { |
+ advance(); |
+ if (stringState.quoteCount == 1) { |
+ scannerState = STRING; |
} else { |
- consume(); |
- break; |
+ scannerState = MULTI_LINE_STRING; |
} |
- |
- default: |
- consume(); |
- break; |
+ return tokens[CODE]; |
+ } else { |
+ stringState.braceCount--; |
+ } |
+ } else if (currentChar == '{') { |
+ stringState.braceCount++; |
} |
- break; |
- |
- case MULTI_LINE_STRING: |
- switch (currentChar) { |
- case '\"': |
- case '\'': |
- if (currentChar != activeStringDelimiter) { |
- consume(); |
- break; |
+ // Intentional fall-through |
+ case CODE: |
+ if (currentChar == '/') { |
+ int nextChar = scanner.peek(1); |
+ if (nextChar == '*') { |
+ scannerState = MULTI_LINE_COMMENT_PREFIX; |
+ if (scanner.peek(2) == '*' && scanner.peek(3) != '/') { |
+ scannerState = DOC_COMMENT_PREFIX; |
} |
- if (lastChar == DOUBLE_QUOTE_QUOTE) { |
- lastChar = DOUBLE_QUOTE_QUOTE_QUOTE; |
- return postFix(MULTI_LINE_STRING); |
- } else if (lastChar == DOUBLE_QUOTE) { |
- lastChar = DOUBLE_QUOTE_QUOTE; |
- } else if (lastChar == SINGLE_QUOTE_QUOTE) { |
- lastChar = SINGLE_QUOTE_QUOTE_QUOTE; |
- return postFix(MULTI_LINE_STRING); |
- } else if (lastChar == SINGLE_QUOTE) { |
- lastChar = SINGLE_QUOTE_QUOTE; |
+ return tokens[CODE]; |
+ } else if (nextChar == '/') { |
+ scannerState = SINGLE_LINE_COMMENT_PREFIX; |
+ return tokens[CODE]; |
+ } else { |
+ advance(); |
+ } |
+ } else if (currentChar == '@') { |
+ int secondChar = scanner.peek(1); |
+ if (secondChar == '\'' || secondChar == '"') { |
+ int thirdChar = scanner.peek(2); |
+ int fourthChar = scanner.peek(3); |
+ if (thirdChar == secondChar && fourthChar == secondChar) { |
+ stringState = new StringState(stringState, true, secondChar, 3); |
+ scannerState = RAW_MULTI_LINE_STRING_PREFIX; |
} else { |
- lastChar = activeStringDelimiter == '\"' ? DOUBLE_QUOTE : SINGLE_QUOTE; |
+ stringState = new StringState(stringState, true, secondChar, 1); |
+ scannerState = RAW_STRING_PREFIX; |
} |
- tokenLength++; |
- break; |
- default: |
- consume(); |
- break; |
+ return tokens[CODE]; |
+ } else { |
+ advance(); |
+ } |
+ } else if (currentChar == '\'' || currentChar == '"') { |
+ int secondChar = scanner.peek(1); |
+ int thirdChar = scanner.peek(2); |
+ if (secondChar == currentChar && thirdChar == currentChar) { |
+ stringState = new StringState(stringState, false, currentChar, 3); |
+ scannerState = MULTI_LINE_STRING_PREFIX; |
+ } else { |
+ stringState = new StringState(stringState, false, currentChar, 1); |
+ scannerState = STRING_PREFIX; |
+ } |
+ return tokens[CODE]; |
+ } else { |
+ advance(); |
} |
+ break; |
} |
+ currentChar = scanner.peek(0); |
} |
+ if (tokenLength > 0) { |
+ return tokens[scannerState]; |
+ } |
+ return Token.EOF; |
} |
- /* |
- * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int) |
- */ |
@Override |
public void setPartialRange(IDocument document, int offset, int length, String contentType, |
int partitionOffset) { |
@@ -480,8 +390,6 @@ |
scanner.setRange(document, offset, length); |
tokenOffset = partitionOffset; |
tokenLength = 0; |
- prefixLength = offset - partitionOffset; |
- lastChar = NONE; |
if (offset == partitionOffset) { |
// restart at beginning of partition |
@@ -491,39 +399,25 @@ |
} |
} |
- /* |
- * @see ITokenScanner#setRange(IDocument, int, int) |
- */ |
@Override |
public void setRange(IDocument document, int offset, int length) { |
scanner.setRange(document, offset, length); |
tokenOffset = offset; |
tokenLength = 0; |
- prefixLength = 0; |
- lastChar = NONE; |
scannerState = CODE; |
} |
- private final void consume() { |
+ private void advance() { |
tokenLength++; |
- lastChar = NONE; |
+ scanner.read(); |
} |
- private final IToken postFix(int state) { |
- tokenLength++; |
- lastChar = NONE; |
- scannerState = CODE; |
- prefixLength = 0; |
- return tokens[state]; |
+ private boolean isEol(int character) { |
+ return character == '\r' || character == '\n' || character == '\u2028' || character == '\u2029'; |
} |
- private final IToken preFix(int state, int newState, int last, int prefLength) { |
- tokenLength -= getLastLength(lastChar); |
- lastChar = last; |
- prefixLength = prefLength; |
- IToken token = tokens[state]; |
- scannerState = newState; |
- return token; |
+ private boolean isIdentifierChar(int character) { |
+ return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') |
+ || (character >= '0' && character <= '9') || character == '_'; |
} |
- |
} |