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;//Result precision set to 16 bits 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("Divisor cannot be 0".equals(value) || "Divisor cannot be 0".equals(i)) {return "Divisor cannot be 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("Divisor cannot be 0".equals(value) || "Divisor cannot be 0".equals(i)) {return "Divisor cannot be 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("Divisor cannot be 0".equals(value) || "Divisor cannot be 0".equals(i)) {return "Divisor cannot be 0";} value = new BigDecimal(value).multiply(new BigDecimal(i)).stripTrailingZeros().toPlainString(); } | <DIVIDE> i = Pow() { if(i.matches("[-+]?0+\\.?0*?")) {//Whether divisor is 0 return "Divisor cannot be 0"; } if("Infinity".equals(value) || "Infinity".equals(i)){ return "Infinity";} if("NaN".equals(value) || "Infinity".equals(i)) {return "NaN";} if("Divisor cannot be 0".equals(value) || "Divisor cannot be 0".equals(i)) {return "Divisor cannot be 0";} try { //Divisibility value = new BigDecimal(value).divide(new BigDecimal(i)).stripTrailingZeros().toPlainString(); }catch(Exception e) { //Non divisibility 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("Divisor cannot be 0".equals(value) || "Divisor cannot be 0".equals(i)) {return "Divisor cannot be 0";} try { //No exception for BigDecimal value = new BigDecimal(Math.pow(Double.parseDouble(value),Double.parseDouble(i))).toPlainString(); }catch(Exception e) { //Infinite BigDecimal throw exception 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;} }
This script is saved as ExpCalcParser.jj. Extract the javacc package and put it in bin directory, as shown below:
Then create a new directory expcalc in the bin directory, press ctrl+shift, right-click, open the cmd window in the bin directory, and enter the command: JavaCC - debug_parser: true - output_directory:. \ \ expcalcparser.jj, as shown below:
Then the generated class appears in expcalc, which can be used directly, as shown in the figure:
Copy the generated class into your application, and you can parse the expression. Call the method and get the calculation result as follows: