CaRMtl/rene/util/parser/StringParser.java

373 lines
6.5 KiB
Java

/*
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
This file is part of C.a.R. software.
C.a.R. is a free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
C.a.R. 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package rene.util.parser;
import java.util.Vector;
/**
* This is a string simple parser.
*/
public class StringParser {
char C[];
int N, L;
boolean Error;
/**
* @param S
* the string to be parsed.
*/
public StringParser(final String S) {
C = S.toCharArray();
N = 0;
L = C.length;
Error = (N >= L);
}
/**
* @return next character is white?
*/
public boolean blank() {
return (C[N] == ' ' || C[N] == '\t' || C[N] == '\n' || C[N] == '\r');
}
/**
* @return next character is white or c?
*/
public boolean blank(final char c) {
return (C[N] == ' ' || C[N] == '\t' || C[N] == '\n' || C[N] == '\r' || C[N] == c);
}
/**
* Cut off the String upto a character c.
*/
public String upto(final char c) {
if (Error)
return "";
int n = N;
while (n < L && C[n] != c)
n++;
if (n >= L)
Error = true;
final String s = new String(C, N, n - N);
N = n;
return s;
}
/**
* Advance one character.
*
* @return String is not empty.
*/
public boolean advance() {
if (N < L)
N++;
if (N >= L)
Error = true;
return !Error;
}
/**
* Parse a word up to a blank.
*/
public String parseword() {
if (Error)
return "";
while (blank()) {
if (!advance())
return "";
}
final int n = N;
while (!Error && !blank())
advance();
return new String(C, n, N - n);
}
/**
* Parse digits upto the character c or blank.
*/
public String parsedigits(final char c) {
if (Error)
return "";
while (blank()) {
if (!advance())
return "";
}
final int n = N;
while (!Error && !blank()) {
if (N > L || C[N] < '0' || C[N] > '9' || C[N] == c)
break;
advance();
}
return new String(C, n, N - n);
}
/**
* Parse digits upto a blank.
*/
public String parsedigits() {
if (Error)
return "";
while (blank()) {
if (!advance())
return "";
}
final int n = N;
while (!Error && !blank()) {
if (N > L || C[N] < '0' || C[N] > '9')
break;
advance();
}
return new String(C, n, N - n);
}
/**
* Parse a word upto the character c or blank.
*/
public String parseword(final char c) {
if (Error)
return "";
while (blank()) {
if (!advance())
return "";
}
final int n = N;
while (!Error && !blank(c))
advance();
return new String(C, n, N - n);
}
/**
* @return next character is a digit?
*/
public boolean isint() {
if (Error)
return false;
return (C[N] >= '0' && C[N] <= '9');
}
/**
* Parse an int upto a blank. The int may be negative.
*
* @return the int
*/
public int parseint() {
int sig = 1;
try {
skipblanks();
if (Error)
return 0;
if (C[N] == '-') {
sig = -1;
N++;
if (N > L) {
Error = true;
return 0;
}
}
return sig * Integer.parseInt(parsedigits(), 10);
} catch (final NumberFormatException e) {
return 0;
}
}
/**
* Parse an int upto a blank or c. The int may be negative.
*
* @return the int
*/
public int parseint(final char c) {
int sig = 1;
try {
skipblanks();
if (Error)
return 0;
if (C[N] == '-') {
sig = -1;
N++;
if (N > L) {
Error = true;
return 0;
}
}
return sig * Integer.parseInt(parsedigits(c), 10);
} catch (final NumberFormatException e) {
return 0;
}
}
/**
* Skip all white characters.
*/
public void skipblanks() {
if (Error)
return;
while (blank())
if (!advance())
break;
}
/**
* Skip everything to the string s.
*
* @return String was found
*/
public boolean skip(final String s) {
if (Error)
return false;
final int l = s.length();
if (N + l > L)
return false;
if (!new String(C, N, l).equals(s))
return false;
N += l;
if (N >= L)
Error = true;
return true;
}
/**
* Get the next character.
*/
public char next() {
if (Error)
return ' ';
else {
N++;
if (N >= L) {
Error = true;
}
return C[N - 1];
}
}
/**
* Return a String, which is parsed from words with limited length.
*
* @param columns
* the maximal length of the string
*/
public String wrapline(final int columns) {
int n = N, good = N;
String s = "";
while (n < L) {
if (C[n] == '\n') {
if (n > N)
s = new String(C, N, n - N);
N = n + 1;
break;
}
if (C[n] == ' ' || C[n] == '\t' || C[n] == '\n') {
good = n;
}
n++;
if (n - N >= columns && good > N) {
s = new String(C, N, good - N);
N = good + 1;
break;
}
if (n >= L) {
if (n > N)
s = new String(C, N, n - N);
N = n;
break;
}
}
if (N >= L)
Error = true;
return s;
}
/**
* Parse the string into lines.
*
* @param columns
* the maximal length of each line
* @return a Vector with lines
*/
public Vector wraplines(final int columns) {
final Vector v = new Vector(10, 10);
String s;
while (!Error) {
s = wrapline(columns);
v.addElement(s);
}
return v;
}
public String wraplineword(final int columns) {
int n = N;
final int good = N;
String s = "";
while (n < L) {
if (C[n] == '\n') {
s = new String(C, N, n - N);
N = n + 1;
break;
}
n++;
if (n >= L) {
if (n > N)
s = new String(C, N, n - N);
N = n;
break;
}
if (n - N >= columns && good > N) {
s = new String(C, N, good - N);
N = good + 1;
if (N < L && C[N] != '\n')
s = s + "\\";
break;
}
}
if (N >= L)
Error = true;
return s;
}
public Vector wrapwords(final int columns) {
final Vector v = new Vector(10, 10);
String s;
while (!Error) {
s = wraplineword(columns);
v.addElement(s);
}
return v;
}
/**
* Replace c1 by c2
*/
public void replace(final char c1, final char c2) {
for (int i = 0; i < L; i++)
if (C[i] == c1)
C[i] = c2;
}
/**
* @return if an error has occured during the parsing.
*/
public boolean error() {
return Error;
}
}