string not able to be matched - java

im working on writing an infix to postfix translator/ calculator. I'm reading from an input file and attempting to match strings that are read. i know im passing into the method the correct string as seen by the print statements used for testing.. i just cant figure out why the conditions of the if statements are not met!
static int j = 1;
public static void readMath(String str, myStack s, myQueue q) {
System.out.println("\n~~~round "+j+"~~~ str=="+str);//<--this line confirms that the correct string is being passed in
//for example: if "1" is passed in, the first if statement's conditions are failing to be met
j++;
if (str == "0" || str == "1" || str == "2" || str == "3" || str == "4" || str == "5" || str == "6" || str == "7" || str == "8" || str == "9") {
System.out.println(">NUMBER"); // <--for testing.
q.enqueue(str);
} else if(str == "+" || str=="-") {
System.out.println("> + or -");
String x = (String)s.pop();
String y = x;
while( !s.isEmpty() && !(x == "<" || x == ">" || x == "&" || x == "|" || x =="=")) {
q.enqueue(x);
x = (String) s.pop();
}
if(x == "<" || x == ">" || x == "&" || x == "|" || x == "=") {
q.enqueue(x);
s.push(y);
}
} else if(str == "<" || str == ">") {
System.out.println(">GT or LT"); // <--for testing.
String x = (String) s.pop();
String y = x;
while( !s.isEmpty() && !(x == "&" || x == "|" || x == "=")) {
q.enqueue(x);
x = (String) s.pop();
}
if(x == "&" || x == "|" || x == "=") {
q.enqueue(x);
s.push(y);
}
} else if(str == "=") {
System.out.println("> ="); // <--for testing.
String x = (String) s.pop();
String y = x;
while( !s.isEmpty() && !(x == "&" || x == "|")) {
q.enqueue(x);
x = (String) s.pop();
}
if(x == "&" || x == "|") {
q.enqueue(x);
s.push(y);
}
} else if(str == "&" || str == "|") {
System.out.println("> & or |"); // <--for testing.
String x = (String) s.pop();
String y = x;
while( !s.isEmpty() && !(x == "!" || x == "&" || x == "|")) {
q.enqueue(x);
x = (String) s.pop();
}
} else if(str=="/" || str == "*") {
System.out.println(">divide or multiply"); // <--for testing.
String x = (String) s.pop();
String y = x;
while( !s.isEmpty() && !(x == "&" || x == "|" || x == "=" || x == "<" || x == ">" || x == "+" || x == "-")) {
q.enqueue(x);
x = (String) s.pop();
}
if(x == "&" || x == "|" || x == "=" || x == "<" || x == ">" || x == "+" || x == "-") {
q.enqueue(x);
s.push(y);
}
} else if(str == ")") {
System.out.println(">close paren"); // <--for testing.
String x = (String) s.pop();
while( !s.isEmpty() && x != "(" ) {
q.enqueue(x);
x = (String) s.pop();
}
}
s.printStack();
q.printQueue();
}
public static myStack s;
public static myQueue q;
public static void readMathFile() {
s = new myStack();
q = new myQueue();
File afile = new File ("/Users/tteumer2010/Documents/java/Project1/src/test.txt");
FileReader fileread = null;
try { fileread = new FileReader(afile); }
catch (FileNotFoundException e) { e.printStackTrace(); }
BufferedReader bufread = new BufferedReader(fileread);
String str = new String();
try {
while((str = bufread.readLine()) != null) {
String[] a = parse(str);
for(int i = 0; i < a.length; i++) {
System.out.println(a[i]);
readMath(a[i], s, q);
}
}
} catch (IOException e) { e.printStackTrace(); }
}
public static String[] parse(String s) {
String[] str = s.split(" ");
return str;
}

