1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 24 *
* Author: Arash Partow (1999-2024) *
* URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
* https://www.opensource.org/licenses/MIT *
* SPDX-License-Identifier: MIT *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template <typename T, T Process(const unsigned char)>
struct char_process : public exprtk::igeneric_function<T>
{
typedef typename exprtk::igeneric_function<T> igfun_t;
typedef typename igfun_t::parameter_list_t parameter_list_t;
typedef typename igfun_t::generic_type generic_type;
typedef typename generic_type::string_view string_t;
using exprtk::igeneric_function<T>::operator();
char_process()
: exprtk::igeneric_function<T>("S")
{}
inline T operator()(parameter_list_t parameters)
{
const unsigned char c = string_t(parameters[0])[0];
return Process(c);
}
};
template <typename T>
T is_digit_func(const unsigned char c)
{
return (('0' <= c) && (c <= '9')) ? T(1) : T(0);
}
template <typename T>
T to_num_func(const unsigned char c)
{
return static_cast<T>(c - '0');
}
template <typename T>
void rpn_example()
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
const std::string rpn_program =
" var stack[1000] := [0]; "
" var stack_size := 0; "
" "
" for (var i := 0; i < rpn_expression[]; i += 1) "
" { "
" var c := rpn_expression[i : i + 1]; "
" "
" if (c == ' ') "
" { "
" continue; "
" } "
" else if (is_digit(c)) "
" { "
" stack[stack_size] := to_num(c); "
" stack_size += 1; "
" } "
" else "
" { "
" var operator := c; "
" var operand1 := stack[stack_size - 2]; "
" var operand2 := stack[stack_size - 1]; "
" stack_size -= 2; "
" "
" switch "
" { "
" case operator == '+' : stack[stack_size] := operand1 + operand2; "
" case operator == '-' : stack[stack_size] := operand1 - operand2; "
" case operator == '*' : stack[stack_size] := operand1 * operand2; "
" case operator == '/' : stack[stack_size] := operand1 / operand2; "
" case operator == '^' : stack[stack_size] := operand1 ^ operand2; "
" }; "
" "
" stack_size += 1; "
" } "
" }; "
" "
" println(stack[0], ' = ', rpn_expression); "
" ";
std::string rpn_expression;
char_process<T,is_digit_func<T>> isdigit;
char_process<T,to_num_func<T>> tonum;
exprtk::rtl::io::println<T> println;
symbol_table_t symbol_table;
symbol_table.add_stringvar("rpn_expression", rpn_expression);
symbol_table.add_function ("println" , println );
symbol_table.add_function ("is_digit" , isdigit );
symbol_table.add_function ("to_num" , tonum );
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
parser.compile(rpn_program, expression);
const std::string rpn_expressions[] =
{
"2 3 8 / ^ 4 6 * + 3 9 / -", // 2 ^ (3 / 8) + 4 * 6 - 3 / 9
"1 2 / 6 5 2 - / * 7 +" , // (1 / 2) * (6 / (5 - 2)) + 7
"1 2 * 3 / 4 * 5 / 6 *" , // ((((1 * 2) / 3) * 4) / 5) * 6
"8 6 4 + * 2 /" // (8 * (6 + 4)) / 2
};
for (std::size_t i = 0; i < sizeof(rpn_expressions) / sizeof(std::string); ++i)
{
rpn_expression = rpn_expressions[i];
expression.value();
}
}
int main()
{
rpn_example<double>();
return 0;
}
|