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就出现生成好的类了,可以直接使用,如图:
把生成的类拷贝到你的应用里,就可以解析表达式了。调用方法和获得计算结果如下图: