/*
* 创建日期 2005-4-4
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
/**
* @author Administrator
*
* TODO 递归下降法解析表达式
* 表达式充许:加,减,乘,除,乘方,括号
*/
class Parser {
//定义表达式项的类型:占位符,分隔符,变量,数值
final int NONE =0;
final int DELIMITER=1;
final int VARIABLE=2;
final int NUMBER=3;
//定义错误类型:
final int SYNTAX=0;
final int UNBALPARENS=1;
final int NOEXP=2;
final int DIVBYZERO=3;
//定义表达式的结束符
final String EOE="\0";
//表达式
private String exp;
//当前表达式索引
private int expIdx;
//当前表达式的项
private String token;
//当前项的类型
private int tokType;
//变量的值存储表
private double vars[]=new double[26];
//表达式解析入口
public double evaluate(String expstr) throws ParserException
{
double result;
exp=expstr;
expIdx=0;
getToken();
//没有表达式出错
if(token.equals(EOE))
handleErr(NOEXP);
//执行表达式解析
result=evalExp1();
//表达式没有结束符
if(!token.equals(EOE))
handleErr(SYNTAX);
return result;
}
//处理变量的值
private double evalExp1() throws ParserException
{
double result;
int varIdx;
int ttokType;
String temptoken;
if(tokType==VARIABLE)
{
//保存当前项
temptoken=new String(token);
ttokType=tokType;
//记录变量的下标
varIdx=Character.toUpperCase(token.charAt(0))-'A';
getToken();
if(!token.equals("=")){
putBack();//返回到取本次取等号之前
token = new String(temptoken);
tokType=ttokType;
}
else{
getToken();
result = evalExp2();
vars[varIdx]=result;
return result;
}
}
return evalExp2();
}
/*加,减两个项
*
*/
private double evalExp2() throws ParserException
{
char op;
double result;
double partialResult;
result=evalExp3();
while((op=token.charAt(0))=='+'||op=='-'){
getToken();
partialResult=evalExp3();
switch(op){
case '-':
result = result - partialResult;
break;
case '+':
result = result + partialResult;
break;
}
}
return result;
}
//对两个因数 乘,除,或取余
private double evalExp3() throws ParserException
{
char op;
double result;
double partialResult;
result = evalExp4();
while((op= token.charAt(0))=='*'||op=='/'||op=='%'){
getToken();
partialResult=evalExp4();
switch(op){
case '*':
result=result*partialResult;
break;
case '/':
if(partialResult==0.0)
handleErr(DIVBYZERO);
result=result/partialResult;
break;
case '%':
if(partialResult==0.0)
handleErr(DIVBYZERO);
result=result%partialResult;
break;
}
}
return result;
}
//乘方处理
private double evalExp4() throws ParserException
{
double result;
double partialResult;
double ex;
int t;
result =evalExp5();
if(token.equals("^")){
getToken();
partialResult=evalExp4();
ex=result;
if(partialResult==0.0){
result=1.0;
}
else{
for(t=(int)partialResult-1;t>0;t--)
result = result * ex;
}
}
return result;
}
//正负号的处理
private double evalExp5() throws ParserException
{
double result;
String op;
op="";
if((tokType == DELIMITER) && token.equals("+")|| token.equals("-")){
op=token;
getToken();
}
result = evalExp6();
if(op.equals("-")) result= -result;
return result;
}
//括号的处理
private double evalExp6() throws ParserException
{
double result;
if(token.equals("(")){
getToken();
result= evalExp2();
if(!token.equals(")"))
handleErr(UNBALPARENS);
getToken();
}
else
result =atom();
return result;
}
//获取表达式中的数值因数
private double atom() throws ParserException
{
double result=0.0;
switch(tokType){
case NUMBER:
try{
result=Double.parseDouble(token);
}
catch(NumberFormatException exc){
handleErr(SYNTAX);
}
getToken();
break;
case VARIABLE:
result=findVar(token);
getToken();
break;
default:
handleErr(SYNTAX);
break;
}
return result;
}
/*
* 获最变量名第一个字符与A的偏移量为下标的数组里的变量值
*/
private double findVar(String vname) throws ParserException
{
if(!Character.isLetter(vname.charAt(0))){
handleErr(SYNTAX);
return 0.0;
}
return vars[Character.toUpperCase(vname.charAt(0))-'A'];
}
/*
* 将表达式的输入字符后退到当前处理之前
*/
private void putBack()
{
if(token==EOE) return;
for(int i=0;i<token.length();i++) expIdx--;
}
//捕捉出错
private void handleErr(int error) throws ParserException
{
String[] err={
"错误0: 非正则表达式错误!",
"错误1: 表达式中括号不匹配!",
"错误2: 没有表达式!",
"错误3: 除零错!"
};
//抛出异常
throw new ParserException(err[error]);
}
//获取表达式的下一项
private void getToken()
{
//将当前项置空
tokType=NONE;
token="";
//检查表达式是否结束
if(expIdx == exp.length()){
token = EOE;
return;
}
//去除空白符
while(expIdx<exp.length() && Character.isWhitespace(exp.charAt(expIdx)))
++expIdx;
//去空白符后,再次检查是否结束
if(expIdx == exp.length()){
token = EOE;
return;
}
//当前项为分隔符
if(isDelim(exp.charAt(expIdx))){
token += exp.charAt(expIdx);
expIdx++;
tokType = DELIMITER;
}//当前项为变量,变量只有第一个字母有意义
else if(Character.isLetter(exp.charAt(expIdx))){
while(!isDelim(exp.charAt(expIdx))){
token += exp.charAt(expIdx);
expIdx++;
if(expIdx>=exp.length()) break;
}
tokType= VARIABLE;
}//当前项为数值
else if(Character.isDigit(exp.charAt(expIdx))){
while(!isDelim(exp.charAt(expIdx))){
token += exp.charAt(expIdx);
expIdx++;
if(expIdx>=exp.length()) break;
}
tokType = NUMBER;
}//结束
else{
token=EOE;
return;
}
}
/**检查是否为分隔符
* @param c
* @return
*/
private boolean isDelim(char c) {
// TODO 自动生成方法存根
if((" +-/*%^=()".indexOf(c) != -1))
return true;
else
return false;
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
Applet表达式解析器.rar_表达式解析
共10个文件
class:3个
java:3个
txt:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 25 浏览量
2022-09-19
12:46:40
上传
评论
收藏 9KB RAR 举报
温馨提示
java的Applet 表达式解析器. 采用递归下隆解析法.可以进行四刚运算. 乘方,括号等正刚运算
资源推荐
资源详情
资源评论
收起资源包目录
Applet表达式解析器.rar (10个子文件)
Applet表达式解析器
bin
CalcApp.class 2KB
ParserException.class 469B
java.policy.applet 141B
Parser.class 5KB
src
Parser.java 6KB
CalcApp.java 1KB
ParserException.java 367B
.project 400B
.classpath 232B
www.pudn.com.txt 218B
共 10 条
- 1
资源评论
邓凌佳
- 粉丝: 65
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功