Skip to content

Commit c6f41be

Browse files
committed
add postfix operations support
1 parent 9eb23a9 commit c6f41be

File tree

5 files changed

+55
-31
lines changed

5 files changed

+55
-31
lines changed

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ int main() {
2525
double result = parser.evaluate("2 + 2 * 2"); // 6
2626

2727
// Add custom operator
28-
parser.registerOperator("max", parser::Operator{
29-
parser::Operator::Type::FUNCTION,
30-
4, false, 2,
28+
parser.registerOperator("max", MathParser::Operator{
29+
MathParser::Operator::Type::FUNCTION,
30+
4, false, false, 2,
3131
[&](auto args) {
3232
// this function convert token to double, according of its type
3333
double left = parser.tokenToDouble(args[0]);
3434
double right = parser.tokenToDouble(args[1]);
35-
return Token{MathParser::Token::Type::NUMBER, std::max(left, right)};
35+
return MathParser::Token{MathParser::Token::Type::NUMBER, std::max(left, right)};
3636
},
3737
"max"
3838
});
@@ -56,16 +56,17 @@ int main() {
5656
### Adding Custom Function or Operator
5757
```cpp
5858
// Register logarithmic function
59-
parser.registerOperator("log", parser::Operator{
59+
parser.registerOperator("!", parser::Operator{
6060
parser::Operator::Type::FUNCTION,
6161
4, // Precedence
6262
false, // Right associativity
63+
true, // Postfix operator
6364
1, // Single argument
6465
[](auto args) {
6566
double arg = parser.tokenToDouble(args[0]);
66-
return MathParser::Token{MathParser::Token::Type::NUMBER, std::log(arg)};
67+
return MathParser::Token{MathParser::Token::Type::NUMBER, std::tgamma(arg+1)};
6768
}, // Evaluating function
68-
"log" // Function name
69+
"!" // Function name
6970
});
7071
```
7172

include/mathparser.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class MathParser {
4444
Type type;
4545
int precedence;
4646
bool isRightAssociative;
47+
bool isPostfix;
4748
int operandCount;
4849
EvaluateFunc evaluate;
4950
std::string symbol;

src/main.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
#include "mathparser.hpp"
2-
#include <iostream>
32

43
int main() {
5-
MathParser math;
6-
std::cout<<math.evaluate("x=5")<<'\n';
7-
std::cout<<math.evaluate("y=7")<<'\n';
8-
std::cout<<math.evaluate("x = x+y+1")<<'\n';
9-
std::cout<<math.evaluate("variable = x - y")<<'\n';
10-
std::cout<<math.getVariableValue("variable");
4+
MathParser parser;
5+
6+
// Evaluate simple expression
7+
double result = parser.evaluate("2 + 2 * 2"); // 6
8+
9+
// Add custom operator
10+
parser.registerOperator("max", MathParser::Operator{
11+
MathParser::Operator::Type::FUNCTION,
12+
4, false, false, 2,
13+
[&](auto args) {
14+
// this function convert token to double, according of its type
15+
double left = parser.tokenToDouble(args[0]);
16+
double right = parser.tokenToDouble(args[1]);
17+
return MathParser::Token{MathParser::Token::Type::NUMBER, std::max(left, right)};
18+
},
19+
"max"
20+
});
21+
22+
// Evaluate custom function
23+
result = parser.evaluate("max(2-2*2, 2^2-1)"); // 3
24+
25+
//Variables
26+
parser.evaluate("x = 3"); // 3
27+
parser.evaluate("y = 42"); // 42
28+
parser.evaluate("x = x + 10"); // 13
29+
parser.evaluate("var = y - x"); // 29
30+
parser.getVariableValue("var"); // 29
31+
1132
return 0;
1233
}

src/mathparser.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void MathParser::init() {
1919
// Добавить в init():
2020
registerOperator("=", {
2121
Operator::Type::BINARY,
22-
0, false, 2,
22+
0, false, false, 2,
2323
[this](auto args) {
2424
if (args[0].type != Token::Type::VARIABLE)
2525
throw std::runtime_error("Left operand must be a variable");
@@ -35,23 +35,23 @@ registerOperator("=", {
3535
});
3636
registerOperator("(", {
3737
Operator::Type::BRACKET,
38-
0, false, 0, nullptr, "("
38+
0, false, false, 0, nullptr, "("
3939
});
4040

4141
registerOperator(")", {
4242
Operator::Type::BRACKET,
43-
0, false, 0, nullptr, ")"
43+
0, false, false, 0, nullptr, ")"
4444
});
4545

4646
registerOperator(",", {
4747
Operator::Type::COMMA,
48-
0, false, 0, nullptr,
48+
0, false, false, 0, nullptr,
4949
","
5050
});
5151

5252
registerOperator("+", {
5353
Operator::Type::BINARY,
54-
1, false, 2,
54+
1, false, false, 2,
5555
[this](auto args) {
5656
double left = tokenToDouble(args[0]);
5757
double right = tokenToDouble(args[1]);
@@ -62,7 +62,7 @@ registerOperator("=", {
6262

6363
registerOperator("-", {
6464
Operator::Type::BINARY,
65-
1, false, 2,
65+
1, false, false, 2,
6666
[this](auto args) {
6767
double left = tokenToDouble(args[0]);
6868
double right = tokenToDouble(args[1]);
@@ -73,7 +73,7 @@ registerOperator("=", {
7373

7474
registerOperator("*", {
7575
Operator::Type::BINARY,
76-
2, false, 2,
76+
2, false, false, 2,
7777
[this](auto args) {
7878
double left = tokenToDouble(args[0]);
7979
double right = tokenToDouble(args[1]);
@@ -84,7 +84,7 @@ registerOperator("=", {
8484

8585
registerOperator("/", {
8686
Operator::Type::BINARY,
87-
2, false, 2,
87+
2, false, false, 2,
8888
[this](auto args) {
8989
double left = tokenToDouble(args[0]);
9090
double right = tokenToDouble(args[1]);
@@ -96,7 +96,7 @@ registerOperator("=", {
9696

9797
registerOperator("^", {
9898
Operator::Type::BINARY,
99-
4, true, 2,
99+
4, true, false, 2,
100100
[this](auto args) {
101101
double left = tokenToDouble(args[0]);
102102
double right = tokenToDouble(args[1]);
@@ -107,7 +107,7 @@ registerOperator("=", {
107107

108108
registerOperator("~", {
109109
Operator::Type::UNARY,
110-
3, true, 1,
110+
3, true, false, 1,
111111
[this](auto args) {
112112
double arg = tokenToDouble(args[0]);
113113
return Token{Token::Type::NUMBER, -arg};
@@ -117,7 +117,7 @@ registerOperator("=", {
117117

118118
registerOperator("sqrt", {
119119
Operator::Type::FUNCTION,
120-
5, false, 1,
120+
5, false, false, 1,
121121
[this](auto args) {
122122
double arg = tokenToDouble(args[0]);
123123
return Token{Token::Type::NUMBER, sqrt(arg)};
@@ -126,7 +126,7 @@ registerOperator("=", {
126126
});
127127
registerOperator("sin", {
128128
Operator::Type::FUNCTION,
129-
5, false, 1,
129+
5, false, false, 1,
130130
[this](auto args) {
131131
double arg = tokenToDouble(args[0]);
132132
return Token{Token::Type::NUMBER, sin(arg)};
@@ -135,7 +135,7 @@ registerOperator("=", {
135135
});
136136
registerOperator("cos", {
137137
Operator::Type::FUNCTION,
138-
5, false, 1,
138+
5, false, false, 1,
139139
[this](auto args) {
140140
double arg = tokenToDouble(args[0]);
141141
return Token{Token::Type::NUMBER, cos(arg)};
@@ -144,7 +144,7 @@ registerOperator("=", {
144144
});
145145
registerOperator("tan", {
146146
Operator::Type::FUNCTION,
147-
5, false, 1,
147+
5, false, false, 1,
148148
[this](auto args) {
149149
double arg = tokenToDouble(args[0]);
150150
return Token{Token::Type::NUMBER, tan(arg)};
@@ -267,7 +267,8 @@ std::vector<MathParser::Token> MathParser::toRPN(const std::string& expression)
267267
RPN.push_back(Token{Token::Type::OPERATOR,topOp.symbol});
268268
}
269269
opStack.push(curOp);
270-
expectOperand = true;
270+
if (curOp.isPostfix) expectOperand = false;
271+
else expectOperand = true;
271272
i++;
272273
}
273274
}

tests/test_mathparser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ int main() {
1818

1919
mathParser.registerOperator("max", MathParser::Operator{
2020
MathParser::Operator::Type::FUNCTION,
21-
4, false, 2,
21+
4, false, false, 2,
2222
[&](auto args) {
2323
double left = mathParser.tokenToDouble(args[0]);
2424
double right = mathParser.tokenToDouble(args[1]);
@@ -27,7 +27,7 @@ int main() {
2727
"max"
2828
});
2929

30-
test(mathParser.evaluate("---4.2")==-4.2, "---4.2 == -4.2");
30+
test(mathParser.evaluate("-~-4.2")==-4.2, "---4.2 == -4.2");
3131
test(mathParser.evaluate("-1-2-3")==-6, "-1-2-3 == -6");
3232
test(mathParser.evaluate("2.1+4.5")==6.6, "2.1 + 4.5 == 6.6");
3333
test(mathParser.evaluate(" 2 +2 * 2 ")==6, "2 + 2 * 2 == 6");

0 commit comments

Comments
 (0)