import java.util.List; import java.util.ArrayList; class Parser { // 1. Let input be the string being parsed. public static List parse(String input) { // 2. Let position be a pointer into input, initially pointing at the start // of the string. int pos = 0; // 3. Let numbers be an initially empty list of integers. This list will be // the result of this algorithm. List numbers = new ArrayList(); while (pos < input.length()) { // 4. If there is a character in the string input at position position, // and it is either a U+0020 SPACE, U+002C COMMA, or U+003B SEMICOLON // character, then advance position to the next character in input, or to // beyond the end of the string if there are no more characters. if ((input.charAt(pos) == 0x0020) || (input.charAt(pos) == 0x002c) || (input.charAt(pos) == 0x003b)) { pos++; } // 5. If position points to beyond the end of input, return numbers and // abort. if (pos >= input.length()) { return numbers; } // 6. If the character in the string input at position position is a // U+0020 SPACE, U+002C COMMA, or U+003B SEMICOLON character, then return // to step 4. if ((input.charAt(pos) == 0x0020) || (input.charAt(pos) == 0x002c) || (input.charAt(pos) == 0x003b)) { continue; } // 7. Let negated be false. boolean negated = false; // 8. Let value be 0. int value = 0; // 9. Let started be false. This variable is set to true when the parser // sees a number or a U+002D HYPHEN-MINUS character (-). boolean started = false; // 10. Let got number be false. This variable is set to true when the // parser sees a number. boolean gotNumber = false; // 11. Let finished be false. This variable is set to true to switch // parser into a mode where it ignores characters until the next separator. boolean finished = false; // 12. Let bogus be false. boolean bogus = false; while (pos < input.length()) { // 13. Parser: If the character in the string input at position position // is: char c = input.charAt(pos); // 13a. A U+002D HYPHEN-MINUS character if (c == 0x002d) { // 13a1. If got number is true, let finished be true. if (gotNumber) { finished = true; } // 13a2. If finished is true, skip to the next step in the overall set // of steps. if (!finished) { if (started) { // 13a3. If started is true, let negated be false. negated = false; } else if (!bogus) { // 13a4. Otherwise, if started is false and if bogus is false, let // negated be true. negated = true; } // 13a5. Let started be true. started = true; } } // 13b. A character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT // NINE (9) else if ((c >= 0x0030) && (c <= 0x0039)) { // 13b1. If finished is true, skip to the next step in the overall set // of steps. if (!finished) { // 13b2. Multiply value by ten. value *= 10; // 13b3. Add the value of the digit, interpreted in base ten, to // value. value += c - 0x0030; // 13b4. Let started be true. started = true; // 13b5. Let got number be true. gotNumber = true; } } // 13c. A U+0020 SPACE character // 13d. A U+002C COMMA character // 13e. A U+003B SEMICOLON character else if ((c == 0x0020) || (c == 0x002c) || (c == 0x003b)) { // 13cde1. If got number is false, return the numbers list and abort. // This happens if an entry in the list has no digits, as in "1,2,x,4". if (!gotNumber) { return numbers; } // 13cde2. If negated is true, then negate value. if (negated) { value *= -1; } // 13cde3. Append value to the numbers list. numbers.add(value); // 13cde4. Jump to step 4 in the overall set of steps. break; } // 13f. A character in the range U+0001 to U+001F, U+0021 to U+002B, // U+002D to U+002F, U+003A, U+003C to U+0040, U+005B to U+0060, U+007b // to U+007F (i.e. any other non-alphabetic ASCII character) else if (((c >= 0x0001) && (c <= 0x001f)) || ((c >= 0x0021) && (c <= 0x002b)) || ((c >= 0x002d) && (c <= 0x002f)) || (c == 0x003a) || ((c >= 0x003c) && (c <= 0x0040)) || ((c >= 0x005b) && (c <= 0x0060)) || ((c >= 0x007b) && (c <= 0x007f))) { // 13f1. If got number is true, let finished be true. if (gotNumber) { finished = true; } // 13f2. If finished is true, skip to the next step in the overall set // of steps. if (!finished) { // 13f3. Let negated be false. negated = false; } } // 13g. Any other character // 13g1. If finished is true, skip to the next step in the overall set // of steps. else { if (!finished) { // 13g2. Let negated be false. negated = false; // 13g3. Let bogus be true. bogus = true; // 13g4. If started is true, then return the numbers list, and // abort. (The value in value is not appended to the list first; // it is dropped.) if (started) { return numbers; } } } // 14. Advance position to the next character in input, or to beyond the // end of the string if there are no more characters. pos++; // 15. If position points to a character (and not to beyond the end of // input), jump to the big Parser step above. if (pos < input.length()) { continue; } // 16. If negated is true, then negate value. if (negated) { value *= -1; } // 17. If got number is true, then append value to the numbers list. if (gotNumber) { numbers.add(value); } // 18. Return the numbers list and abort. return numbers; } // Step 13 Loop } // Step 4 Loop // should not happen return null; } public static void main(String[] args) { List ints = parse("a=65 b=73 c=45 d=67"); for (int i = 0; i < ints.size(); i++) { System.out.println(ints.get(i)); } } }