Another String equality question,here you go ...
(str == "0" and all the string equality compariosions in your code
should be
("0".equals(str)
use equals() method to check for string equality.== operator checks if two string references refer to the same string object.

Or rather use "0".equals(str) instead of str.equals("0"), because if str is null last one will fail (NullPointerException)
Cheers!

Related

String matching with a specific character

The exercise I am trying to do is to basically recognize X, if there are a set number of Xs in string A then string B should also have a set number of Xs in the same position as string a but the problem I am having is that it's not recognizing the Xs and therefore string a cannot equal to string b, I don't quite understand my mistake in my code either so I would like to know the problem in what I am doing.
public class Excersize4 {
public static boolean EqualX ( String strA, String strB ) {
if ( strA.isEmpty() && strB.isEmpty()) {
return true;
}
else if ( strA.isEmpty() && !strB.isEmpty()) {
if (strB.charAt(0) != 'X')
return EqualX(strA,strB.substring(1));
else
return false;
}
else if (strB.isEmpty() && !strA.isEmpty()) {
if (strA.charAt(0) != 'X')
return EqualX(strA.substring(1), strB);
else
return false;
}
else {
if (strA.charAt(0) == 'X' && strB.charAt(0) == 'X')
return EqualX(strA.substring(1),strB.substring(1));
else if (strA.charAt(0) == 'X' || strB.charAt(0) != 'X')
return false;
else if (strA.charAt(0) != 'X' || strB.charAt(0) != 'X')
return EqualX (strA.substring(1), strB.substring(1));
else
return true;
}
}
public static void main (String[] args) {
String strA = "XaXaXaX";
String strB = "XeXwXeX";
if ( EqualX( strA, strB ) )
System.out.println( "\"" + strA + "\" == \"" + strB + "\"");
else
System.out.println( "\"" + strA + "\" != \"" + strB + "\"");
}
}
If you run your code with a debugger, you will realize that the if conditions, in method EqualX, are wrong. They should be && instead of ||.
Here is the corrected code (which adheres to Java naming conventions):
public class Excersize4 {
public static boolean equalX(String strA, String strB) {
if (strA.isEmpty() && strB.isEmpty()) {
return true;
}
else if (strA.isEmpty() && !strB.isEmpty()) {
if (strB.charAt(0) != 'X')
return equalX(strA, strB.substring(1));
else
return false;
}
else if (strB.isEmpty() && !strA.isEmpty()) {
if (strA.charAt(0) != 'X')
return equalX(strA.substring(1), strB);
else
return false;
}
else {
if (strA.charAt(0) == 'X' && strB.charAt(0) == 'X')
return equalX(strA.substring(1), strB.substring(1));
else if (strA.charAt(0) == 'X' && strB.charAt(0) != 'X') // CHANGE HERE
return false;
else if (strA.charAt(0) != 'X' && strB.charAt(0) != 'X') // CHANGE HERE
return equalX(strA.substring(1), strB.substring(1));
else
return true;
}
}
public static void main(String[] args) {
String strA = "XaXaXaX";
String strB = "XeXwXeX";
if (equalX(strA, strB))
System.out.println("\"" + strA + "\" == \"" + strB + "\"");
else
System.out.println("\"" + strA + "\" != \"" + strB + "\"");
}
}
When I run the above code, the following is printed:
"XaXaXaX" == "XeXwXeX"

How to check for balanced brackets WITHOUT a stack/regex?

So basically before people start questioning why I'm not using a stack to save time over using counters and stuff.
This is a homework problem working with space complexity, so ignoring time complexity, we are attempting to reduce space complexity.
To do so, I have to use counters to keep track of the brackets.
Possible bracket types: '(' ')' '[' ']'
I've tried some coding but I seem to be having a problem with one of the test strings, and I just can't pinpoint where the problem is happening.
Boolean isWF(String w) {
// maxLevel is found and any variables I'm using has been initialized
for(int i = 0; i < maxLevel; i++) {
x = w.charAt(i);
currentLevel = i;
if(x == '(' || x == '[') {
holder = x; // Store bracket here to check match
savedLevel++;
counter++;
currentLevel++;
for(int j = i+1; j < w.length(); j++) {
x = w.charAt(j);
if(x == '(' || x == '[') {
currentLevel++;
if(currentLevel == savedLevel) {
holder = x;
counter++;
}
}
else if(x == ')' || x == ']') {
if(currentLevel == savedLevel) {
if((holder == '(' && x == ')') || (holder == '[' && x == ']')) {
currentLevel--;
counter--;
}
else
return false;
}
else {
currentLevel--;
}
}
}
}
else if(x == ')' || x == ']') {
counter--;
if(counter < 0) {
return false;
}
}
}
if(counter != 0) {
return false;
}
return true;
}
}
The strings I'm testing:
()[] - expected to be true, actual is true
([)] - expected to be false, actual is false
[([([()])])] - expected to be true, actual is true
([()([])()][()(())]()) - expected to be true, actual is false
([()([])())[()(())]()) - expected to be false, actual is false
Not a direct answer to where is the bug in your approach but the following approach seems to solve your input cases and is much simpler.
Basically you go over the string checking if the next symbol is one you can accept e.g. you can't accept a ) right after a [ and you keep a count of the open/close of brackets. If they ever go negative it means you are missing something.
public static boolean isBalanced(String s) {
int sOpen = 0;
int rOpen = 0;
for(int i = 0; i < s.length() - 1; ++i) {
final char current = s.charAt(i);
final char next = s.charAt(i + 1);
if(!isValidSymbol(current, next)) {
return false;
}
if(current == '(') rOpen++;
else if(current == '[') sOpen++;
else if(current == ')') rOpen--;
else if(current == ']') sOpen--;
if(rOpen < 0 || sOpen < 0) return false;
}
final char lastChar = s.charAt(s.length() - 1);
if(lastChar == '(') rOpen++;
else if(lastChar == '[') sOpen++;
else if(lastChar == ')') rOpen--;
else if(lastChar == ']') sOpen--;
return s.length() > 1 && rOpen == 0 && sOpen == 0;
}
private static boolean isValidSymbol(char from, char to) {
if(from == '(') {
return to == ')' || to == '[' || to == '(' ;
}
else if(from == '[') {
return to == ']' || to == '(' || to == '[';
}
return true;
}
public static void main(String[] args) {
String testInput = "()[]";
assert isBalanced(testInput) : "expected true";
testInput = "([)]";
assert isBalanced(testInput) == false : "expected false";
testInput = "[([([()])])]";
assert isBalanced(testInput) : "expected true";
testInput = "([()([])()][()(())]())";
assert isBalanced(testInput) : "expected true";
testInput = "([()([])())[()(())]()) ";
assert isBalanced(testInput) == false : "expected false";
}

Use existing Method instead of new Parameter

I'm trying to finish this project and I can't figure how to use my existing method in my other method. I want to get rid of VOWELS, which is defined as a field the class, and I just want to use the method isVowel which returns a boolean after you type in a Char.
This is what I have:
public class StringAndIO {
private static Scanner v;
static final String VOWELS = "AaEeIiOoUuÄäÖöÜü";
public static boolean isVowel(char c) {
if (c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 'u'
|| c == 'U' || c == 'ä' || c == 'Ä' || c == 'ö' || c == 'Ö' || c == 'ü' || c == 'Ü') {
return true;
} else {
return false;
}
}
public static String toPigLatin(String text) {
String ret = "";
String vowelbuf = "";
for (int i = 0; i < text.length(); ++i) {
char x = text.charAt(i);
if (VOWELS.indexOf(x) != -1) {
vowelbuf += x;
} else {
if (vowelbuf.length() > 0) {
ret += vowelbuf + "b" + vowelbuf + x;
vowelbuf = "";
} else {
ret += x;
}
}
}
if (vowelbuf.length() > 0) {
ret += vowelbuf + "b" + vowelbuf;
}
return ret;
}
/**
* only there for testing purpose
*/
public static void main(String[] args) {
v = new Scanner(System.in);
System.out.println("Enter a Char!");
char c = v.next().charAt(0);
System.out.println(isVowel(c));
String s = "Meine Mutter ißt gerne Fisch";
System.out.println(s);
System.out.println(toPigLatin(s));
System.out.println();
}
}
THis is how to use your isVowel(x) method inside the other method
public static String toPigLatin(String text) {
String ret = "";
String vowelbuf = "";
for (int i = 0; i < text.length(); ++i) {
char x = text.charAt(i);
if (isVowel(x)) {
vowelbuf += x;
} else {
if (vowelbuf.length() > 0) {
ret += vowelbuf + "b" + vowelbuf + x;
vowelbuf = "";
} else {
ret += x;
}
}
}
if (vowelbuf.length() > 0) {
ret += vowelbuf + "b" + vowelbuf;
}
return ret;
}

Final return statement, ignore

Im working on a token iterator (valid tokens, "true, false, "true", "&", "!", "(", "false", "^", "true", ")".
The code is working, my question is about return values. I often run into this problem, I have return statements, but the final return statement throws off my result by duplicating the last return statement.
I think I know for sure the error lays within my placement of { and } and while i've learned they aren't necessary, since there's so many nested if's i feel they are necessary.
This seems to be a common problem to me and others ive worked with, does anyone have an idea of how to prevent this problem from happening? Thanks!
My code outputs:
line: [ ! BAD (true ^ false) % truelybad]
next token: [!]
next token: [(]
next token: [true]
next token: [^]
next token: [false]
next token: [)]
next token: [)]
and should output
next token: [!]
next token: [(]
next token: [true]
next token: [^]
next token: [false]
next token: [)]
public class TokenIter implements Iterator<String> {
ArrayList<String> token = new ArrayList<String>();
static int count = 0;
// input line to be tokenized
private String line;
// the next Token, null if no next Token
private String nextToken;
// implement
public TokenIter(String line) {
this.line = line;
}
#Override
// implement
public boolean hasNext() {
// System.out.println(count);
return count < line.length();
}
#Override
// implement
public String next() {
while (hasNext()) {
char c = line.charAt(count);
if (c == '!' || c == '!' || c == '^' || c == '(' || c == ')') {
token.add(Character.toString(c));
count++;
nextToken = Character.toString(c);
return nextToken;
} else if (c == 't' || c == 'T') {
count++;
c = line.charAt(count);
if (c == 'r') {
count++;
c = line.charAt(count);
}
if (c == 'u') {
count++;
c = line.charAt(count);
}
if (c == 'e') {
count++;
c = line.charAt(count);
}if (c == ' ' || c == '!' || c == '!' || c == '^' || c == '(' || c == ')'){
token.add("true");
nextToken = "true";
//count++;
return nextToken;
}
} else if (c == 'f' || c == 'F') {
count++;
c = line.charAt(count);
if (c == 'a') {
count++;
c = line.charAt(count);
}
if (c == 'l') {
count++;
c = line.charAt(count);
}
if (c == 's') {
count++;
c = line.charAt(count);
}
if (c == 'e') {
count++;
c = line.charAt(count);
}
if (c == ' ' || c == '!' || c == '!' || c == '^' || c == '(' || c == ')'){
token.add("false");
nextToken = "false";
// count++;
return nextToken;
}
} else if (c == ' ') {
count++;
} else {
count++;
}
}
return nextToken;
}
#Override
// provided, do not change
public void remove() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
// provided
public static void main(String[] args) {
String line;
// you can play with other inputs on the command line
if (args.length > 0)
line = args[0];
// or do the standard test
else
line = " ! BAD (true ^ false) % truelybad";
System.out.println("line: [" + line + "]");
TokenIter tokIt = new TokenIter(line);
while (tokIt.hasNext())
System.out.println("next token: [" + tokIt.next() + "]");
}
}
Problem with your code comes only when last digit is not a token.
Reason - You are checking hasNext() which is true it goes inside your code.You are not setting nextToken for this case so it uses your lask token and display it.
I updated your code to always return a value and check if value return is from token list then display otherwise ignore it.
public class test implements Iterator<String> {
static List<String> tokenList = Arrays.asList( "true", "&", "!", "(", "false", "^", "true", ")");
ArrayList<String> token = new ArrayList<String>();
static int count = 0;
// input line to be tokenized
private String line;
// the next Token, null if no next Token
private String nextToken;
// implement
public test(String line) {
this.line = line;
}
#Override
// implement
public boolean hasNext() {
// System.out.println(count);
return count < line.length();
}
#Override
// implement
public String next() {
while (hasNext()) {
char c = line.charAt(count);
if (c == '!' || c == '!' || c == '^' || c == '(' || c == ')') {
token.add(Character.toString(c));
count++;
nextToken = Character.toString(c);
return nextToken;
} else if (c == 't' || c == 'T') {
count++;
c = line.charAt(count);
if (c == 'r') {
count++;
c = line.charAt(count);
}
if (c == 'u') {
count++;
c = line.charAt(count);
}
if (c == 'e') {
count++;
c = line.charAt(count);
}if (c == ' ' || c == '!' || c == '!' || c == '^' || c == '(' || c == ')'){
token.add("true");
nextToken = "true";
//count++;
return nextToken;
}
} else if (c == 'f' || c == 'F') {
count++;
c = line.charAt(count);
if (c == 'a') {
count++;
c = line.charAt(count);
}
if (c == 'l') {
count++;
c = line.charAt(count);
}
if (c == 's') {
count++;
c = line.charAt(count);
}
if (c == 'e') {
count++;
c = line.charAt(count);
}
if (c == ' ' || c == '!' || c == '!' || c == '^' || c == '(' || c == ')'){
token.add("false");
nextToken = "false";
// count++;
return nextToken;
}
} else if (c == ' ') {
count++;
nextToken = null;
} else {
count++;
nextToken = null;
}
}
return nextToken;
}
#Override
// provided, do not change
public void remove() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
// provided
public static void main(String[] args) {
String line;
// you can play with other inputs on the command line
if (args.length > 0)
line = args[0];
// or do the standard test
else
line = " ! BAD (true ^ false) % truelybad ";
System.out.println("line: [" + line + "]");
test tokIt = new test(line);
while (tokIt.hasNext()) {
String s = tokIt.next();
if (s != null && tokenList.contains(s))
System.out.println("next token: [" + s + "]");
}
}
}
The underlying problem here is that your hasNext() method returns true not if there is another token in the String, but if it hasn't finished parsing the String yet.
So what happens is if you put in the String " ! ! true lotsofcrap ", then calling next() will return "!", then "!", then "true", then after that has been returned, there are no more tokens in the String, yet hasNext() still returns true.
What you might consider doing is having hasNext() parse through the string, but instead of returning the next String, return true only if it finds another token ahead of the current position. Keep in mind that in hasNext(), you do not want to directly increment count. Instead, make a local variable int something = count; at the beginning of hasNext() and use that. If you fix that, then the rest of your code SHOULD work just fine.

Custom Tokenizer, Iterator with quotes

Maybe some one can help?
How to modify this method next() that the next token can be: 'abc' text with the quotes.
Now if the text contains quote are throwed ExpressionException Unknown operator ''' at position...
#Override
public String next() {
StringBuilder token = new StringBuilder();
if (pos >= input.length()) {
return previousToken = null;
}
char ch = input.charAt(pos);
while (Character.isWhitespace(ch) && pos < input.length()) {
ch = input.charAt(++pos);
}
if (Character.isDigit(ch)) {
while ((Character.isDigit(ch) || ch == decimalSeparator)
&& (pos < input.length())) {
token.append(input.charAt(pos++));
ch = pos == input.length() ? 0 : input.charAt(pos);
}
} else if (ch == minusSign
&& Character.isDigit(peekNextChar())
&& ("(".equals(previousToken) || ",".equals(previousToken)
|| previousToken == null || operators
.containsKey(previousToken))) {
token.append(minusSign);
pos++;
token.append(next());
} else if (Character.isLetter(ch)) {
while ((Character.isLetter(ch) || Character.isDigit(ch) || (ch == '_')) && (pos < input.length())) {
token.append(input.charAt(pos++));
ch = pos == input.length() ? 0 : input.charAt(pos);
}
} else if (ch == '(' || ch == ')' || ch == ',') {
token.append(ch);
pos++;
//FIXME
else if (ch == '\''){
pos++;
String temp = "\'"+next()+"\'";
token.append(temp);
pos++;
}
//
} else {
while (!Character.isLetter(ch) && !Character.isDigit(ch)
&& !Character.isWhitespace(ch) && ch != '('
&& ch != ')' && ch != ',' && (pos < input.length())) {
token.append(input.charAt(pos));
pos++;
ch = pos == input.length() ? 0 : input.charAt(pos);
if (ch == minusSign) {
break;
}
}
if (!operators.containsKey(token.toString())) {
throw new ExpressionException("Unknown operator '" + token
+ "' at position " + (pos - token.length() + 1));
}
}
return previousToken = token.toString();
}
eval
public Object eval() {
Stack<Object> stack = new Stack<Object>();
for (String token : getRPN()) {
mylog.pl("Reverse polish notation TOKEN : " + token + " RPN size: " + getRPN().size() );
if (operators.containsKey(token)) {
Object v1 = stack.pop();
Object v2 = stack.pop();
stack.push(operators.get(token).eval(v2, v1));
} else if (variables.containsKey(token)) {
stack.push(variables.get(token).round(mc));
} else if (functions.containsKey(token.toUpperCase())) {
Function f = functions.get(token.toUpperCase());
ArrayList<Object> p = new ArrayList<Object>(f.getNumParams());
for (int i = 0; i < f.numParams; i++) {
p.add(0, stack.pop());
}
Object fResult = f.eval(p);
stack.push(fResult);
} else if (isDate(token)) {
Long date = null;
try {
date = SU.sdf.parse(token).getTime();
} catch (ParseException e) {/* IGNORE! */
}
stack.push(new BigDecimal(date, mc));
} else {
if (BusinessStrategy.PREFIX_X.equals(Character.toString(token.charAt(0)))) {
stack.push(token);
} else {
stack.push(new BigDecimal(token, mc));
}
}
}
return stack.pop();
}
Reverse notation
private List<String> getRPN() {
if (rpn == null) {
rpn = shuntingYard(this.expression);
}
return rpn;
}
Yard
private List<String> shuntingYard(String expression) {
List<String> outputQueue = new ArrayList<String>();
Stack<String> stack = new Stack<String>();
Tokenizer tokenizer = new Tokenizer(expression);
String lastFunction = null;
while (tokenizer.hasNext()) {
String token = tokenizer.next();
if (isNumber(token)) {
outputQueue.add(token);
} else if (variables.containsKey(token)) {
outputQueue.add(token);
} else if (functions.containsKey(token.toUpperCase())) {
stack.push(token);
lastFunction = token;
} else if (Character.isLetter(token.charAt(0))) {
if ("\'".equals(Character.toString(token.charAt(0)))){
outputQueue.add(token);
} else {
stack.push(token);
}
} else if (",".equals(token)) {
while (!stack.isEmpty() && !"(".equals(stack.peek())) {
outputQueue.add(stack.pop());
}
if (stack.isEmpty()) {
throw new ExpressionException("Parse error for function '"
+ lastFunction + "'");
}
} else if (operators.containsKey(token)) {
Operator o1 = operators.get(token);
String token2 = stack.isEmpty() ? null : stack.peek();
while (operators.containsKey(token2)
&& ((o1.isLeftAssoc() && o1.getPrecedence() <= operators
.get(token2).getPrecedence()) || (o1
.getPrecedence() < operators.get(token2)
.getPrecedence()))) {
outputQueue.add(stack.pop());
token2 = stack.isEmpty() ? null : stack.peek();
}
stack.push(token);
} else if ("(".equals(token)) {
stack.push(token);
} else if (")".equals(token)) {
while (!stack.isEmpty() && !"(".equals(stack.peek())) {
outputQueue.add(stack.pop());
}
if (stack.isEmpty()) {
throw new RuntimeException("Mismatched parentheses");
}
stack.pop();
if (!stack.isEmpty()
&& functions.containsKey(stack.peek().toUpperCase())) {
outputQueue.add(stack.pop());
}
}
}
while (!stack.isEmpty()) {
String element = stack.pop();
if ("(".equals(element) || ")".equals(element)) {
throw new RuntimeException("Mismatched parentheses");
}
if (!operators.containsKey(element)) {
throw new RuntimeException("Unknown operator or function: "
+ element);
}
outputQueue.add(element);
}
return outputQueue;
}
Error
*java.util.EmptyStackException
at java.util.Stack.peek(Unknown Source)
at java.util.Stack.pop(Unknown Source)
at com.business.Expression.eval(Expression.java:1033)*
It is in eval method Object v1 = stack.pop(); line.
Thanks !
In method next you have recursive calls in two places:
after seeing a minus sign
after recognizing an apostrope
The first situation will construct tokens where a minus is followed by a digit (i.e., an unsigend number follows) - OK. (Although, not having a sign but an unary minus operator deserves some consideration.)
The second scenario means trouble. After advancing past the initial apostrophe, another next-result is expected, as if string literals would only contain one number or one identifier or a single operator. Anyway, the next() executes, let's say it returns a number: then an apostroph is added to the token, but there's no effort to check whether there is a closing apostrophe nor to skip that.
else if (ch == '\''){
token.append( '\'' );
pos++;
while( pos < input.length() &&
(ch = input.charAt(pos++)) != '\'' ){
token.append( ch );
}
token.append( '\'' );
This doesn't permit an apostrophe to be a character within the string and it does not diagnose an unterminated string. But this can be added rather easily.

Categories