Error in Lexing a Mathematical Equation

Asked

Viewed 68 times

3

I’m doing a C++ equation interpreter and I’m trying to show the type of the symbol. But I’m in trouble. I don’t know what’s wrong.

Any constructive tips are welcome.

main.cpp:

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

//disables any deprecation warning
#pragma warning(disable : 4996)

//usings
using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::stringstream;

bool try_parse(const std::string& s)
{
    char* end = 0;
    double val = strtod(s.c_str(), &end);
    return end != s.c_str() && val != HUGE_VAL;
}

char first_char(string str) {
    return *str.c_str();
}


vector<string> tok_type(vector<string> vec) {
    for (int i = 0; i < vec.size(); i++) {
        string &s = vec[i];
        if (!try_parse(s) || first_char(s) != '&') {
            s = "<unknown> " + s;
            continue;
        }
        else if(!try_parse(s) || first_char(s) == '&'){
            s = "<operator> " + s;
            continue;
        }
        else if (try_parse(s) || first_char(s) != '&') {
            s = "<double> " + s;
            continue;
        }
    }
    return vec;
}

long double parse(string str) {
    return std::stold(str);
}

vector<string> split(string str, string token = " ") {
    vector<string>result;
    while (str.size()) {
        int index = str.find(token);
        if (index != string::npos) {
            result.push_back(str.substr(0, index));
            str = str.substr(index + token.size());
            if (str.size() == 0)result.push_back(str);
        }
        else {
            result.push_back(str);
            str = "";
        }
    }
    return result;
}

string simplify(string expr) {
    string iexpr = expr;
    for (int i = 0; i < iexpr.length(); i++) {

        char& c = iexpr[i];

        if (c == '+')
            iexpr.replace(i, 1, " &ad ");
        else if (c == '-')
            iexpr.replace(i, 1, " &sb ");
        else if (c == '*') 
            iexpr.replace(i, 1, " &mp ");
        else if (c == '/')
            iexpr.replace(i, 1, " &dv ");

    }
    return iexpr;
}

int main() {
    vector<string> sep_rep = tok_type(split(simplify("21+32-3*2")));
    for (auto str : sep_rep) {
        cout << str << endl;
    }

    std::cin.get();
    return 0;
}

The way out is:

<double>21
<operator>&ad
<double>32
<operator>&sb
<double>3
<operator>&mp
<double>2 

But that’s the one I get...

<unknown>21
<unknown>&ad
<unknown>32
<unknown>&sb
<unknown>3
<unknown>&mp
<unknown>2
  • Already tested the function try_parse separately? Something bothers me about her.

  • If the answer below solved your problem and there was no doubt left, mark it as correct/accepted by clicking on the " " that is next to it, which also marks your question as solved. If you still have any questions or would like further clarification, feel free to comment.

  • Worked !!!!!!!!

1 answer

3

Your mistake is silly. In the parts where you have try_parse(s) and first_char(s), you used || when you should use &&.

I also recommend storing the results of try_parse(s) and first_char(s) in a variable of type bool not to keep calling these methods up to three times to the same string.

In my case, I also had to add a #include <cmath> to compile.

See here working on ideone.

  • I was intrigued by cmath... what definition you needed for this header?

  • 1

    @Jeffersonquesado is the HUGE_VAL who needs <cmath>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.