2016-03-07 04:37:01 +00:00
|
|
|
package com.bytezone.diskbrowser.visicalc;
|
|
|
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
public class Expression
|
|
|
|
{
|
|
|
|
// Expressions:
|
|
|
|
// - number
|
|
|
|
// - cell address
|
|
|
|
// - function
|
|
|
|
// - expression [+-*/^] expression
|
|
|
|
// - [+-=] expression
|
|
|
|
// - ( expression )
|
|
|
|
|
|
|
|
private static final Pattern pattern = Pattern.compile ("");
|
|
|
|
|
|
|
|
private boolean isUnavailable;
|
|
|
|
private boolean isError;
|
|
|
|
|
|
|
|
private boolean hasValue;
|
|
|
|
private double value;
|
|
|
|
private Function function;
|
|
|
|
private Address address;
|
|
|
|
|
|
|
|
private Expression expression1;
|
|
|
|
private char operator;
|
|
|
|
private Expression expression2;
|
|
|
|
|
|
|
|
private final Sheet parent;
|
|
|
|
|
|
|
|
public Expression (Sheet parent, String input)
|
|
|
|
{
|
|
|
|
this.parent = parent;
|
|
|
|
String text = input.trim ();
|
|
|
|
|
2016-03-07 12:16:11 +00:00
|
|
|
System.out.printf ("New expression:[%s]%n", input);
|
2016-03-07 04:37:01 +00:00
|
|
|
char firstChar = text.charAt (0);
|
|
|
|
if (firstChar == '-')
|
|
|
|
{
|
2016-03-07 12:16:11 +00:00
|
|
|
char secondChar = text.charAt (1);
|
|
|
|
if ((secondChar >= '0' && secondChar <= '9') || secondChar == '.')
|
|
|
|
{
|
|
|
|
String text2 = text.substring (1);
|
|
|
|
String numberText = getNumberText (text2);
|
|
|
|
char op = getOperator (numberText, text2);
|
|
|
|
if (op == ' ')
|
|
|
|
{
|
|
|
|
value = Double.parseDouble (numberText) * -1;
|
|
|
|
hasValue = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
expression1 = new Expression (parent, "-" + numberText);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
operator = '-';
|
|
|
|
expression1 = new Expression (parent, text.substring (1));
|
|
|
|
}
|
2016-03-07 04:37:01 +00:00
|
|
|
}
|
|
|
|
else if (firstChar == '=' || firstChar == '+')
|
|
|
|
{
|
|
|
|
expression1 = new Expression (parent, text.substring (1));
|
|
|
|
}
|
|
|
|
else if (firstChar == '@')
|
|
|
|
{
|
|
|
|
String functionText = getFunctionText (text);
|
|
|
|
char op = getOperator (functionText, text);
|
|
|
|
if (op == ' ')
|
|
|
|
function = Function.getInstance (parent, functionText);
|
|
|
|
}
|
|
|
|
else if (firstChar == '(')
|
|
|
|
{
|
|
|
|
String bracketText = getFunctionText (text);
|
|
|
|
char op = getOperator (bracketText, text);
|
|
|
|
if (op == ' ')
|
|
|
|
expression1 =
|
|
|
|
new Expression (parent, bracketText.substring (1, bracketText.length () - 2));
|
|
|
|
}
|
|
|
|
else if ((firstChar >= '0' && firstChar <= '9') || firstChar == '.')
|
|
|
|
{
|
|
|
|
String numberText = getNumberText (text);
|
|
|
|
char op = getOperator (numberText, text);
|
|
|
|
if (op == ' ')
|
|
|
|
{
|
|
|
|
value = Double.parseDouble (numberText);
|
|
|
|
hasValue = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (firstChar >= 'A' && firstChar <= 'Z')
|
|
|
|
{
|
|
|
|
String addressText = getAddressText (text);
|
|
|
|
char op = getOperator (addressText, text);
|
|
|
|
if (op == ' ')
|
|
|
|
address = new Address (addressText);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
System.out.printf ("Error processing [%s]%n", text);
|
|
|
|
}
|
|
|
|
|
2016-03-07 12:16:11 +00:00
|
|
|
private char getOperator (String text1, String text2)
|
2016-03-07 04:37:01 +00:00
|
|
|
{
|
2016-03-07 12:16:11 +00:00
|
|
|
if (text1.length () == text2.length ())
|
|
|
|
return ' ';
|
|
|
|
|
|
|
|
char op = text2.charAt (text1.length ());
|
|
|
|
if (op == '+' || op == '-' || op == '*' || op == '/' || op == '^')
|
|
|
|
{
|
|
|
|
expression1 = new Expression (parent, text1);
|
|
|
|
operator = op;
|
|
|
|
expression2 = new Expression (parent, text2.substring (text1.length () + 1));
|
|
|
|
return op;
|
|
|
|
}
|
|
|
|
|
|
|
|
System.out.println ("error");
|
|
|
|
// error
|
|
|
|
return '!';
|
2016-03-07 04:37:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double getValue ()
|
|
|
|
{
|
|
|
|
if (hasValue)
|
|
|
|
return value;
|
|
|
|
|
|
|
|
if (function != null)
|
|
|
|
return function.getValue ();
|
|
|
|
|
|
|
|
if (address != null)
|
2016-03-07 12:16:11 +00:00
|
|
|
{
|
|
|
|
Cell cell = parent.getCell (address);
|
|
|
|
if (cell != null)
|
|
|
|
return parent.getCell (address).getValue ();
|
|
|
|
System.out.println ("Error with address");
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-07 04:37:01 +00:00
|
|
|
|
|
|
|
if (expression2 == null)
|
|
|
|
{
|
|
|
|
if (operator == '-')
|
|
|
|
return expression1.getValue () * -1;
|
|
|
|
return expression1.getValue ();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (operator)
|
|
|
|
{
|
|
|
|
case ' ':
|
|
|
|
return expression1.getValue ();
|
|
|
|
case '+':
|
|
|
|
return expression1.getValue () + expression2.getValue ();
|
|
|
|
case '-':
|
|
|
|
return expression1.getValue () - expression2.getValue ();
|
|
|
|
case '*':
|
|
|
|
return expression1.getValue () * expression2.getValue ();
|
|
|
|
case '/':
|
|
|
|
return expression1.getValue () / expression2.getValue ();
|
|
|
|
case '^':
|
|
|
|
return Math.pow (expression1.getValue (), expression2.getValue ());
|
|
|
|
}
|
|
|
|
|
|
|
|
System.out.println ("Unresolved value");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getFunctionText (String text)
|
|
|
|
{
|
|
|
|
int ptr = text.indexOf ('('); // find first left parenthesis
|
|
|
|
int depth = 1;
|
|
|
|
while (++ptr < text.length ()) // find matching right parenthesis
|
|
|
|
{
|
|
|
|
if (text.charAt (ptr) == ')')
|
|
|
|
{
|
|
|
|
--depth;
|
|
|
|
if (depth == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (text.charAt (ptr) == '(')
|
|
|
|
++depth;
|
|
|
|
}
|
|
|
|
return text.substring (0, ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getNumberText (String text)
|
|
|
|
{
|
|
|
|
int ptr = 0;
|
|
|
|
while (++ptr < text.length ())
|
|
|
|
{
|
|
|
|
char c = text.charAt (ptr);
|
|
|
|
if (c != '.' && (c < '0' || c > '9'))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return text.substring (0, ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getAddressText (String text)
|
|
|
|
{
|
|
|
|
int ptr = 0;
|
|
|
|
while (++ptr < text.length ())
|
|
|
|
{
|
|
|
|
char c = text.charAt (ptr);
|
|
|
|
if ((c < '0' || c > '9') && (c < 'A' || c > 'Z'))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return text.substring (0, ptr);
|
|
|
|
}
|
|
|
|
|
2016-03-07 12:16:11 +00:00
|
|
|
@Override
|
|
|
|
public String toString ()
|
2016-03-07 04:37:01 +00:00
|
|
|
{
|
2016-03-07 12:16:11 +00:00
|
|
|
StringBuilder text = new StringBuilder ();
|
2016-03-07 04:37:01 +00:00
|
|
|
|
2016-03-07 12:16:11 +00:00
|
|
|
text.append (String.format ("Has value ......... %s%n", hasValue));
|
|
|
|
text.append (String.format ("Value ............. %f%n", value));
|
|
|
|
text.append (String.format ("Function .......... %s%n", function));
|
|
|
|
text.append (String.format ("Address ........... %s%n", address));
|
|
|
|
text.append (String.format ("Operator .......... %s%n", operator));
|
|
|
|
text.append (String.format ("Expression1 ....... %s%n", expression1));
|
|
|
|
text.append (String.format ("Expression2 ....... %s%n", expression2));
|
2016-03-07 04:37:01 +00:00
|
|
|
|
2016-03-07 12:16:11 +00:00
|
|
|
return text.toString ();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void main (String[] args)
|
|
|
|
{
|
|
|
|
Expression ex = new Expression (null, "-5+12-6");
|
|
|
|
System.out.println (ex.getValue ());
|
2016-03-07 04:37:01 +00:00
|
|
|
}
|
|
|
|
}
|