org.dbflute.lasta.di.util.Tokenizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lasta-di Show documentation
Show all versions of lasta-di Show documentation
DI Container for LastaFlute, super forked from Seasar as Java8
The newest version!
/*
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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 org.dbflute.lasta.di.util;
/**
* トークンを認識するクラスです。
*
* @author modified by jflute (originated in Seasar)
*
*/
public class Tokenizer {
/**
* EOFをあらわします。
*/
public static final int TT_EOF = -1;
/**
* Quoteをあらわします。
*/
public static final int TT_QUOTE = '\'';
/**
* 単語をあらわします。
*/
public static final int TT_WORD = -3;
private static final int TT_NOTHING = -4;
private static final int NEED_CHAR = Integer.MAX_VALUE;
private static final int QUOTE = '\'';
private static final byte CT_WHITESPACE = 1;
private static final byte CT_ALPHA = 4;
private byte[] ctype;
private static byte[] defaultCtype = new byte[256];
private String str;
private int colno = 0;
private int ttype = TT_NOTHING;
private String sval;
private char[] buf = new char[20];
private int peekc = NEED_CHAR;
private byte peekct = 0;
static {
setup(defaultCtype);
}
/**
* {@link Tokenizer}を作成します。
*
* @param str
* 文字列
*/
public Tokenizer(String str) {
this(str, defaultCtype);
}
/**
* {@link Tokenizer}を作成します。
*
* @param str
* 文字列
* @param ctype
* 文字のタイプの配列
*/
public Tokenizer(String str, byte[] ctype) {
this.str = str;
this.ctype = ctype;
}
/**
* @param ctype2
* 文字のタイプの配列
*/
protected static void setup(byte[] ctype2) {
wordChars(ctype2, 'a', 'z');
wordChars(ctype2, 'A', 'Z');
wordChars(ctype2, '0', '9');
wordChar(ctype2, '@');
wordChar(ctype2, '|');
wordChar(ctype2, '_');
wordChar(ctype2, '?');
wordChar(ctype2, '>');
wordChar(ctype2, '=');
wordChar(ctype2, '!');
wordChar(ctype2, '<');
wordChar(ctype2, '"');
wordChar(ctype2, '~');
wordChar(ctype2, '*');
wordChar(ctype2, '.');
// ordinaryChar(ctype2, '=');
// ordinaryChar(ctype2, ',');
whitespaceChars(ctype2, 0, ' ');
}
/**
* 単語用の文字として設定します。
*
* @param ctype2
* 文字のタイプの配列
* @param low
* @param hi
*/
protected static void wordChars(byte[] ctype2, int low, int hi) {
if (low < 0) {
low = 0;
}
if (hi >= ctype2.length) {
hi = ctype2.length - 1;
}
while (low <= hi) {
ctype2[low++] |= CT_ALPHA;
}
}
/**
* 単語用の文字として設定します。
*
* @param ctype2
* 文字のタイプの配列
* @param val
* 文字コード
*/
protected static void wordChar(byte[] ctype2, int val) {
ctype2[val] |= CT_ALPHA;
}
/**
* 空白用の文字として設定します。
*
* @param ctype2
* 文字のタイプの配列
* @param low
* 最小の文字コード
* @param hi
* 最大の文字コード
*/
protected static void whitespaceChars(byte[] ctype2, int low, int hi) {
if (low < 0) {
low = 0;
}
if (hi >= ctype2.length) {
hi = ctype2.length - 1;
}
while (low <= hi) {
ctype2[low++] = CT_WHITESPACE;
}
}
/**
* 単独で存在する文字として設定します。
*
* @param ctype2
* 文字のタイプの配列
* @param ch
* 文字コード
*/
protected static void ordinaryChar(byte[] ctype2, int ch) {
if (ch >= 0 && ch < ctype2.length) {
ctype2[ch] = 0;
}
}
/**
* 文字列の値を返します。
*
* @return 文字列の値
*/
public final String getStringValue() {
return sval;
}
/**
* 次のトークンに進めます。
*
* @return トークンのタイプ
*/
public int nextToken() {
initVal();
if (processEOF()) {
return ttype;
}
if (processWhitespace()) {
return ttype;
}
if (processWord()) {
return ttype;
}
if (processQuote()) {
return ttype;
}
if (processOrdinary()) {
return ttype;
}
return ttype = peekc;
}
/**
* 既に読み込んだ文字列を返します。
*
* @return 既に読み込んだ文字列
*/
public final String getReadString() {
return str.substring(0, colno - 1);
}
private int read() {
if (colno >= str.length()) {
return -1;
}
return str.charAt(colno++);
}
private void initVal() {
sval = null;
}
private boolean processEOF() {
if (peekc < 0) {
ttype = TT_EOF;
return true;
}
if (peekc == NEED_CHAR) {
peekc = read();
if (peekc < 0) {
ttype = TT_EOF;
return true;
}
}
return false;
}
private boolean processWhitespace() {
peekct = peekc < 256 ? ctype[peekc] : CT_ALPHA;
while ((peekct & CT_WHITESPACE) != 0) {
if (peekc == '\r') {
peekc = read();
if (peekc == '\n') {
peekc = read();
}
} else {
peekc = read();
}
if (peekc < 0) {
ttype = TT_EOF;
return true;
}
peekct = peekc < 256 ? ctype[peekc] : CT_ALPHA;
}
return false;
}
private boolean processWord() {
if ((peekct & CT_ALPHA) != 0) {
int i = 0;
do {
if (i >= buf.length) {
char nb[] = new char[buf.length * 2];
System.arraycopy(buf, 0, nb, 0, buf.length);
buf = nb;
}
buf[i++] = (char) peekc;
peekc = read();
peekct = peekc < 0 ? CT_WHITESPACE : (peekc < 256 ? ctype[peekc] : CT_ALPHA);
} while ((peekct & (CT_ALPHA)) != 0);
sval = String.copyValueOf(buf, 0, i);
ttype = TT_WORD;
return true;
}
return false;
}
private boolean processQuote() {
if (peekc == QUOTE) {
ttype = QUOTE;
int i = 0;
int d = read();
int c = d;
while (d >= 0) {
if (d == QUOTE) {
int d2 = read();
if (d2 == QUOTE) {
c = QUOTE;
} else {
d = d2;
break;
}
} else {
c = d;
}
if (i >= buf.length) {
char nb[] = new char[buf.length * 2];
System.arraycopy(buf, 0, nb, 0, buf.length);
buf = nb;
}
buf[i++] = (char) c;
d = read();
}
peekc = d;
sval = String.copyValueOf(buf, 0, i);
return true;
}
return false;
}
private boolean processOrdinary() {
if (peekct == 0) {
ttype = peekc;
peekc = read();
peekct = peekc < 0 ? CT_WHITESPACE : (peekc < 256 ? ctype[peekc] : CT_ALPHA);
return true;
}
return false;
}
}