Skip to main content
Became Hot Network Question
Tweeted twitter.com/StackCodeReview/status/1351182598966554638
Minor copy-editing
Source Link
Toby Speight
  • 81.8k
  • 14
  • 101
  • 309

C++ Simple equation Parserparser and evaluator

I am relatively new to C++ coming formfrom languages such as Java and would like tips to make my code more C++ like and doing things in the C++ way.

The header file:

Many thanks

C++ Simple equation Parser

I am relatively new to C++ coming form languages such as Java and would like tips to make my code more C++ like and doing things in the C++ way.

The header file

Many thanks

Simple equation parser and evaluator

I am relatively new to C++ coming from languages such as Java and would like tips to make my code more C++ like and doing things in the C++ way.

The header file:

Source Link

C++ Simple equation Parser

I am relatively new to C++ coming form languages such as Java and would like tips to make my code more C++ like and doing things in the C++ way.

The header file

#pragma once

#include <string>
#include <memory>

class Expression
{
public:
    std::string symbol;
    std::shared_ptr<Expression> left;
    std::shared_ptr<Expression> right;

    float eval();
    static Expression parse(std::string s);

private:
    Expression(std::string symbol, Expression *left, Expression *right);
    static Expression parseRec(std::string s);
    static float evalRec(const Expression &e);
};

cpp file:

#include "Expression.hpp"
#include <unordered_map>

Expression::Expression(std::string symbol, Expression *left, Expression *right)
    : symbol(symbol), left(left), right(right) {}

float Expression::eval()
{
    return Expression::evalRec(*this);
}

float Expression::evalRec(const Expression &e)
{
    switch (e.symbol[0])
    {
    case '+':
        return evalRec(*e.left) + evalRec(*e.right);
    case '-':
        return evalRec(*e.left) - evalRec(*e.right);
    case '*':
        return evalRec(*e.left) * evalRec(*e.right);
    case '/':
        return evalRec(*e.left) / evalRec(*e.right);
    default:
        return std::stoi(e.symbol);
    }
}

Expression Expression::parse(std::string s)
{
    //Remove whitespace
    std::string output;
    for (auto &i : s)
    {
        if (i != ' ')
            output += i;
    }
    return parseRec(output);
}

Expression Expression::parseRec(std::string s)
{
    const std::unordered_map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 10}, {'/', 10}};
    int indexOfLowest = -1;
    int i = 0;
    for (auto &&j : s)
    {
        switch (j)
        {
        case '+':
        case '-':
        case '*':
        case '/':
            if (indexOfLowest == -1)
                indexOfLowest = i;
            else if (precedence.at(j) <= precedence.at(s[indexOfLowest]))
                indexOfLowest = i;
            break;
        default:
            break;
        }
        i++;
    }
    if (indexOfLowest == -1)
    {
        return Expression(s, NULL, NULL);
    }
    else
    {
        return Expression(std::string(1, s[indexOfLowest]),
                          new Expression(parseRec(s.substr(0, indexOfLowest))),
                          new Expression(parseRec(s.substr(indexOfLowest + 1, s.length() - indexOfLowest - 1))));
    }
}

and a simple main:

#include <iostream>
#include "Expression.hpp"

int main(int argc, char const *argv[])
{
    //Parsed expression tree
    Expression e = Expression::parse("5 + 10 * 2 + 6 / 3");
    std::cout << e.eval() << std::endl;
    return 0;
}

Many thanks