⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 java的Applet 表达式解析器. 采用递归下隆解析法.可以进行四刚运算. 乘方,括号等正刚运算
💻 JAVA
字号:
/*
 * 创建日期 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;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -