javacc5.0 实现四则运算计算器脚本

options{
 STATIC=false;
 LEXER_CLASS="ExpCalcParserTokenManager";
}
PARSER_BEGIN(ExpCalcParser)
import java.io.*;
import java.io.PrintStream; 
import java.math.BigDecimal;

public class ExpCalcParser{
	private static final int DEF_DIV_SCALE = 16;//结果精度设置为16位
	private String exp;
	
	public static ExpCalcParser createExpressionParser(String s) {
      SimpleCharStream scs = new SimpleCharStream(new StringReader(s), 1, 1, s.length());
      ExpCalcParserTokenManager token_source = new ExpCalcParserTokenManager(scs);
      return new ExpCalcParser(token_source);
	}
	public static void main(String args[]) throws ParseException{
		String exp = "1/0.0";
		ExpCalcParser parser = createExpressionParser(exp);
		System.out.println(parser.calculator());
	}

}
PARSER_END(ExpCalcParser)

SKIP : 
{
	<(" ")>
}
TOKEN : { < EOL: "\n" | "\r" | "\r\n" > } 
TOKEN : 
{
	<#DIGITS : (["0"-"9"])+ >
	|
	<NUMBER : <DIGITS> | <DIGITS>"."<DIGITS>>
	|
	<ADD : "+" >
	|
	<SUBTRACT : "-" >
	|
	<MULTIPLY : "*" >
	|
	<DIVIDE : "/" >
	|
	<POW : "^">
	|
	<LEFT_PAR : "(" >
	|
	<RIGHT_PAR : ")" >
}
public String calculator(): 
{
	String result = "";
}
{
	(result = Expression())*
	 { return result; } 
}
String Expression() :
{
	String i;
	String value;
}
{
	value = Term()
	(
		<ADD>
		i=Term()
		{ 
		if("Infinity".equals(value) || "Infinity".equals(i)){ return "Infinity";}
		if("NaN".equals(value) || "Infinity".equals(i)) {return "NaN";}
		if("除数不能为0".equals(value) || "除数不能为0".equals(i)) {return "除数不能为0";}
		value = new BigDecimal(value).add(new BigDecimal(i)).stripTrailingZeros().toPlainString();
		}
		|
		<SUBTRACT>
		i=Term()
		{
		if("Infinity".equals(value) || "Infinity".equals(i)){ return "Infinity";}
		if("NaN".equals(value) || "Infinity".equals(i)) {return "NaN";}
		if("除数不能为0".equals(value) || "除数不能为0".equals(i)) {return "除数不能为0";}
		 value = new BigDecimal(value).subtract(new BigDecimal(i)).stripTrailingZeros().toPlainString();
		}
	)*
	{return value;}
}
String Term() :
{
	String i;
	String value;
}
{
	value = Pow()
	(
		<MULTIPLY>
		i = Pow()
		
		{
			if("Infinity".equals(value) || "Infinity".equals(i)){return "Infinity";}
			if("NaN".equals(value) || "Infinity".equals(i)) {return "NaN";}
			if("除数不能为0".equals(value) || "除数不能为0".equals(i)) {return "除数不能为0";}
			value = new BigDecimal(value).multiply(new BigDecimal(i)).stripTrailingZeros().toPlainString();
		}
		|
		<DIVIDE>
		i = Pow()
		{
			if(i.matches("[-+]?0+\\.?0*?")) {//除数是否为0
				return "除数不能为0";
			}
			if("Infinity".equals(value) || "Infinity".equals(i)){ return "Infinity";}
			if("NaN".equals(value) || "Infinity".equals(i)) {return "NaN";}
			if("除数不能为0".equals(value) || "除数不能为0".equals(i)) {return "除数不能为0";}
			try {
				//能整除
				value = new BigDecimal(value).divide(new BigDecimal(i)).stripTrailingZeros().toPlainString();
			}catch(Exception e) {
				//不能整除
				value = new BigDecimal(value).divide(new BigDecimal(i),DEF_DIV_SCALE,BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
			}
		}	
	)*
	{return value;}
}

String Pow() : 
{
	String i;
	String value;
}
{
	value = Primary()
	(
		<POW>
		i = Primary()
		{
			if("Infinity".equals(value) || "Infinity".equals(i)){ return "Infinity";}
			if("NaN".equals(value) || "Infinity".equals(i)) {return "NaN";}
			if("除数不能为0".equals(value) || "除数不能为0".equals(i)) {return "除数不能为0";}
			try {
				 //非无穷大BigDecimal不出异常
				 value = new BigDecimal(Math.pow(Double.parseDouble(value),Double.parseDouble(i))).toPlainString();
			 }catch(Exception e) {
				 //无穷大BigDecimal抛异常
				 value = new Double(Math.pow(Double.parseDouble(value),Double.parseDouble(i))).toString();
			 }
		}
	)*
	{return value;}
}

String Primary() :
{
	Token t;
	String value;
}
{
	t=<NUMBER>
	{return t.image;}
	|
	<LEFT_PAR> value = Expression() <RIGHT_PAR>
	{ return value;}
	|
	<SUBTRACT> value = Primary()
	{return new BigDecimal("0").subtract(new BigDecimal(value)).stripTrailingZeros().toPlainString();}
	|
	<ADD> value = Primary()
	{return value;}
	
}

本脚本保存为 ExpCalcParser.jj,解压javacc压缩包,放到bin目录下,如下图:

然后在bin目录里新建目录expcalc,并且按住ctrl+shift,点击鼠标右键,在bin目录打开cmd窗口,输入命令:javacc -debug_parser:true -output_directory:.\\expcalc ExpCalcParser.jj,如下图:

 

然后在expcalc就出现生成好的类了,可以直接使用,如图:

 

把生成的类拷贝到你的应用里,就可以解析表达式了。调用方法和获得计算结果如下图:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值