📄 solver.java
字号:
package xcalc;
import java.util.Enumeration;
import java.util.Stack;
import xcalc.Real;
public final class Solver
{
public static final String[] C_COMMANDS =
{
"0","1","2","3","4","5","6","7","8","9",
".","+","-","*","/","%","^","(",")","PI",
"e","x","y","ANS","sqrt(","log10(","log2(","ln(","sin(","cos(","tan(",
"asin(","acos(","atan(","sinh(","cosh(","tanh(","asinh","acosh(","atanh(","fac(",
";","P(","C(","abs("
};
public static final int K_0 = 0;
public static final int K_1 = 1;
public static final int K_2 = 2;
public static final int K_3 = 3;
public static final int K_4 = 4;
public static final int K_5 = 5;
public static final int K_6 = 6;
public static final int K_7 = 7;
public static final int K_8 = 8;
public static final int K_9 = 9;
public static final int K_POINT = 10;
public static final int K_ADD = 11;
public static final int K_SUB = 12;
public static final int K_MUL = 13;
public static final int K_DIV = 14;
public static final int K_MOD = 15;
public static final int K_POWER = 16;
public static final int K_BREAKET_OPEN = 17;
public static final int K_BREAKET_CLOSE = 18;
public static final int K_PI = 19;
public static final int K_E = 20;
public static final int K_X = 21;
public static final int K_Y = 22;
public static final int K_ANS = 23;
public static final int K_SQRT = 24;
public static final int K_LOG10 = 25;
public static final int K_LOG2 = 26;
public static final int K_LN = 27;
public static final int K_SIN = 28;
public static final int K_COS = 29;
public static final int K_TAN = 30;
public static final int K_ASIN = 31;
public static final int K_ACOS = 32;
public static final int K_ATAN = 33;
public static final int K_SINH = 34;
public static final int K_COSH = 35;
public static final int K_TANH = 36;
public static final int K_ASINH = 37;
public static final int K_ACOSH = 38;
public static final int K_ATANH = 39;
public static final int K_FAC = 40;
public static final int K_SEMI = 41;
public static final int K_PER = 42;
public static final int K_COM = 43;
public static final int K_ABS = 44;
public static final int K_EOF = 100;
private static Enumeration e;
private static String lookaheadValue;
private static int lookaheadKind;
private static Symbol eq;
private static Stack tempStack = new Stack();;
private static void acceptIt() throws Exception{
//system.out.println("acceptIt");
if(!e.hasMoreElements()) {
lookaheadValue ="";
lookaheadKind = K_EOF;
return;
}
lookaheadValue = (String)e.nextElement();
lookaheadKind = tokenType(lookaheadValue);
}
public static int tokenType(String token) throws Exception{
for(int i = 0; i<C_COMMANDS.length;++i){
if(token==C_COMMANDS[i])
return i;
}
throw new Exception("Unknown command");
}
public static Real solve(Real x, Real y)
{
Num.setXVar(x);
Num.setYVar(y);
return solve();
}
public static Real solve(Real x)
{
Num.setXVar(x);
return solve();
}
public static Real solve()
{
//long s = System.currentTimeMillis();
Real result = eq.eval();
//System.out.println(System.currentTimeMillis()-s);
return result;
}
public static void initialize(Enumeration e) throws Exception
{
Solver.e = e;
Solver.tempStack.removeAllElements();
acceptIt();
parse1();
Solver.eq = (Symbol)tempStack.pop();
}
// <1> ::= <2> <1_>
private static void parse1() throws Exception{
//system.out.println("parse1");
parse2();
parse1_();
}
// <1_> ::= K_ADD <1>
// <1_> ::= K_SUB <2> <1_>
// <1_> ::= e
private static void parse1_() throws Exception{
//system.out.println("parse1_");
Symbol links, rechts;
switch(lookaheadKind) {
case K_ADD:
acceptIt();
parse1();
rechts = (Symbol)tempStack.pop();
links = (Symbol)tempStack.pop();
tempStack.push(new Exp2(K_ADD,links,rechts));
break;
case K_SUB:
acceptIt();
parse2();
//sub
rechts = (Symbol)tempStack.pop();
links = (Symbol)tempStack.pop();
tempStack.push(new Exp2(K_SUB,links,rechts));
parse1_();
break;
}
}
// <2> ::= <3> <2_>
private static void parse2() throws Exception{
//system.out.println("parse2");
parse3();
parse2_();
}
// <2_> ::= K_MUL <2>
// <2_> ::= K_DIV <3> <2_>
// <2_> ::= e
private static void parse2_() throws Exception{
//system.out.println("parse2_");
Symbol links, rechts;
switch(lookaheadKind) {
case K_MUL:
acceptIt();
case K_BREAKET_OPEN:
case K_0:
case K_1:
case K_2:
case K_3:
case K_4:
case K_5:
case K_6:
case K_7:
case K_8:
case K_9:
case K_PI:
case K_E:
case K_X:
case K_Y:
case K_ANS:
case K_SQRT:
case K_LOG10:
case K_LOG2:
case K_LN :
case K_SIN:
case K_COS:
case K_TAN:
case K_ASIN:
case K_ACOS:
case K_ATAN:
case K_SINH:
case K_COSH:
case K_TANH:
case K_ASINH:
case K_ACOSH:
case K_ATANH:
case K_FAC:
case K_PER:
case K_COM:
case K_ABS:
parse2();
rechts = (Symbol)tempStack.pop();
links = (Symbol)tempStack.pop();
tempStack.push(new Exp2(K_MUL,links,rechts));
break;
case K_DIV:
acceptIt();
parse3();
//div
rechts = (Symbol)tempStack.pop();
links = (Symbol)tempStack.pop();
tempStack.push(new Exp2(K_DIV,links,rechts));
parse2_();
break;
}
}
// <3> ::= <4> <3_>
private static void parse3() throws Exception{
//system.out.println("parse3");
parse4();
parse3_();
}
// <3_> ::= K_POWER <3>
// <3_> ::= e
private static void parse3_() throws Exception{
//system.out.println("parse3_");
Symbol links, rechts;
switch(lookaheadKind) {
case K_POWER:
acceptIt();
parse3();
rechts = (Symbol)tempStack.pop();
links = (Symbol)tempStack.pop();
tempStack.push(new Exp2(K_POWER,links,rechts));
break;
}
}
// <4> ::= K_ADD <4>
// <4> ::= K_SUB <4>
// <4> ::= <5>
private static void parse4() throws Exception{
//system.out.println("parse4");
switch(lookaheadKind) {
case K_ADD:
acceptIt();
parse4();
break;
case K_SUB:
acceptIt();
parse4();
Symbol rechts = (Symbol)tempStack.pop();
tempStack.push(new Exp1(K_SUB,rechts));
break;
default:
parse5();
break;
}
}
// <5> ::= K_ANS
// <5> ::= K_PI
// <5> ::= K_E
// <5> ::= K_X
// <5> ::= K_BREAKET_OPEN <1> K_BREAKET_CLOSE
// <5> ::= K_FUNCTION <1> K_BREAKET_CLOSE
// <5> ::= <6>
private static void parse5() throws Exception{
//system.out.println("parse5");
switch(lookaheadKind) {
case K_ANS:
acceptIt();
tempStack.push(new Num(XCalc.history.ANS()));
break;
case K_PI:
acceptIt();
tempStack.push(new Num(Real.PI));
break;
case K_E:
acceptIt();
tempStack.push(new Num(Real.E));
break;
case K_X:
acceptIt();
tempStack.push(Num.getXVar());
break;
case K_Y:
acceptIt();
tempStack.push(Num.getYVar());
break;
case K_BREAKET_OPEN:
acceptIt();
parse1();
if(lookaheadKind==K_BREAKET_CLOSE)
acceptIt();
break;
case K_SQRT:
case K_LOG10:
case K_LOG2:
case K_LN :
case K_SIN:
case K_COS:
case K_TAN:
case K_ASIN:
case K_ACOS:
case K_ATAN:
case K_SINH:
case K_COSH:
case K_TANH:
case K_ASINH:
case K_ACOSH:
case K_ATANH:
case K_FAC:
case K_ABS:
final int funcType = lookaheadKind;
acceptIt();
parse1();
if(lookaheadKind==K_BREAKET_CLOSE)
acceptIt();
//calculate function
Symbol rechts = (Symbol)tempStack.pop();
tempStack.push(new Exp1(funcType,rechts));
break;
case K_PER:
case K_COM:
final int f = lookaheadKind;
acceptIt();
parse1();
if(lookaheadKind==K_SEMI)
acceptIt();
parse1();
if(lookaheadKind==K_BREAKET_CLOSE)
acceptIt();
//calculate function
final Symbol b = (Symbol)tempStack.pop();
final Symbol a = (Symbol)tempStack.pop();
tempStack.push(new Exp2(f,a,b));
break;
default:
parse6();
break;
}
}
// <6> ::= K_NUMBER <6>
// <6> ::= K_POINT <6_>
// <6_> ::= K_NUMBER <6_>
// <6_> ::= e
private static void parse6() throws Exception{
//system.out.println("parse6");
StringBuffer sb = new StringBuffer();
boolean g = lookaheadKind<10;
while(lookaheadKind<10){
sb.append(lookaheadValue);
acceptIt();
}
if(lookaheadKind==K_POINT){
sb.append(lookaheadValue);
acceptIt();
g = g || (lookaheadKind<10);
while(lookaheadKind<10){
sb.append(lookaheadValue);
acceptIt();
}
}
if(!g){
throw new Exception("Expect a number");
}
tempStack.push(new Num(new Real(sb.toString())));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -