# simple-math-calculator **Repository Path**: jinceon/simple-math-calculator ## Basic Information - **Project Name**: simple-math-calculator - **Description**: 简易计算器。输入计算式子 如1+2*3-4/5 计算器返回计算结果。计算器将式子解析成抽象语法树后转译成 BigDecimal的计算来处理,因此无精度问题 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-02-06 - **Last Updated**: 2024-07-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # antlr4应用场景 ## 1.简易计算器 众所周知,Java、JS 等语言在计算小数时可能出现精度问题。如 ```shell > 0.1 + 0.2 0.30000000000000004 ``` 当然 Java 本身也提供了 BigDecimal 等类进行精确计算。 ```java BigDecimal a = new BigDecimal("0.1"); BigDecimal b = new BigDecimal("0.2"); a.add(b) ``` 但是这样又显得很繁琐。即使一个简单的算式`a+b*c-d/e`改成BigDecimal的写法就需要大量的代码。 刚好在学习antlr,就试试将一个算式解析抽象成语法树后,再自动改写转译成BigDecimal的形式。 本项目即是在这样的学习背景下产生的一个toy项目。 ## 2. 文本转换器 对接某公司的api,其返回了一个建议的树结构,如下所示 ``` [ "a", "b", "c":[ "d", "e":[ "f", "g":["h","i"] ] ] ] ``` 其表达的业务含义大概类似于扁平的parent二维表 | id | parent | |----|--------| | a | | | b | | | c | | | d | c | | e | c | | f | e | | g | e | | h | g | | i | g | 期望转成如上表格所示的关系型父子二维表格(见`SimpleTreeFlattenVisitor`)。 转成json格式(见`SimpleTreeVisitor`)。 ```json [ "a", "b", { "c":[ "d", { "e":[ "f", {"g":["h","i"]} ] } ] } ] ``` ## 代码目录及说明 1. 编写语法词法规则,见 `Calculator.g4`、`SimpleTree.g4` 2. 执行 `mvn antlr4:antlr4`,根据g4词法语法规则生成对应的解析文件,见 src/main/java 下的 `io.gitee.jinceon.parser` 3. 继承 `*BaseVisitor` 并根据实际需求填充覆盖方法,见 `ExprVisitor`(简易计算器)、`SimpleTreeVisitor`(文本转换器) 4. 对外暴露API,见 `Calculator` ## Usage ### 常量计算 ```java Calculator.calculate("1+2*3-4/5") // 6.2 ``` ### 变量计算 ```java Map context= new HashMap<>(); context.put("a", 0.1); context.put("b", 0.2); context.put("c", 3); context.put("d", -4); context.put("e", 5); Calculator.calculate("a+b", context) // a+b=0.1+0.2=0.3 Calculator.calculate("a+b*c-d/e", context) // 0.1 + 0.2*0.3 - (-4)/5 = 0.1 + 0.6 - (-0.8) = 1.5 ```