ExpressionParser
Description
A powerful, self-contained, and header-only C++ library designed to parse and evaluate complex mathematical and logical expressions from string inputs. Built with pure C++, it provides a robust and versatile engine for applications requiring dynamic calculation capabilities, such as scientific calculators, data analysis tools, or embedded scripting engines.
The parser is engineered for high precision and flexibility, offering extensive control over calculation behavior, including angle units for trigonometric functions and operator precedence. Beyond simple arithmetic, it supports a vast library of functions, handles logical and bitwise operations, and can even evaluate expressions as a function of a variable \(x\) over a given range. A key feature is its ability to generate a complete, step-by-step breakdown of the evaluation process, making it an excellent tool for educational or debugging purposes.
Technologies Used
- Language: C++
- Core Libraries: C++ Standard Library (STL)
- Key Components:
string
,vector
,stack
,unordered_map
,cmath
for mathematical functions, andrandom
for number generation.
Functionality & Features
The ExpressionParser
is equipped with an extensive set of features that provide a comprehensive evaluation environment.
Core Mathematical Operations
- Full Arithmetic Support: Handles addition, subtraction, multiplication, division, and exponentiation (
^
) with correct operator precedence. - Configurable Operator Precedence: Features robust support for implicit multiplication (e.g.
2(3+1)
or5x
), with an option to assign it a higher binding priority than standard division. - Advanced Syntax: Correctly parses nested parentheses, factorials (
!
), percentages (%
), permutations (P
), combinations (C
), and the modulo operator function (mod(m,n)
). Both the factorial and percentage operators bind tightly to their operands with a higher precedence than exponentiation (e.g.2^5%
is evaluated as2^(0.05)
). - Constants and Randomness: Built-in support for constants
pi
(\(\pi\)) ande
(\(e\)), along with a special token for generating random numbers between0
,1
(rnd#
). - Context-Aware Parsing: Features a sophisticated system for scientific notation and constants. The lowercase
e
is dual-purpose: it’s parsed as Euler’s number unless immediately followed by a digit (or a decimal point), in which case it signifies scientific notation (\(\times10^{...}\)). For unambiguous use, the uppercaseE
acts as a more powerful and dedicated scientific notation operator that correctly handles signs, allowing expressions like2.5E-3
to be evaluated as \(2.5\times10^{-3}\). The parser also correctly interprets absolute value using vertical bars (|
) with any level of nesting.
Advanced Mathematical Functions
- Comprehensive Function Library: Includes a wide range of functions:
- Trigonometry:
sin
,cos
,tan
,csc
,sec
,cot
- Inverse Trigonometry:
asin
,acos
,atan
,scsc
,asec
,acot
- Hyperbolic:
sinh
,cosh
,tanh
,csch
,sech
,coth
- Inverse Hyperbolic:
asinh
,acosh
,atanh
,acsch
,asech
,acoth
- Logarithms & Roots:
log(n)
,log(base,n)
,ln
,sqrt
,cbrt
,nthrt(n,m)
- Others:
abs
,rndInt(from,to)
for a random integer value betweenfrom
andto
.
- Trigonometry:
- Flexible Angle Units: Seamlessly performs trigonometric calculations in degrees, radians, or gradians.
Logical and Bitwise Operations
- Comparison Operators: Full support for
<
,>
,=
,<=
, and>=
. - Logic Gates: A complete set of logical gates including
AND
,OR
,NOT
,NAND
,NOR
,XOR
, andXNOR
. - Bitwise Shift Operators: Includes support for left (
<<
) and right (>>
) bitwise shifts, which perform efficient multiplication and division by powers of two on integer operands. - Dual-Mode Logic: A unique feature allowing logic gates to operate in two modes:
- Logical Mode: Treats any non-zero value as
true
(1). - Bitwise Mode: Performs bitwise operations on integer operands.
- Logical Mode: Treats any non-zero value as
- Boolean Functions: Includes helper functions like
ispr
(is prime),issqr
(is perfect square),isodd
, andiseven
—each returns either1
(true) or0
(false), then the evaluation is continued.
Functional Evaluation
- Evaluation over a Variable: Treats expressions as functions of \(x\), allowing evaluation at a single point, a vector of points, or over a specified range (
start
,end
,step
)—either for generating full lists of evaluation steps, or just returning the values. - Summation (\(\sum\)) and Product (\(\prod\)): Includes
sum(expr, start, end)
andprod(expr, start, end)
functions to perform complex calculations over a specified range.
User-Centric Features
- Variable Precision Control: Users can specify the numerical precision (up to 17 decimal places) for all calculations, affecting the final result, internal constants, and all steps in the generated evaluation trace.
- Step-by-Step Evaluation: Can generate a complete, sequential breakdown of the calculation steps, from the initial expression to the final result, perfect for educational tools or debugging.
- Advanced Expression Formatting: Provides a utility to “beautify” raw string expressions for clean UI display, with options to force asterisks with implicit multiplication, use
|
for absolute values, force decimal points, and insert spaces around operators (excludingP
,C
). - Granular Error Reporting: Returns specific, detailed error codes from a list of 49 possible issues, allowing for precise feedback on invalid syntax, mathematical domain errors (e.g.
sqrt(-1)
), or invalid function arguments.
Implementation Highlights
The library’s internal architecture is designed for clarity, maintainability, and robustness.
- Modular, Multi-Class Architecture: The core logic is cleanly separated into distinct, nested classes, each with a single responsibility:
ExpressionFormatter
: A powerful pre-processing engine that sanitizes, tokenizes, and standardizes the raw input string. It intelligently handles ambiguous syntax like absolute value bars (|
) and implicit function brackets. Also, it supports early exiting with an error code if the expression was discovered to be invalid while formatting.ExpressionValidator
: A dedicated validation layer that checks for syntactical correctness, proper operator placement, and valid function arguments before any evaluation occurs.ExpressionEvaluator
: The heart of the library, which uses a recursive descent parsing strategy to evaluate the formatted and validated expression. It correctly handles operator precedence and associativity, including right-to-left for exponentiation (e.g.2^3^4
is treated as2^(3^4)
).
- Recursive Descent Evaluation Strategy: The evaluation logic breaks down complex expressions by recursively solving the contents of the highest-precedence operations first (parentheses, functions), and then working through the standard order of operations. This is managed elegantly using a stack to keep track of nested evaluation contexts when generating step-by-step solutions.
- Pre-processing Pipeline: Instead of a single, monolithic parsing function, the class uses a pipeline approach. An input expression first goes through formatting and validation. This crucial step simplifies the evaluation logic immensely, as the
ExpressionEvaluator
can assume it is receiving a well-formed and unambiguous expression string. - Tokenization with Single Characters: A clever design choice was to map all functions and multi-character operators (e.g. “sin”, “acosh”, “«”) to unique single-character tokens during the formatting stage. This significantly simplifies and accelerates the parsing logic within the
ExpressionEvaluator
, as it only needs to handle single-character operators. - Atomic Operand Marking via ‘Magic Characters’: To solve ambiguity with parenthesized negative bases (e.g.
(-2)^4
), theExpressionFormatter
uses an elegant marking system. When it detects a pattern like(...)
followed by an operator such as^
,!
,%
,P
, orC
, it inserts a unique, non-mathematical “magic character” before the opening parenthesis. This character acts as a flag for theExpressionEvaluator
, signaling it to treat the entire parenthesized block as a single, unbreakable atomic operand. This guarantees the expression is fully resolved (to-2
in the example) before being passed to the operator, ensuring mathematical correctness. - Heuristic and Recursive Disambiguation of Absolute Value |…|: Parsing the ambiguous
|
character is handled by a robust, multi-stage algorithm. Initially, heuristic rules analyze the context around each|
to resolve clear-cut cases, converting them to unambiguous internal tokens for “open” ([
) and “close” (]
). For any remaining ambiguous bars, the parser employs a recursive backtracking algorithm. This powerful technique systematically explores all possible pairings until it finds a syntactically valid structure. Once fully disambiguated, the pairs are converted into the mapped character forabs(...)
function format for the evaluator. - Efficient and Numerically Stable Combinatorics: The calculation of permutations (
nPr
) and combinations (nCr
) is highly optimized to prevent overflow errors common with naive factorial-based methods.- For permutations, instead of calculating
n! / (n-r)!
, the implementation directly computes the product series \(n\times(n-1)\times...\times(n-r+1)\), avoiding large intermediate factorial values. - For combinations, the logic is further optimized for numerical stability. Rather than computing the full permutation and then dividing by
r!
, the algorithm interleaves multiplication and division within a single loop (\((\frac{n}{1})\times(\frac{n-1}{2})\times...\times(\frac{n-r+1}{r})\)). This keeps the cumulative result as small as possible at each step, dramatically reducing the risk of overflow and maintaining precision.
- For permutations, instead of calculating
- Optimized Result Substitution with Sign Consolidation: When substituting a calculated value back into the expression string, the evaluator avoids the common inefficiency of creating redundant signs (e.g.
10+-5
) that require a separate clean-up pass. It uses specialized, context-aware methods (_insertSubPartialResult
and_insertSubPartialResult_funs
) that inspect the operator preceding the sub-expression. Based on this context and the sign of the result, these methods consolidate the signs in a single action—for example, converting10-(-5)
directly to10+5
. This improves performance and ensures the expression string remains syntactically clean at every stage of the step-by-step evaluation.
Important notes — Must read before use
Class Usage
- Properties/Fields: The
ExpressionParser
class defines several properties that can be accessed or modified through corresponding getter and setter methods. The following table describes each property and its intended purpose:
Property | Type | Purpose | Methods |
---|---|---|---|
expression |
std::string |
- This stores the input expression, providing the ability to retrieve or update its value when needed. - Default value: "0" |
getExpression() , setExpression(const std::string&) |
implicitMultHighPrec |
bool |
- This controls whether implicit multiplication (juxtaposition) binds more tightly than standard left-to-right evaluation. - If true , it will give higher precedence over division. Otherwise, it will not.- This doesn't affect functions with implicit brackets, they have their own rules. - Defualt value: false . |
getImplicitMultHighPrec() , setImplicitMultHighPrec(const bool) |
forceBitwiseLogic |
bool |
- This controls the behavior of logical operators. - If true , logical operators will behave as bitwise operators, producing error codes if used with non-integer values.- If false , logical operators will use standard logical evaluation, treating any non-zero value as true .- Default value: false . |
getForceBitwiseOperations() , setForceBitwiseLogic(const bool) |
precision |
short |
- This controls the precision of the results, internal calculations, and formatted expressions. - It will get clamped between 0 and 17. - Default value: 6 digits after the decimal point. |
getPrecision() , setPrecision(const short) |
angleUnit |
ExpressionParser |
- This is used when calculating trigonometric and inverse trigonometric functions. - Default value: AngleUnits:: fRADIAN . |
getAngleUnit , setAngleUnit(const ExpressionParser::AngleUnits) |
- Note that all these fields can be initialized through the class constructor when creating a new object. Alternatively, you may omit them, in which case default values will be applied.
- Operational Methods: The
ExpressionParser
class offers a range of methods dedicated to evaluating, formatting, and generating step-by-step analyses of expressions. The table below outlines these methods, along with their respective purposes and return types:
Method | Purpose & Return Type |
---|---|
evaluate |
- This method evaluates the specified expression and returns an ExpressionParser:: EvaluationResult structure containing the computed double value and an accompanying error code indicating the evaluation status. |
formatExpression |
- This method formats the value of the specified expression to enhance readability and ensure suitability for user interfaces.- It accepts four parameters that define the formatting behavior: forceDecimalPoints to enforce decimal point display, forceAsterisks to explicitly denote implicit multiplication, useAbsBars to represent absolute values using vertical bars instead of the function format, and useSpaces to insert spacing around operators (excluding P and C ).- The method returns a std::string containing the formatted result. |
generateEvaluationSteps |
- This method evaluates the specified expression while recording each step of the evaluation process.- It accepts the same set of parameters as the formatExpression method to define the formatting of each recorded step.- It returns a std::vector<std::string> containing a sequential breakdown of the evaluation procedure. If the expression is invalid prior to evaluation, an empty vector is returned. If an error occurs during evaluation, the returned vector will stop at the last successfull step.- This method does not return an error code. |
evaluateAt |
- This method interprets the specified expression as a function of x .- It accepts a single double parameter representing the value to substitute for x , then evaluates the resulting expression.- The method returns an ExpressionParser::EvaluationResult structure containing the computed double value along with an accompanying error code indicating the evaluation status. |
evaluateAt |
- This overload of the evaluateAt method accepts a single std::vector<double> parameter and evaluates the specified expression as a function of x for each provided value.- If the expression is invalid prior to evaluation, an empty vector is returned. Otherwise, the method returns a std::vector<ExpressionParser::EvaluationSteps> containing the evaluation results corresponding to each input value. |
evaluateAt |
- This overload of the evaluateAt method accepts three double parameters: startValue , endValue , and step .- It evaluates the specified expression as a function of x , beginning with startValue , incrementing by step , and continuing to substitute and evaluate until the value of endValue is reached or exceeded.- If the expression is invalid prior to evaluation, an empty vector is returned. Likewise, if the parameter set is invalid (for example, if startValue is less than endValue while step is negative), the method also returns an empty vector. Otherwise, it returns a std::vector<ExpressionParser::EvaluationSteps> containing the evaluation results for each computed value. |
generateEvaluationStepsAt |
- This method accepts a single double parameter along with the same set of formatting parameters used by the formatExpression method.- It interprets the specified expression as a function of x , substitutes the given value, and returns a std::vector<std::string> representing a sequential breakdown of the evaluation process, with each step formatted according to the provided parameters.- If the expression is invalid prior to evaluation, an empty vector is returned. |
generateEvaluationStepsAt |
- This overload of the generateEvaluationStepsAt method accepts a single std::vector<double> parameter, along with the same set of formatting parameters used by the formatExpression method.- It interprets the specified expression as a function of x , substituting and evaluating it for each value in the vector.- The method returns a std::vector<std::vector<std::string>> , where each inner vector contains the formatted evaluation steps corresponding to each individual input value respectively.- If the expression is invalid prior to evaluation, an empty vector is returned. |
generateEvaluationStepsAt |
- This overload of the generateEvaluationStepsAt method accepts three double parameters: startValue , endValue , and step , in addition to the same set of formatting parameters used by the formatExpression method.- It evaluates the specified expression as a function of x , beginning with startValue , incrementing by step , and continuing to substitute and evaluate until the value of endValue is reached or exceeded.- The method returns a std::vector<std::vector<std::string>> , where each inner vector contains the formatted evaluation steps corresponding to each individual computed value respectively.- If the expression is invalid prior to evaluation, an empty vector is returned. |
Syntax Notes
- Function calls without brackets: The rule is that the argument continues only through implicit multiplication between numeric values and constants. It also extends through chains of exponentiation, as well as nested function calls. In all other cases, the argument is considered to have ended. For example:
Expression | Evaluated as |
---|---|
sin30epi^13^(1+1)(2+2) |
$$\sin(30e\pi^{13^{(1+1)}})\cdot(2+2)$$ |
logasinhsinh4.5(1+1) |
$$\log(\sinh^{-1}(\sinh(4.5)))\cdot(1+1)$$ |
sin30sin60pi(1+1) |
$$\sin(30)\cdot\sin(60\pi)\cdot(1+1)$$ |
- Note that the value of implicitMultHighPrec
doesn’t have an effect here, but you can always use parenthesis to specify exactly what you want.
- Scientific Notation: Using an uppercase
E
does not possess a unique operator precedence. Instead, it is automatically transformed into*10^
during the formatting process, regardless of the expression following. For example:
Expression | Evaluated as |
---|---|
2E+sincos15rnd#-(2/3)e3e |
$$2\times10^{\sin(\cos(15\text{rnd#}))}-\frac{2}{3}\times10^3\times{e}$$ |
17.5eE-rndInt(5,15)^-1-2/3 |
$$17.5e\times10^{-\text{rndInt(5,15)}^{-1}}-\frac{2}{3}=\frac{17.5e}{10^{\frac{1}{\text{rndInt(5,15)}}}}-\frac{2}{3}$$ |
- Parser Formatting vs. Mathematical Formatting: Certain expressions cannot be represented exactly as they appear in standard mathematical notation. The following table outlines the syntax used by the parser alongside their corresponding representations in conventional mathematical form:
Expression | Corresponds To |
---|---|
a^b |
$$a^b$$ |
nPr |
$${}^nP_r, P(n, r)$$ |
nCr |
$$\begin{pmatrix}n\\c\end{pmatrix},{}^nC_r,C(n, r)$$ |
asin(x) , acos(x) , asinh(x) , acosh(x) , etc. |
$$\sin^{-1}(x), \cos^{-1}(x), \sinh^{-1}(x), \cosh^{-1}(x), \text{etc.}$$ |
sqrt(x), cbrt(x), nthrt(x,n) |
$$\sqrt{x},\sqrt[3]{x},\sqrt[n]{x}$$ |
log(a,b) |
$$\log_a(b)$$ |
sum(f(x),a,b) |
$$\sum_{x=a}^b{f(x)}$$ |
prod(f(x),a,b) |
$$\prod_{x=a}^b{f(x)}$$ |
Calculation Priority Sequence
Order | Calculation Type | Examples |
---|---|---|
1 | Parenthetical Expressions: evaluated from the deepest upwards. | (1+1) ,12+(12*(13-25.5)) |
2 | Function Calls: evalulated from left to right. | sin30pi , log(2,13) , rndInt(-10,10) , NOT(-10) |
3 | Factorials (! ) & Percentages (% ): they both bind tighly to what is behind them (as mentioned before). |
25! , 2/5% |
4 | Exponents (^ ): evaluated from right to left when nesting to represent power towers. |
2^3 , 2+3^4^5 |
5 | Unary Minus: when using (- ) to indicate negation rather than subtraction. |
12*-12 , -(11+2) |
6 | Implicit Multiplication (Juxtaposition): this priority only applies if implicitMultHighPrec is set to true . It will have higher precedence than standard left to right evaluation when combined with division. |
12/3(1+1.5) ,-3.14(1+1)(2+2) |
7 | Permutations(P ) & Combinations (C ): evaluated from left to right. |
1+5P2 , 13.5/14C12 |
8 | Multiplication (* ) & Division (/ ): evaluated from left to right. |
1+2*3 , 1/2*3/4/5 |
9 | Addition (+ ) & Subtraction (- ): evaluated from left to right. |
1+12-14 |
10 | Bitwise Shift Operators (<< for left shift), (>> for right shift): evaluated from left to right. |
12+13<<14*12 , 7>>1 |
11 | Comparison Operators (< , > , = , <= , >= ): evaluated from left to right |
1=1 , 4+3<2+1 |
12 | Logical Operators (AND , NAND ): can be used also as bitwise operators if forceBitwiseLogic is set to true —evaluated from left to right. |
1NAND0 , 14AND6 |
13 | Logical Operators (NAND , NOR , XOR , XNOR ): can be used also as bitwise operators if forceBitwiseLogic is set to true —evaluated from left to right. |
1OR0 , 14XNOR6 |
Error Codes
The class supports a comprehensive set of over 40 error codes, which may be triggered if an expression is determined to be invalid prior to evaluation, or if an error occurs during the evaluation process. The following table enumerates all potential issues along with their corresponding error codes and illustrative examples:
Error Code | Description | Examples |
---|---|---|
NO_ERRORS |
Is triggered when the expression is evaluated with no errors whatsover. | 12*(3+4) |
INVALID_IMPLICIT_MULTIPLICATION |
Is triggered when placing a number (or decimal point) directly after a closed bracket, absolute value bar, or after a constant/variable. | (1+1)12.5 , 3.5pi7 |
INVALID_DECIMAL_POINTS |
Is triggered when finding broken/invalid decimal points placements. | 12.4.6 , 3..14 , pi.e |
INVALID_BRACKETS |
Is triggered when the expression contains misbalanced or invalid bracket arrangements. | (1+1))((2+2) , ((13.5+12(14.6)) , 1+()+2 |
INVALID_SCIENTIFIC_NOTATION |
Is triggered when a capital E is preceded by an operator or an open bracket. |
E+3 , 1+(E2) , 2*E3.5) |
INVALID_OPERATOR_PLACEMENT |
Is triggered when two operators are placed next to each other, or when an expression starts with an operator that should have an operand before it. | \pi*/e , 14^(^15) |
INVALID_FUNCTION_ARGUMENTS |
Is triggered when passing an invalid number of arguments to a multi-argument function, or when using invalid arrangements of commas in multi-argument function calls. | log(2,3,4) , prod(,2,3,) |
INVALID_FUNCTION_CALL |
Is triggered when calling a function without passing any arguments, or using multi-argument functions without brackets. | e+csc/12 , 1.5(2E3log) |
INVALID_ABS_BARS |
Is triggered when using an impossible/broken arrangement of vertical bars, or if they cause the expression to be invalid for any other reason after formatting them. | |1+2|3| , 12+|8.12*|3.1|+1|+|12| |
INVALID_EXPRESSION |
Is triggered if the expression was found to be invalid for any other reason. | C , |,12| , 12,,12 , sum(2,x^2,5) , ln,3 |
CANNOT_DIVIDE_BY_ZERO |
Is triggered when reaching a division by zero while evaluating. | 8P(1/(2^3-8)) , sum(1/x,-5,5) |
INVALID_EXPONENTIATION |
Is triggered when reaching an invalid exponentiation operation while evaluating. | (-e)^pi , (-2)^-0.3 , 0^0 |
EVALUATION_OUT_OF_RANGE |
Is triggered when the value 21024 - 1 is exceeded during evaluation. | 2^1024 , 990! |
INVALID_FACTORIAL_INPUT |
Is triggered when using a decimal or negative operand. | 1.5! , (-5)! |
INVALID_PERMUTATIONS_OPERANDS , INVALID_COMBINATIONS_OPERANDS |
Is triggered when using decimal or negative operands with permutations & combinations respectively. It may also be triggered when the first operand is less than the second. | -9.5P5 , 3P6 |
INVALID_BITWISE_LEFT_SHIFT_OPERANDS , INVALID_BITWISE_RIGHT_SHIFT_OPERANDS |
Is triggered when using at least one decimal operand with the left & right shift operators respectively. | 30.4<<3 , 12>>0.2 |
INVALID_BITWISE_NOT_OPERAND |
Is triggered when passing a decimal value into the bitwise NOT function, provided that forceBitwiseLogic is set to true . |
14AND(NOT-4.7) |
INVALID_BITWISE_AND_OPERANDS , INVALID_BITWISE_OR_OPERANDS , INVALID_BITWISE_NAND_OPERANDS , INVALID_BITWISE_NOR_OPERANDS , INVALID_BITWISE_XOR_OPERANDS , INVALID_BITWISE_XNOR_OPERANDS |
Is triggered when using at least one decimal operand with logical AND ,OR ,NAND ,NOR ,XOR , and XNOR respectively, provided that forceBitwiseLogic is set to true . |
1.5eAND18.7 , 42.5XOR-2e |
OUT_OF_DOMAIN_TAN , OUT_OF_DOMAIN_CSC , OUT_OF_DOMAIN_SEC , OUT_OF_DOMAIN_COT , OUT_OF_DOMAIN_ASIN , OUT_OF_DOMAIN_ACOS , OUT_OF_DOMAIN_ACSC , OUT_OF_DOMAIN_ASEC , OUT_OF_DOMAIN_ACOT , OUT_OF_DOMAIN_CSCH , OUT_OF_DOMAIN_COTH , OUT_OF_DOMAIN_ACOSH , OUT_OF_DOMAIN_ATANH , OUT_OF_DOMAIN_ACSCH , OUT_OF_DOMAIN_ASECH , OUT_OF_DOMAIN_ACOTH , OUT_OF_DOMAIN_LOG10 , OUT_OF_DOMAIN_LN , OUT_OF_DOMAIN_SQRT |
Is triggered with tan , csc , sec , cot , asin , acos , acsc , asec , acot , csch , coth , acosh , atanh , acsch , asech , acoth , log (with one argument), ln , and sqrt respectively when the value of the argument falls outside of the accepted domain of the function. |
log-1 , sec(pi/2) (if angleUnit is set to AngleUnits::RADIAN ), sqrt(-2) |
OUT_OF_DOMAIN_LOG |
For the base, it's triggered when the base is non-positve or equal to 1 . For the argument, it's triggered when the argument is non-positive. |
log(-2,5) , log(1,0) , log(e,-4) |
OUT_OF_DOMAIN_NTHRT |
Is triggered when the index is equal to 0 , or the index is even with a negative argument for the ntrht(arg,index) . |
nthrt(-25,2) , nthrt(5,0) |
OUT_OF_DOMAIN_MOD |
Is triggered when passing at least one decimal argument for the mod(a,b) . |
mod(1.5,2) , nthrt(-5,0.1) |
INVALID_SUM_LIMITS , INVALID_PROD_LIMITS |
Is triggered if at least one of the limits is decimal or if the second limit is less than the first for sum(expr,a,b) , and prod(expr,a,b) respectively. |
sum(2x,-2.5,5) , prod(2x,20,15) |
Conclusion
The ExpressionParser
project is a testament to meticulous software design and a deep understanding of string manipulation/parsing algorithms. It successfully creates a feature-rich, reliable, and easy-to-integrate C++ library for a wide range of mathematical and logical tasks. This project showcases advanced skills in C++ development, object-oriented design, algorithm implementation, and robust error handling. Potential future enhancements could include support for user-defined variables and functions to further extend its scripting capabilities.
How to Use
- Download the header file from the section below.
- Include it in your C++ project using
#include "..."
, with the appropriate path between the double quotes.
Source Code
You can find the source code for this header here.