quickeval-cpp is a C++ header and cpp tool, using the eval() function that takes a string to mimic python's eval() function.
A mathematical expression evaluator built from scratch in C++, featuring custom lexer, parser, and interpreter.
This calculator processes mathematical expressions through three distinct phases:
- Lexing: Tokenizes the input string into meaningful components
- Parsing: Handles operator precedence and parentheses evaluation
- Interpreting: Computes the final result
No external libraries. No shortcuts. Just pure C++ implementation.
The main entry point. Evaluates a mathematical expression and returns the result.
double result = eval("2 + 3 * 4"); // Returns 14.0Tokenizes the input string into individual components (numbers, operators, parentheses).
vector<string> tokens = lex("2 + 3"); // Returns ["2", "+", "3"]Processes tokens to handle operator precedence and evaluates parentheses recursively.
vector<string> parsed = parse({"2", "+", "3", "*", "4"}); // Returns ["2", "+", "12"]Evaluates the parsed tokens from left to right, computing the final result.
double result = interpret({"2", "+", "12"}); // Returns 14.0Helper function that performs basic arithmetic on two operands.
double result = evaluate("5", "*", "3"); // Returns 15.0| Operator | Description | Example | Result |
|---|---|---|---|
+ |
Addition | 5 + 3 |
8 |
- |
Subtraction | 5 - 3 |
2 |
* |
Multiplication | 5 * 3 |
15 |
/ |
Division | 6 / 3 |
2 |
() |
Parentheses | (2 + 3) * 4 |
20 |
g++ main.cpp calculator.cpp -o calculator
./calculator#include "calculator.h"
int main() {
double result = eval("(1 + 2) * 3");
cout << result << endl; // Outputs: 9
return 0;
}This section breaks down the journey from text to result, perfect for learning how interpreters work.
When you type 2 + 3 * 4, here's what happens:
Input String: "2 + 3 * 4"
↓
LEXER (lex)
↓
Tokens: ["2", "+", "3", "*", "4"]
↓
PARSER (parse)
↓
Parsed: ["2", "+", "12"]
↓
INTERPRETER (interpret)
↓
Result: 14.0
What it does: Breaks the input string into meaningful pieces called "tokens".
Why we need it: Computers can't understand "2+3" as math - they just see characters. We need to identify what's a number, what's an operator, and what's a parenthesis.
Input: "2 + 3 * 4"
Output: ["2", "+", "3", "*", "4"]
Input: "(10 + 5) / 3"
Output: ["(", "10", "+", "5", ")", "/", "3"]
The lexer reads the input character by character:
- If it sees a digit or decimal point → part of a number
- If it sees a space → separator (ignore it)
- If it sees
+,-,*,/→ operator token - If it sees
(or)→ parenthesis token
// Simplified logic:
for (char c : input) {
if (isdigit(c) || c == '.') {
// Build up a number
current += c;
}
else if (c == '+' || c == '-' || c == '*' || c == '/') {
// Save the number, then save the operator
tokens.push_back(current);
tokens.push_back(string(1, c));
}
}What it does: Figures out the order of operations and handles parentheses.
Why we need it: Math has rules! 2 + 3 * 4 should be 2 + 12 = 14, not 5 * 4 = 20. Multiplication comes before addition.
Input: ["2", "+", "3", "*", "4"]
Step 1: Handle * first → "3 * 4" = "12"
Output: ["2", "+", "12"]
Input: ["(", "2", "+", "3", ")", "*", "4"]
Step 1: Evaluate parentheses → "(2 + 3)" = "5"
Step 2: Now we have ["5", "*", "4"]
Output: ["20"]
Step 1: Handle Parentheses
When we find (, we locate its matching ), extract everything inside, and recursively parse and evaluate it. Replace the entire parenthetical expression with its result.
// Find: ["(", "2", "+", "3", ")", "*", "4"]
// Extract: ["2", "+", "3"]
// Evaluate recursively: 5
// Replace: ["5", "*", "4"]Step 2: Handle Multiplication and Division
After parentheses are gone, scan through and immediately evaluate any * or / operations.
// Find: ["2", "+", "3", "*", "4"]
// See *: evaluate "3 * 4" = 12
// Replace: ["2", "+", "12"]Now only addition and subtraction remain (left to right).
What it does: Takes the simplified tokens and calculates the final result.
Why we need it: After parsing, we're left with simple left-to-right operations. Time to actually do the math!
Input: ["2", "+", "12"]
Step 1: Start with 2
Step 2: See "+", add 12 → 2 + 12 = 14
Output: 14.0
Start with the first number, then repeatedly:
- Read an operator (
+,-,*,/) - Read the next number
- Perform that operation
- Continue with the result
result = 2 // Start
result = 2 + 12 // Apply "+" with 12
result = 14 // Done!Let's trace through a complex example: (1 + (2 * 3)) * ((4 + 5) / 3) - 2
"(1 + (2 * 3)) * ((4 + 5) / 3) - 2"
↓
["(", "1", "+", "(", "2", "*", "3", ")", ")", "*", "(", "(", "4", "+", "5", ")", "/", "3", ")", "-", "2"]
Round 1: Evaluate (2 * 3)
["(", "1", "+", "(", "2", "*", "3", ")", ")", ...]
└─────────┘
↓
"6"
["(", "1", "+", "6", ")", ...]
Round 2: Evaluate (1 + 6)
["(", "1", "+", "6", ")", ...]
└──────────────────┘
↓
"7"
["7", "*", "(", "(", "4", "+", "5", ")", "/", "3", ")", "-", "2"]
Round 3: Evaluate (4 + 5)
["7", "*", "(", "(", "4", "+", "5", ")", "/", "3", ")", "-", "2"]
└─────────┘
↓
"9"
["7", "*", "(", "9", "/", "3", ")", "-", "2"]
Round 4: Evaluate (9 / 3)
["7", "*", "(", "9", "/", "3", ")", "-", "2"]
└──────────────┘
↓
"3"
["7", "*", "3", "-", "2"]
Round 5: Handle multiplication
["7", "*", "3", "-", "2"]
└─────────┘
↓
"21"
["21", "-", "2"]
["21", "-", "2"]
↓
21 - 2 = 19
Final Result: 19 ✓
When we encounter parentheses, we don't try to solve them directly. Instead, we extract what's inside and say "figure this out first" (by calling parse again). This is recursion - a function calling itself.
Not all operators are equal:
- Parentheses: highest priority (do these first)
- Multiplication/Division: medium priority
- Addition/Subtraction: lowest priority (do these last)
We handle this by processing in order: parentheses → then * and / → then + and -.
Once we've handled precedence, operations of equal priority go left to right:
10 - 5 - 2 → (10 - 5) - 2 → 5 - 2 → 3
NOT: 10 - (5 - 2) → 10 - 3 → 7 ✗
The lexer is a simple state machine - it's either:
- Building a number
- Just saw an operator
- Just saw a parenthesis
This pattern (state machines) is everywhere in computer science.
========CALCULATOR=======
This calculator is made in C++ and uses manual processing with lexing, parsing, and interpreting.
Made by Razka Rizaldi, tyydev1.
Evaluate: (1 + (2 * 3)) * ((4 + 5) / 3) - 2
Result: 19
calculator/
├── calculator.h # Public API declarations
├── calculator.cpp # Implementation of lexer, parser, interpreter
└── main.cpp # CLI interface
- Unary operators (
-5,+3) - Exponentiation (
2^3) - More mathematical functions (
sin,cos,sqrt) - Variables and assignments (
x = 5)
Razka Rizaldi (tyydev1)
Built as a learning project to understand how interpreters work under the hood - no tutorials, just problem-solving and debugging.
Free to use for learning purposes. If you learn something from this, that's the best license there is.