home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-12-14 | 6.3 KB | 363 lines |
- import java.awt.*;
-
- /*
- * Defines an individual cell
- */
- public class Cell {
-
- /*
- * Token types returned by Lex()
- */
- static final int NUMBER = 1;
- static final int EQUALS = 2;
- static final int PLUS = 3;
- static final int MINUS = 4;
- static final int STAR = 5;
- static final int SLASH = 6;
- static final int TEXT = 7;
- static final int EOT = 8;
- static final int LEFT = 9;
- static final int RIGHT = 10;
- static final int UNKN = 11;
- static final int FORMULA = 12;
- static final int REFERENCE = 13;
-
- /*
- * What is in this cell
- */
- int type;
-
- /*
- * The numeric value, if this cell is numeric
- */
- double value;
-
- /*
- * Numeric value for this token
- */
- double lexValue;
-
- /*
- * Index into input string (used for parsing)
- */
- int lexIndex;
-
- /*
- * Token value returned from Lex()
- */
- int token;
-
- /*
- * The text contents of this cell
- */
- String text;
- int textLength;
- int textIndex;
-
- /*
- * Reference to all cells in spreadsheet
- */
- Cell cells[][];
-
- /*
- * Error flag, set if parse error detected
- */
- boolean error;
-
- /*
- * Used to force rereading of tokens
- */
- boolean lexFlag;
-
- /*
- * Number of rows and columns in the spreadsheet
- * Used for bounds checking
- */
- int cols;
- int rows;
-
- public Cell (Cell cs[][], int r, int c) {
-
- cells = cs;
- rows = r;
- cols = c;
- text = "";
- lexFlag = true;
- type = UNKN;
- }
-
- /*
- * Called to get the numeric value of this cell
- */
- double evaluate () {
-
- resetLex ();
- error = false;
- switch (type) {
- case FORMULA:
- Lex ();
- value = Level1 ();
- if (error) return 0;
- return value;
-
- case NUMBER:
- value = lexValue;
- return value;
-
- case UNKN:
- return 0;
- }
- error = true;
- return 0;
- }
-
- /*
- * Returns the string representation of the value
- */
- String evalToString () {
-
- String s;
-
- if (type == TEXT || type == UNKN) return text;
- s = String.valueOf (value);
- if (error) return "Error";
- else return s;
- }
-
- /*
- * Called to enter a string into this cell
- */
- void enter (String s) {
-
- text = s;
- textLength = text.length ();
- resetLex ();
- error = false;
- switch (Lex ()) {
- case EQUALS:
- type = FORMULA;
- break;
-
- case NUMBER:
- type = NUMBER;
- value = lexValue;
- break;
-
- default:
- type = TEXT;
- break;
- }
- }
-
- /*
- * Top level of the recursive descent parser
- * Handle plus and minus.
- */
- double Level1 () {
-
- boolean ok;
- double x1, x2;
-
- x1 = Level2 ();
- if (error) return 0;
-
- ok = true;
- while (ok) switch (Lex ()) {
- case PLUS:
- x2 = Level2 ();
- if (error) return 0;
- x1 += x2;
- break;
-
- case MINUS:
- x2 = Level2 ();
- if (error) return 0;
- x1 -= x2;
- break;
-
- default:
- Unlex ();
- ok = false;
- break;
- }
- return x1;
- }
-
- /*
- * Handle multiply and divide.
- */
- double Level2 () {
-
- boolean ok;
- double x1, x2;
-
- x1 = Level3 ();
- if (error) return 0;
-
- ok = true;
- while (ok) switch (Lex ()) {
- case STAR:
- x2 = Level3 ();
- if (error) return 0;
- x1 *= x2;
- break;
-
- case SLASH:
- x2 = Level3 ();
- if (error) return 0;
- x1 /= x2;
- break;
-
- default:
- Unlex ();
- ok = false;
- break;
- }
- return x1;
- }
-
- /*
- Handle unary minus, parentheses, constants, and cell references
- */
- double Level3 () {
-
- double x1, x2;
-
- switch (Lex ()) {
- case MINUS:
- x2 = Level1 ();
- if (error) return 0;
- return -x2;
-
- case LEFT:
- x2 = Level1 ();
- if (error) return 0;
- if (Lex () != RIGHT) {
- error = true;
- return 0;
- }
- return x2;
-
- case NUMBER:
- case REFERENCE:
- return lexValue;
- }
- error = true;
- return 0;
- }
-
- /*
- * Reset the lexical analyzer.
- */
- void resetLex () {
-
- lexIndex = 0;
- lexFlag = true;
- }
-
- /*
- * Push a token back for rereading.
- */
- void Unlex () {
-
- lexFlag = false;
- }
-
- /*
- * Returns the next token
- */
- int Lex () {
-
- if (lexFlag) {
- token = lowlevelLex ();
- }
- lexFlag = true;
- return token;
- }
-
- /*
- * Returns the next token in the text string
- */
- int lowlevelLex () {
-
- char c;
- String s;
-
- do {
- if (lexIndex >= textLength) return EOT;
- c = text.charAt (lexIndex++);
- } while (c == ' ');
- switch (c) {
- case '=':
- return EQUALS;
-
- case '+':
- return PLUS;
-
- case '-':
- return MINUS;
-
- case '*':
- return STAR;
-
- case '/':
- return SLASH;
-
- case '(':
- return LEFT;
-
- case ')':
- return RIGHT;
- }
-
- if (c >= '0' && c <= '9') {
- s = "";
- while ((c >= '0' && c <= '9') || c == '.' ||
- c == '-' || c == 'e' || c == 'E') {
- s += c;
- if (lexIndex >= textLength) break;
- c = text.charAt (lexIndex++);
- }
- lexIndex -= 1;
- try {
- lexValue = Double.valueOf (s).doubleValue();
- } catch (NumberFormatException e) {
- System.out.println (e);
- error = true;
- return UNKN;
- }
- return NUMBER;
- }
- if (c >= 'a' && c <= 'z') {
- int col = c - 'a';
- int row;
- s = "";
- if (lexIndex >= textLength) {
- error = true;
- return UNKN;
- }
- c = text.charAt (lexIndex++);
- while (c >= '0' && c <= '9') {
- s += c;
- if (lexIndex >= textLength) break;
- c = text.charAt (lexIndex++);
- }
- lexIndex -= 1;
- try {
- row = Integer.valueOf (s).intValue() - 1;
- } catch (NumberFormatException e) {
- error = true;
- return UNKN;
- }
- if (row >= rows || col >= cols) {
- error = true;
- return REFERENCE;
- }
- lexValue = cells[row][col].evaluate();
- if (cells[row][col].error) error = true;
- return REFERENCE;
- }
- return TEXT;
- }
- }
-