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

📄 expcomplier.java

📁 用JAVA写的计算一段数学表达式的程序
💻 JAVA
字号:
/*
 *  Copyright 2006 CSK
 *  http://www.csksoft.net
 */

package net.csksoft.util.expcomp;
import org.omg.CORBA.*;
import java.util.*;
public class ExpComplier {
	private String strExpressionBuf;
	private LinkedList<ExpToken> tokenCalBuf;
	private String strLastErrInfo;
	public ExpComplier()
	{
		initEnv();
	}
	public ExpComplier(String Exp)
	{
		initEnv();
		SetExpression(Exp);
	}
	public String SetExpression(String Exp)
	{
		String strOld;
		strOld = strExpressionBuf;
		strExpressionBuf = Exp;
		return strOld;
	}
	public String GetExpression()
	{
		return strExpressionBuf;
	}
	public String GetLastError()
	{
		return strLastErrInfo;
	}
	public boolean Complie()
	{
		return TokenizerAndParse();
	}
	private boolean TokenizerAndParse()
	{
		tokenCalBuf.clear();
		int nPos;
		int nLastState;
		Stack<Character> stkParser = new Stack<Character>();
		Stack<Integer> stkParserNum = new Stack<Integer>();		
		String tmpStr= new String(strExpressionBuf);
		String tmpNumBuffer = "";
		tmpStr = "#" + tmpStr + "#";
		ExpToken currentToken;
		nLastState = 0;
		char cLast = 0;
		char cCurrent =0 ;
		for (nPos=0;nPos<tmpStr.length();nPos++) // DFA RegExp
		{
			
			cLast = cCurrent;
			cCurrent= tmpStr.charAt(nPos);
			
			switch(getCharType(cCurrent))
			{
				case 0: // invaild char
					strLastErrInfo = "at" + nPos + " bad operation type";
					return false;
				
				case 1: // number
					switch(nLastState)
					{
						case 0://start
							tmpNumBuffer ="";
							
							break;
						case 1://last is number
							tmpNumBuffer +=cCurrent;
							break;
						case 2://last is op
							tmpNumBuffer = "";
							tmpNumBuffer +=cCurrent;
							break;
					}
					nLastState = 1;
					
				break;
				case 2: //operator
					switch(nLastState)
					{
						case 0://start
							
							break;
						case 1://last is number
							
							
								
								NumberToken tmpNumbetTk =new NumberToken();
								try
								{
									tmpNumbetTk.setValue(Double.parseDouble(tmpNumBuffer));
								}
								catch(NumberFormatException ec){
									strLastErrInfo = "at" + nPos + " Bad Number";
									return false;
								}
								currentToken = (ExpToken)tmpNumbetTk;
								
								tokenCalBuf.add(currentToken);
							
							break;
						case 2:
							if (cCurrent=='+' || cCurrent=='-')
							{
								if (cLast!=')')
								{
									currentToken = (ExpToken)new NumberToken(0);
									tokenCalBuf.add(currentToken);
								}
							}
							
					}
					
				
						if (cCurrent == '#'){
							
							if (nPos!=0 && nPos!=tmpStr.length()-1)
							{
								strLastErrInfo = "at" + nPos + " bad operation type";
								return false;
							}
						}
						
					if (!onGetOpToken(stkParser,stkParserNum,nPos,cCurrent,nLastState)) return false;
					nLastState = 2;
				break;
			}
		}
		if (!stkParser.isEmpty())
		{
			strLastErrInfo = "at" + nPos + " stack err";
			return false;
		}
		return true;
	}
	private boolean onGetOpToken(Stack<Character> opstk,Stack<Integer> opNumstk,int currentpos,char cToken,int laststate)
	{
		char tmpStkToken;
	
		do
		{
			if (opstk.isEmpty()){
				if (cToken=='#'){
					opstk.push(new Character(cToken));
					opNumstk.push(new Integer(laststate));
					return true;
				}
				else
				{
					strLastErrInfo = "at" + currentpos + " stack err";
					return false;
				}
			
			}
			tmpStkToken = opstk.peek().charValue();
			int currentTokenInfo = opNumstk.peek().intValue();
			switch(compareOpLevel(tmpStkToken,cToken))
			{
			case 0:
				opstk.pop();
				opNumstk.pop();
				return true;
				
			case -1:
				opstk.push(new Character(cToken));
				opNumstk.push(new Integer(laststate));
				return true;
				
			case 1:
				opstk.pop();
				opNumstk.pop();
				ExpToken tOpToken;
				switch(tmpStkToken)
				{
					case '+':
					//	if (currentTokenInfo==2){
					//		OpPlus tmpTk =  new OpPlus();
					//		tmpTk.setArgNum(1);
					//		tOpToken =(ExpToken)tmpTk;
					//	}else
					//	{
							tOpToken =(ExpToken) new OpPlus();
					//	}
						
						
					break;
					case '-':
					//	if (currentTokenInfo==2){
					//		OpMinus tmpTk =  new OpMinus();
					//		tmpTk.setArgNum(1);
					//		tOpToken =(ExpToken)tmpTk;
					//	}else
					//	{
							tOpToken =(ExpToken) new OpMinus();
					//	}
						
					break;
					case '*':
						tOpToken =(ExpToken) new OpMul();
					break;
					case '/':
						tOpToken =(ExpToken) new OpDiv();
					break;
					default:
						strLastErrInfo = "at" + currentpos + " bad operation";
						return false;	
				
				}
				tokenCalBuf.add(tOpToken);
				
				break;
			case 2:
				strLastErrInfo = "at" + currentpos + " bad operation" ;
				return false;
			}
			
	
		}while(true);
		
	}
	private int compareOpLevel(char tokenA,char tokenB){
		int[][] opLevelTable
		={
			//    +  -  *  /  ^  (  )  #
				 {1, 1,-1,-1,-1,-1, 1, 1}, // +
				 {1, 1,-1,-1,-1,-1, 1, 1}, // -
				 {1, 1, 1, 1,-1,-1, 1, 1}, // *
				 {1, 1, 1, 1,-1,-1, 1, 1}, // /
			     {1, 1, 1, 1, 1,-1, 1, 1}, // ^
				{-1,-1,-1,-1,-1,-1, 0, 2}, // (
				 {1, 1, 1, 1, 1, 2, 1, 1}, // )
				{-1,-1,-1,-1,-1,-1, 2, 0} // #
				
		};
		
		return opLevelTable[getOpIndex(tokenA)][getOpIndex(tokenB)];
	}
	private int getCharType(char c){
		String strDigitalTable = "0123456789.";
		
		if (strDigitalTable.indexOf(c)!=-1) return 1;
		if (getOpIndex(c)!=-1) return 2;
		return 0;
	}
	private int getOpIndex(char c)
	{
		String strOperationTable = "+-*/^()#";
		return strOperationTable.indexOf(c);
	}
	public boolean calc(DoubleHolder ans){
		Stack<OpObj> stkCalc = new Stack<OpObj>();
		if (strLastErrInfo.equals(""))
		{
			while(!tokenCalBuf.isEmpty())
			{
				ExpToken CurrentToken = tokenCalBuf.removeFirst();
				switch(CurrentToken.getTokenType())
				{
				case ExpToken.TOKEN_NUMBER_CONST:
					stkCalc.push((OpObj)CurrentToken);
					break;
				case ExpToken.TOKEN_OPERATION:
					if (((OperationToken)CurrentToken).Calc(stkCalc) == false)
						{
							strLastErrInfo = "error when exec op";
							return false;
						}
					
					
					
				
				}
			}
			if (stkCalc.isEmpty())
			{
				ans.value = 0;
				
			}
			else
			{
				ans.value = stkCalc.pop().getValue();
			}
			if (!stkCalc.isEmpty())
			{
				strLastErrInfo = "stack err";
				return false;
			
			}			
			return true;
		}
		return false;
	}
	private void initEnv()
	{
		tokenCalBuf = new LinkedList<ExpToken>();

		strExpressionBuf = "";
		strLastErrInfo = "";
	}
}

⌨️ 快捷键说明

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