373 lines
6.5 KiB
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;
|
|
}
|
|
}
|