home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1.2 How-To
/
JavaHowTo.iso
/
javafile
/
ch06
/
Cell.java
< prev
next >
Wrap
Text File
|
1998-12-14
|
6KB
|
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;
}
}