diff options
Diffstat (limited to 'src/main/javassist/compiler/Lex.java')
-rw-r--r-- | src/main/javassist/compiler/Lex.java | 881 |
1 files changed, 435 insertions, 446 deletions
diff --git a/src/main/javassist/compiler/Lex.java b/src/main/javassist/compiler/Lex.java index fb188de5..69175dee 100644 --- a/src/main/javassist/compiler/Lex.java +++ b/src/main/javassist/compiler/Lex.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved. * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.compiler; class Token { @@ -47,501 +36,501 @@ public class Lex implements TokenId { * Constructs a lexical analyzer. */ public Lex(String s) { - lastChar = -1; - textBuffer = new StringBuffer(); - currentToken = new Token(); - lookAheadTokens = null; - - input = s; - position = 0; - maxlen = s.length(); - lineNumber = 0; + lastChar = -1; + textBuffer = new StringBuffer(); + currentToken = new Token(); + lookAheadTokens = null; + + input = s; + position = 0; + maxlen = s.length(); + lineNumber = 0; } public int get() { - if (lookAheadTokens == null) - return get(currentToken); - else { - Token t; - currentToken = t = lookAheadTokens; - lookAheadTokens = lookAheadTokens.next; - return t.tokenId; - } + if (lookAheadTokens == null) + return get(currentToken); + else { + Token t; + currentToken = t = lookAheadTokens; + lookAheadTokens = lookAheadTokens.next; + return t.tokenId; + } } /** * Looks at the next token. */ public int lookAhead() { - return lookAhead(0); + return lookAhead(0); } public int lookAhead(int i) { - Token tk = lookAheadTokens; - if (tk == null) { - lookAheadTokens = tk = currentToken; // reuse an object! - tk.next = null; - get(tk); - } - - for (; i-- > 0; tk = tk.next) - if (tk.next == null) { - Token tk2; - tk.next = tk2 = new Token(); - get(tk2); - } - - currentToken = tk; - return tk.tokenId; + Token tk = lookAheadTokens; + if (tk == null) { + lookAheadTokens = tk = currentToken; // reuse an object! + tk.next = null; + get(tk); + } + + for (; i-- > 0; tk = tk.next) + if (tk.next == null) { + Token tk2; + tk.next = tk2 = new Token(); + get(tk2); + } + + currentToken = tk; + return tk.tokenId; } public String getString() { - return currentToken.textValue; + return currentToken.textValue; } public long getLong() { - return currentToken.longValue; + return currentToken.longValue; } public double getDouble() { - return currentToken.doubleValue; + return currentToken.doubleValue; } private int get(Token token) { - int t; - do { - t = readLine(token); - } while (t == '\n'); - token.tokenId = t; - return t; + int t; + do { + t = readLine(token); + } while (t == '\n'); + token.tokenId = t; + return t; } private int readLine(Token token) { - int c = getNextNonWhiteChar(); - if(c < 0) - return c; - else if(c == '\n') { - ++lineNumber; - return '\n'; - } - else if (c == '\'') - return readCharConst(token); - else if (c == '"') - return readStringL(token); - else if ('0' <= c && c <= '9') - return readNumber(c, token); - else if(c == '.'){ - c = getc(); - if ('0' <= c && c <= '9') { - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - tbuf.append('.'); - return readDouble(tbuf, c, token); - } - else{ - ungetc(c); - return readSeparator('.'); - } - } - else if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_' - || c == '$') - return readIdentifier(c, token); - else - return readSeparator(c); + int c = getNextNonWhiteChar(); + if(c < 0) + return c; + else if(c == '\n') { + ++lineNumber; + return '\n'; + } + else if (c == '\'') + return readCharConst(token); + else if (c == '"') + return readStringL(token); + else if ('0' <= c && c <= '9') + return readNumber(c, token); + else if(c == '.'){ + c = getc(); + if ('0' <= c && c <= '9') { + StringBuffer tbuf = textBuffer; + tbuf.setLength(0); + tbuf.append('.'); + return readDouble(tbuf, c, token); + } + else{ + ungetc(c); + return readSeparator('.'); + } + } + else if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_' + || c == '$') + return readIdentifier(c, token); + else + return readSeparator(c); } private int getNextNonWhiteChar() { - int c; - do { - c = getc(); - if (c == '/') { - c = getc(); - if (c == '/') - do { - c = getc(); - } while (c != '\n' && c != '\r' && c != -1); - else if (c == '*') - while (true) { - c = getc(); - if (c == -1) - break; - else if (c == '*') - if ((c = getc()) == '/') { - c = ' '; - break; - } - else - ungetc(c); - } - else { - ungetc(c); - c = '/'; - } - } - } while(isBlank(c)); - return c; + int c; + do { + c = getc(); + if (c == '/') { + c = getc(); + if (c == '/') + do { + c = getc(); + } while (c != '\n' && c != '\r' && c != -1); + else if (c == '*') + while (true) { + c = getc(); + if (c == -1) + break; + else if (c == '*') + if ((c = getc()) == '/') { + c = ' '; + break; + } + else + ungetc(c); + } + else { + ungetc(c); + c = '/'; + } + } + } while(isBlank(c)); + return c; } private int readCharConst(Token token) { - int c; - int value = 0; - while ((c = getc()) != '\'') - if (c == '\\') - value = readEscapeChar(); - else if (c < 0x20) { - if (c == '\n') - ++lineNumber; - - return BadToken; - } - else - value = c; - - token.longValue = value; - return CharConstant; + int c; + int value = 0; + while ((c = getc()) != '\'') + if (c == '\\') + value = readEscapeChar(); + else if (c < 0x20) { + if (c == '\n') + ++lineNumber; + + return BadToken; + } + else + value = c; + + token.longValue = value; + return CharConstant; } private int readEscapeChar() { - int c = getc(); - if (c == 'n') - c = '\n'; - else if (c == 't') - c = '\t'; - else if (c == 'r') - c = '\r'; - else if (c == 'f') - c = '\f'; - else if (c == '\n') - ++lineNumber; - - return c; + int c = getc(); + if (c == 'n') + c = '\n'; + else if (c == 't') + c = '\t'; + else if (c == 'r') + c = '\r'; + else if (c == 'f') + c = '\f'; + else if (c == '\n') + ++lineNumber; + + return c; } private int readStringL(Token token) { - int c; - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - for (;;) { - while ((c = getc()) != '"') { - if (c == '\\') - c = readEscapeChar(); - else if (c == '\n' || c < 0) { - ++lineNumber; - return BadToken; - } - - tbuf.append((char)c); - } - - for (;;) { - c = getc(); - if (c == '\n') - ++lineNumber; - else if (!isBlank(c)) - break; - } - - if (c != '"') { - ungetc(c); - break; - } - } - - token.textValue = tbuf.toString(); - return StringL; + int c; + StringBuffer tbuf = textBuffer; + tbuf.setLength(0); + for (;;) { + while ((c = getc()) != '"') { + if (c == '\\') + c = readEscapeChar(); + else if (c == '\n' || c < 0) { + ++lineNumber; + return BadToken; + } + + tbuf.append((char)c); + } + + for (;;) { + c = getc(); + if (c == '\n') + ++lineNumber; + else if (!isBlank(c)) + break; + } + + if (c != '"') { + ungetc(c); + break; + } + } + + token.textValue = tbuf.toString(); + return StringL; } private int readNumber(int c, Token token) { - long value = 0; - int c2 = getc(); - if (c == '0') - if (c2 == 'X' || c2 == 'x') - for (;;) { - c = getc(); - if ('0' <= c && c <= '9') - value = value * 16 + (long)(c - '0'); - else if ('A' <= c && c <= 'F') - value = value * 16 + (long)(c - 'A' + 10); - else if ('a' <= c && c <= 'f') - value = value * 16 + (long)(c - 'a' + 10); - else { - token.longValue = value; - if (c == 'L' || c == 'l') - return LongConstant; - else { - ungetc(c); - return IntConstant; - } - } - } - else if ('0' <= c2 && c2 <= '7') { - value = c2 - '0'; - for (;;) { - c = getc(); - if ('0' <= c && c <= '7') - value = value * 8 + (long)(c - '0'); - else { - token.longValue = value; - if (c == 'L' || c == 'l') - return LongConstant; - else { - ungetc(c); - return IntConstant; - } - } - } - } - - value = c - '0'; - while ('0' <= c2 && c2 <= '9') { - value = value * 10 + c2 - '0'; - c2 = getc(); - } - - token.longValue = value; - if (c2 == 'F' || c2 == 'f') { - token.doubleValue = (double)value; - return FloatConstant; - } - else if (c2 == 'E' || c2 == 'e' || c2 == '.') { - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - tbuf.append(value); - return readDouble(tbuf, c2, token); - } - else if (c2 == 'L' || c2 == 'l') - return LongConstant; - else { - ungetc(c2); - return IntConstant; - } + long value = 0; + int c2 = getc(); + if (c == '0') + if (c2 == 'X' || c2 == 'x') + for (;;) { + c = getc(); + if ('0' <= c && c <= '9') + value = value * 16 + (long)(c - '0'); + else if ('A' <= c && c <= 'F') + value = value * 16 + (long)(c - 'A' + 10); + else if ('a' <= c && c <= 'f') + value = value * 16 + (long)(c - 'a' + 10); + else { + token.longValue = value; + if (c == 'L' || c == 'l') + return LongConstant; + else { + ungetc(c); + return IntConstant; + } + } + } + else if ('0' <= c2 && c2 <= '7') { + value = c2 - '0'; + for (;;) { + c = getc(); + if ('0' <= c && c <= '7') + value = value * 8 + (long)(c - '0'); + else { + token.longValue = value; + if (c == 'L' || c == 'l') + return LongConstant; + else { + ungetc(c); + return IntConstant; + } + } + } + } + + value = c - '0'; + while ('0' <= c2 && c2 <= '9') { + value = value * 10 + c2 - '0'; + c2 = getc(); + } + + token.longValue = value; + if (c2 == 'F' || c2 == 'f') { + token.doubleValue = (double)value; + return FloatConstant; + } + else if (c2 == 'E' || c2 == 'e' || c2 == '.') { + StringBuffer tbuf = textBuffer; + tbuf.setLength(0); + tbuf.append(value); + return readDouble(tbuf, c2, token); + } + else if (c2 == 'L' || c2 == 'l') + return LongConstant; + else { + ungetc(c2); + return IntConstant; + } } private int readDouble(StringBuffer sbuf, int c, Token token) { - if (c != 'E' && c != 'e') { - sbuf.append((char)c); - for (;;) { - c = getc(); - if ('0' <= c && c <= '9') - sbuf.append((char)c); - else - break; - } - } - - if (c == 'E' || c == 'e') { - sbuf.append((char)c); - c = getc(); - if (c == '+' || c == '-') { - sbuf.append((char)c); - c = getc(); - } - - while ('0' <= c && c <= '9') { - sbuf.append((char)c); - c = getc(); - } - } - - try { - token.doubleValue = Double.parseDouble(sbuf.toString()); - } - catch (NumberFormatException e) { - return BadToken; - } - - if (c == 'F' || c == 'f') - return FloatConstant; - else { - ungetc(c); - return DoubleConstant; - } + if (c != 'E' && c != 'e') { + sbuf.append((char)c); + for (;;) { + c = getc(); + if ('0' <= c && c <= '9') + sbuf.append((char)c); + else + break; + } + } + + if (c == 'E' || c == 'e') { + sbuf.append((char)c); + c = getc(); + if (c == '+' || c == '-') { + sbuf.append((char)c); + c = getc(); + } + + while ('0' <= c && c <= '9') { + sbuf.append((char)c); + c = getc(); + } + } + + try { + token.doubleValue = Double.parseDouble(sbuf.toString()); + } + catch (NumberFormatException e) { + return BadToken; + } + + if (c == 'F' || c == 'f') + return FloatConstant; + else { + ungetc(c); + return DoubleConstant; + } } // !"#$%&'( )*+,-./0 12345678 9:;<=>? private static final int[] equalOps - = { NEQ, 0, 0, 0, MOD_E, AND_E, 0, 0, - 0, MUL_E, PLUS_E, 0, MINUS_E, 0, DIV_E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, LE, EQ, GE, 0 }; + = { NEQ, 0, 0, 0, MOD_E, AND_E, 0, 0, + 0, MUL_E, PLUS_E, 0, MINUS_E, 0, DIV_E, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, LE, EQ, GE, 0 }; private int readSeparator(int c) { - int c2, c3; - if ('!' <= c && c <= '?') { - int t = equalOps[c - '!']; - if (t == 0) - return c; - else { - c2 = getc(); - if (c == c2) - switch (c) { - case '=' : - return EQ; - case '+' : - return PLUSPLUS; - case '-' : - return MINUSMINUS; - case '&' : - return ANDAND; - case '<' : - c3 = getc(); - if (c3 == '=') - return LSHIFT_E; - else { - ungetc(c3); - return LSHIFT; - } - case '>' : - c3 = getc(); - if (c3 == '=') - return RSHIFT_E; - else if (c3 == '>') { - c3 = getc(); - if (c3 == '=') - return ARSHIFT_E; - else { - ungetc(c3); - return ARSHIFT; - } - } - else { - ungetc(c3); - return RSHIFT; - } - default : - break; - } - else if (c2 == '=') - return t; - } - } - else if (c == '^') { - c2 = getc(); - if (c2 == '=') - return EXOR_E; - } - else if (c == '|') { - c2 = getc(); - if (c2 == '=') - return OR_E; - else if (c2 == '|') - return OROR; - } - else - return c; - - ungetc(c2); - return c; + int c2, c3; + if ('!' <= c && c <= '?') { + int t = equalOps[c - '!']; + if (t == 0) + return c; + else { + c2 = getc(); + if (c == c2) + switch (c) { + case '=' : + return EQ; + case '+' : + return PLUSPLUS; + case '-' : + return MINUSMINUS; + case '&' : + return ANDAND; + case '<' : + c3 = getc(); + if (c3 == '=') + return LSHIFT_E; + else { + ungetc(c3); + return LSHIFT; + } + case '>' : + c3 = getc(); + if (c3 == '=') + return RSHIFT_E; + else if (c3 == '>') { + c3 = getc(); + if (c3 == '=') + return ARSHIFT_E; + else { + ungetc(c3); + return ARSHIFT; + } + } + else { + ungetc(c3); + return RSHIFT; + } + default : + break; + } + else if (c2 == '=') + return t; + } + } + else if (c == '^') { + c2 = getc(); + if (c2 == '=') + return EXOR_E; + } + else if (c == '|') { + c2 = getc(); + if (c2 == '=') + return OR_E; + else if (c2 == '|') + return OROR; + } + else + return c; + + ungetc(c2); + return c; } private int readIdentifier(int c, Token token) { - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - - do { - tbuf.append((char)c); - c = getc(); - } while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_' - || c == '$' || '0' <= c && c <= '9'); - - ungetc(c); - - String name = tbuf.toString(); - int t = ktable.lookup(name); - if (t >= 0) - return t; - else { - /* tbuf.toString() is executed quickly since it does not - * need memory copy. Using a hand-written extensible - * byte-array class instead of StringBuffer is not a good idea - * for execution speed. Converting a byte array to a String - * object is very slow. Using an extensible char array - * might be OK. - */ - token.textValue = name; - return Identifier; - } + StringBuffer tbuf = textBuffer; + tbuf.setLength(0); + + do { + tbuf.append((char)c); + c = getc(); + } while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_' + || c == '$' || '0' <= c && c <= '9'); + + ungetc(c); + + String name = tbuf.toString(); + int t = ktable.lookup(name); + if (t >= 0) + return t; + else { + /* tbuf.toString() is executed quickly since it does not + * need memory copy. Using a hand-written extensible + * byte-array class instead of StringBuffer is not a good idea + * for execution speed. Converting a byte array to a String + * object is very slow. Using an extensible char array + * might be OK. + */ + token.textValue = name; + return Identifier; + } } private static final KeywordTable ktable = new KeywordTable(); static { - ktable.append("abstract", ABSTRACT); - ktable.append("boolean", BOOLEAN); - ktable.append("break", BREAK); - ktable.append("byte", BYTE); - ktable.append("case", CASE); - ktable.append("catch", CATCH); - ktable.append("char", CHAR); - ktable.append("class", CLASS); - ktable.append("const", CONST); - ktable.append("continue", CONTINUE); - ktable.append("default", DEFAULT); - ktable.append("do", DO); - ktable.append("double", DOUBLE); - ktable.append("else", ELSE); - ktable.append("extends", EXTENDS); - ktable.append("false", FALSE); - ktable.append("final", FINAL); - ktable.append("finally", FINALLY); - ktable.append("float", FLOAT); - ktable.append("for", FOR); - ktable.append("goto", GOTO); - ktable.append("if", IF); - ktable.append("implements", IMPLEMENTS); - ktable.append("import", IMPORT); - ktable.append("instanceof", INSTANCEOF); - ktable.append("int", INT); - ktable.append("interface", INTERFACE); - ktable.append("long", LONG); - ktable.append("native", NATIVE); - ktable.append("new", NEW); - ktable.append("null", NULL); - ktable.append("package", PACKAGE); - ktable.append("private", PRIVATE); - ktable.append("protected", PROTECTED); - ktable.append("public", PUBLIC); - ktable.append("return", RETURN); - ktable.append("short", SHORT); - ktable.append("static", STATIC); - ktable.append("strict", STRICT); - ktable.append("super", SUPER); - ktable.append("switch", SWITCH); - ktable.append("synchronized", SYNCHRONIZED); - ktable.append("this", THIS); - ktable.append("throw", THROW); - ktable.append("throws", THROWS); - ktable.append("transient", TRANSIENT); - ktable.append("true", TRUE); - ktable.append("try", TRY); - ktable.append("void", VOID); - ktable.append("volatile", VOLATILE); - ktable.append("while", WHILE); + ktable.append("abstract", ABSTRACT); + ktable.append("boolean", BOOLEAN); + ktable.append("break", BREAK); + ktable.append("byte", BYTE); + ktable.append("case", CASE); + ktable.append("catch", CATCH); + ktable.append("char", CHAR); + ktable.append("class", CLASS); + ktable.append("const", CONST); + ktable.append("continue", CONTINUE); + ktable.append("default", DEFAULT); + ktable.append("do", DO); + ktable.append("double", DOUBLE); + ktable.append("else", ELSE); + ktable.append("extends", EXTENDS); + ktable.append("false", FALSE); + ktable.append("final", FINAL); + ktable.append("finally", FINALLY); + ktable.append("float", FLOAT); + ktable.append("for", FOR); + ktable.append("goto", GOTO); + ktable.append("if", IF); + ktable.append("implements", IMPLEMENTS); + ktable.append("import", IMPORT); + ktable.append("instanceof", INSTANCEOF); + ktable.append("int", INT); + ktable.append("interface", INTERFACE); + ktable.append("long", LONG); + ktable.append("native", NATIVE); + ktable.append("new", NEW); + ktable.append("null", NULL); + ktable.append("package", PACKAGE); + ktable.append("private", PRIVATE); + ktable.append("protected", PROTECTED); + ktable.append("public", PUBLIC); + ktable.append("return", RETURN); + ktable.append("short", SHORT); + ktable.append("static", STATIC); + ktable.append("strict", STRICT); + ktable.append("super", SUPER); + ktable.append("switch", SWITCH); + ktable.append("synchronized", SYNCHRONIZED); + ktable.append("this", THIS); + ktable.append("throw", THROW); + ktable.append("throws", THROWS); + ktable.append("transient", TRANSIENT); + ktable.append("true", TRUE); + ktable.append("try", TRY); + ktable.append("void", VOID); + ktable.append("volatile", VOLATILE); + ktable.append("while", WHILE); } private static boolean isBlank(int c) { - return c == ' ' || c == '\t' || c == '\f' || c == '\r' - || c == '\n'; + return c == ' ' || c == '\t' || c == '\f' || c == '\r' + || c == '\n'; } private static boolean isDigit(int c) { - return '0' <= c && c <= '9'; + return '0' <= c && c <= '9'; } private void ungetc(int c) { - lastChar = c; + lastChar = c; } private int getc() { - if (lastChar < 0) - if (position < maxlen) - return input.charAt(position++); - else - return -1; - else { - int c = lastChar; - lastChar = -1; - return c; - } + if (lastChar < 0) + if (position < maxlen) + return input.charAt(position++); + else + return -1; + else { + int c = lastChar; + lastChar = -1; + return c; + } } } |