/*
* Copyright © 2010-2011 Rebecca G. Bettencourt / Kreative Software
* <p>
* 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
* <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
* <p>
* 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.
* <p>
* Alternatively, the contents of this file may be used under the terms
* of the GNU Lesser General Public License (the "LGPL License"), in which
* case the provisions of LGPL License are applicable instead of those
* above. If you wish to allow use of your version of this file only
* under the terms of the LGPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the LGPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the LGPL License.
* @since KSFL 1.2
* @author Rebecca G. Bettencourt, Kreative Software
*/
package com.kreative.binpack;
import java.io.IOException;
import java.io.Reader;
import java.util.Vector;
public class DFExpressionLexer {
// Change this number to adjust how long tokens can be.
private static final int LOOKAHEAD_LIMIT = 65536;
private Reader reader;
private Vector<String> buffer;
private String lastToken;
public DFExpressionLexer(Reader r) {
this.reader = r;
this.buffer = new Vector<String>();
this.lastToken = null;
}
private String internalGetNextToken() throws IOException {
int firstChar = reader.read();
while (Character.isWhitespace(firstChar)) {
firstChar = reader.read();
}
if (firstChar < 0) {
return null;
} else if (firstChar == '"' || firstChar == '\'' || firstChar == '`') {
StringBuffer s = new StringBuffer();
s.append(Character.toChars(firstChar));
while (true) {
int nextChar = reader.read();
if (nextChar < 0) break;
s.append(Character.toChars(nextChar));
if (nextChar == firstChar) break;
}
return s.toString();
} else if (Character.isDigit(firstChar) || Character.isLetter(firstChar) || firstChar == '_') {
reader.mark(LOOKAHEAD_LIMIT);
int numChars = 0;
while (true) {
int nextChar = reader.read();
if (nextChar < 0 || !(
Character.isDigit(nextChar)
|| Character.isLetter(nextChar)
|| (nextChar == '_')
)) break;
numChars++;
}
reader.reset();
StringBuffer s = new StringBuffer();
s.append(Character.toChars(firstChar));
while (numChars-->0) {
s.append(Character.toChars(reader.read()));
}
return s.toString();
} else {
StringBuffer s;
String ss;
reader.mark(LOOKAHEAD_LIMIT);
int secondChar = reader.read();
int thirdChar = reader.read();
s = new StringBuffer();
s.append(Character.toChars(firstChar));
if (secondChar >= 0) s.append(Character.toChars(secondChar));
if (thirdChar >= 0) s.append(Character.toChars(thirdChar));
ss = s.toString();
if (ss.equals(">>>") || ss.equals("<=>")) {
return ss;
}
s = new StringBuffer();
s.append(Character.toChars(firstChar));
if (secondChar >= 0) s.append(Character.toChars(secondChar));
ss = s.toString();
if (
ss.equals("!!") || ss.equals("<<") || ss.equals(">>")
|| ss.equals("<=") || ss.equals(">=")
|| ss.equals("==") || ss.equals("!=") || ss.equals("<>")
|| ss.equals("&&") || ss.equals("^^") || ss.equals("||")
) {
reader.reset();
reader.read();
return ss;
}
s = new StringBuffer();
s.append(Character.toChars(firstChar));
ss = s.toString();
reader.reset();
return ss;
}
}
public String lookToken(int i) throws IOException {
if (i < 1) return lastToken;
while (i > buffer.size()) {
String token = internalGetNextToken();
if (token == null) return null;
else buffer.add(token);
}
return buffer.get(i-1);
}
public String getToken() throws IOException {
if (buffer.isEmpty()) {
return lastToken = internalGetNextToken();
} else {
return lastToken = buffer.remove(0);
}
}
}