A RESTful service that evaluates mathematical expressions, persists requests and results, and allows querying expressions by result.
- Evaluates infix mathematical expressions (e.g.
3 + 4 * (2 - 1)) - Supports operator precedence and parentheses
- Persists each expression and its result, and provides a unique id
- Provides search endpoint to retrieve expressions by result, and id
- Input validation driven by parsing (not regex-based), and early fail
- Throws validation error (only recognizes [0-9], brackets[(, )] and operators[/, *, +, -]
- Checkout the project from github: https://github.com/pranjal710/Abacus
- This project has been tested on Intellij 2023.3.3 (Community Edition), Gradle 8.5(bundled), OpenJDK 21.0.2, and 10.4.32-MariaDB (and MySQL))
- Update the file src/main/resources/evaluation-configuration.yaml
- database > jdbcurl > Swap ABACUS to the right DB name, and change host and port
- DB should be present on the server
- If the required table are not present in DB, then Liquibase needs to run. To run:
- Gradle task: application > liquibase ->
gradle liquibase
- Gradle task: application > liquibase ->
- To run application:
- Gradle task application > run ->
gradle run
- Gradle task application > run ->
- Default port the server comes on are 9090 for application and 9091 for admin
- This can be changed in the yaml file
- API Usage
- API to evaluate and save: POST: http://localhost:9090/rest/api/expressions/evaluate , example payload:
{ "expression" : "3+4*6-12" } - API to search by ID: GET: http://localhost:9090/rest/api/expressions/query/id?identifier={id}
- API to search by result: GET: http://localhost:9090/rest/api/expressions/query/result?identifier={result}
- Host is assumed to be
localhost, which can be changed to your host. - Service assumes DB server to be up an running, with required tables
- API to evaluate and save: POST: http://localhost:9090/rest/api/expressions/evaluate , example payload:
The service uses a parser-driven validation approach:
- ExpressionValidator.java - validates provided expression
- NumbersOperatorsTokenizer.java – converts the expressions into tokens
- InfixEvaluator.java – evaluates tokenized expression, by converting them to postfix
- PosfixEvaluator.java – evaluates a postfix tokenized expression
- ArithmeticOperators.java - available arithmetic operators
- TokenType.java - types of tokens supported
- ExpressionsDao.java - abstracts db queries
Invalid expressions fail during validation and are reported with meaningful error messages.
- Java
- Dropwizard
- MySQL
- Gradle
- JUnit 5
- Mockito
- Liquibase
- Expressions are purely numeric (no variables or functions)
- Validation is achieved via parsing
- ORM is intentionally avoided for simplicity
- Instead of building an AST, stack is used to evaluate given limited use case
- Health Check
- AST based evaluation, to support variables
- ANTLR, for richer grammar
- ORM integration
- Function support
- Cache of evaluated expressions
- Pagination for queries
- Code Analyser
- Test Coverage eg. Jacoco