📄 mycalculator.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.math.*;
import java.util.*;
/**
* @(#)MyCalculator.java
* @author 刘小方 软0402 200494085
* @version 1.00 2007/4/16
*/
public class MyCalculator
{
private static final int ADD=0; // +
private static final int MUL=1; // *
private static final int LBRACE=2; // (
private static final int RBRACE=3; // )
private static final int NUM=4; // data
private static final int END=5; // end
private static final int OTHER=6; // others
private static final int SUB=7; // -
private static final int DIV=8; // /
private static final int SIN=9; //sin
private static final int COS=10; //cos
private static final int TAN=11; //tan
private static final int POW=12; //pow:x*x
private static final int SQRT=13; //sqrt
private static final int LN = 14; //ln(x)
private static final int LG = 15; //lg(x)
private static double pi=Math.PI;
private static char[] input=new char[100]; //存储输入流
private static int lookahead; //当前位置
private static int pCur=0; //输入流下标
private static double yylval; //输入流的具体数据值
private static int num=0; //判断括号配对
private static boolean error=false; //成功与否
static String s0=""; //暂时存储输入流
static int ip=0; //s0的长度
static String s=""; //事件源的标签
private static int i = 0; //+/-
static TextField output=new TextField("请输入算式:like this: 1+(-2)*3-4*sin30+pow2-5/lg10!",100); //从键盘输入算式
static Label l4=new Label("Hello!");
// 词法分析器,读入一个记号
public static int yylex(){
char[] num=new char[20]; //数据(字符型)存储
int temp=0; //num数组下标
int pointFlag=0; //判断"."
// 过滤掉空白
while ( input[pCur]==' ' )
pCur++;
// 如果是数字,那么把这个记号的数值计算出来放在 yylval 中
while (input[pCur] >= '0' && input[pCur] <= '9'||input[pCur]=='.')
{
System.out.println(input[pCur]);
if(input[pCur]=='.')
{
if(pointFlag==1||temp==0)
{
System.out.println("\n Error__Point!\n");
error=true;
return 0;
}
pointFlag=1;
}
num[temp++] = input[pCur++]; //将数据按字节存储于数组中
System.out.println("ggggggg");
}
if (temp >0)
{
yylval=Double.parseDouble(new String(num)); //char--->double
return NUM;
}
// 处理算符和括号等
switch (input[pCur++]) // 注意:这里指针往前移了一位
{
case '+': return ADD;
case '*':return MUL;
case '(':return LBRACE;
case ')':return RBRACE;
case '\0': return END;
case '-':return SUB;
case '/':return DIV;
case 's': //sin
if(input[pCur]=='i')
{
pCur=pCur+2;
return SIN;
}
else if(input[pCur]=='q') //sqrt
{
pCur=pCur+3;
return SQRT;
}
else return OTHER;
case 'c': //cos
if(input[pCur]=='o'){
pCur=pCur+2;
return COS;
}
else return OTHER;
case 't': //tan
if(input[pCur]=='a')
{
pCur=pCur+2;
return TAN;
}
else return OTHER;
case 'l':
if (input[pCur] == 'n') //ln
{
pCur = pCur + 1;
return LN;
}
else if (input[pCur] == 'g') //lg
{
pCur = pCur + 1;
return LG;
}
else return OTHER;
case 'p': //pow
if(input[pCur]=='o'){
pCur=pCur+2;
return POW;
}
else return OTHER;
default: return OTHER;
}
}
public static void Match(int t) //将输入流的当前符号与理论值匹配
{
if (lookahead == t)
{
if (lookahead==LBRACE) // (
num++;
if (lookahead==RBRACE) // )
{
if (num>0) //括号匹配否
num--;
else
{
error=true;
System.out.println("Error_Lbrace and Rbrace!");
}
}
lookahead = yylex(); //得到下一个数据或算符或其他
}
else
{
error=true;
System.out.println("False_Match()!");
}
}
public static double T() //T-->FT'
{
System.out.println("T "+lookahead);
double temp=0;
switch (lookahead)
{
case LBRACE: // FIRST(T)={(,num,-,sin,cos,tan,pow,sqrt,ln,lg}
case SUB:
case SIN:
case COS:
case TAN:
case POW:
case SQRT:
case LN:
case LG:
case NUM:
temp=F()*T_();
return temp;
default:
error=true;
System.out.println("False_T()!");
return 0;
}
}
public static double E_() // 处理 E'-->+TE'|-TE'|e
{
System.out.println("E' "+lookahead);
switch (lookahead)
{
case ADD: // FIRST(E')={+,-,e}
Match(ADD); return T() + E_();
case SUB:
Match(SUB); return -T() + E_();
case RBRACE: // E'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(E')={), $}
case END:
return 0;
default:
error=true;
System.out.println("False_E'()!");
return 0;
}
}
public static double E() // 处理 E-->TE'
{
System.out.println("E "+lookahead);
double temp=0;
switch (lookahead)
{
case LBRACE: //FIRST(E')={(,num,-,sin,cos,tan,pow,sqrt,ln,lg}
case NUM:
case SUB:
case SIN:
case COS:
case TAN:
case POW:
case SQRT:
case LN:
case LG:
temp=T() + E_();
return temp;
default:
error=true;
System.out.println("False_E()!");
return 0;
}
}
public static double T_() // 处理 T'-->*FT'|/FT'|e
{
System.out.println("T' "+lookahead);
double temp=0;
double f=0;
switch (lookahead)
{
case MUL: // FIRST(T')={*,/,e}
Match(MUL);
return F() * T_();
case DIV:
Match(DIV);
f=F();
if(f==0)
{
error=true;
System.out.println("/0 Unlegeal!");
}
else temp=1/f * T_();
return temp;
case ADD: // T'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(T')={+,-,),NUM,$}
case SUB:
case END:
case NUM:
case RBRACE:
return 1;
default:
error=true;
System.out.println("False_T'()!");
return 0;
}
}
public static double F() // 处理 F-->(E)|num|-F|sinF|cosF|tanF|powF|sqrtF|lnF|lgF
{
System.out.println("F "+lookahead);
double temp=0;
double t=0;
switch(lookahead)
{
case LBRACE: // FIRST(F)={(,num,-,sin,cos,tan,pow,sqrt,ln,lg}
Match(LBRACE);
temp = E();
Match(RBRACE);
return temp;
case NUM:
temp = yylval;
Match(NUM);
return temp;
case SUB:
Match(SUB);
temp=-F();
return temp;
case SIN:
Match(SIN);
t=F();
t=(t/180)*pi;
temp=Math.sin(t);
return temp;
case COS:
Match(COS);
t=F();
t=(t/180)*pi;
temp=Math.cos(t);
return temp;
case TAN:
Match(TAN);
t=F();
if (t == 90)
error = true;
t=(t/180)*pi;
temp=Math.tan(t);
return temp;
case POW:
Match(POW);
temp=Math.pow(F(),2);
return temp;
case LG:
Match(LG);
double ln=F();
System.out.println("F()"+ln);
if (ln > 0)
{
temp = Math.log10(ln) ;
return temp;
}
else {
error = true;
return 0;
}
case LN:
Match(LN);
double lN = F();
//System.out.println("F()" + lN);
if (lN > 0)
{
temp = Math.log(lN);
return temp;
}
else
{
error = true;
return 0;
}
case SQRT:
Match(SQRT);
double st=F();
if(st<0){
System.out.println("负数"+st+"无法开根号!");
error=true;
}
else if(st==0){
System.out.println("sqrt(0)!");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -