123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- /*
- * 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. Alternatively, the contents of this file may be used under
- * the terms of the GNU Lesser General Public License Version 2.1 or later.
- *
- * 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.
- */
-
- package javassist.compiler;
-
- class Token {
- public Token next = null;
- public int tokenId;
-
- public long longValue;
- public double doubleValue;
- public String textValue;
- }
-
- public class Lex implements TokenId {
- private int lastChar;
- private StringBuffer textBuffer;
- private Token currentToken;
- private Token lookAheadTokens;
-
- private String input;
- private int position, maxlen, lineNumber;
-
- /**
- * 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;
- }
-
- public int get() {
- 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);
- }
-
- 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;
- }
-
- public String getString() {
- return currentToken.textValue;
- }
-
- public long getLong() {
- return currentToken.longValue;
- }
-
- public double getDouble() {
- return currentToken.doubleValue;
- }
-
- private int get(Token token) {
- 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);
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
- }
-
- 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;
- }
- }
-
- // !"#$%&'( )*+,-./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 };
-
- 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;
- }
-
- 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;
- }
- }
-
- 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);
- }
-
- private static boolean isBlank(int c) {
- return c == ' ' || c == '\t' || c == '\f' || c == '\r'
- || c == '\n';
- }
-
- private static boolean isDigit(int c) {
- return '0' <= c && c <= '9';
- }
-
- private void ungetc(int 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;
- }
- }
- }
|