#include "zavorky.h"
std::string remove_parantheses(const std::string& line);
std::string parse_line(const std::string& line); //purges whitespace
int process_line(const std::string& in_line)
{
std::string line = parse_line(in_line);
std::string outline = remove_parantheses(line);
std::cout << outline << std::endl;
return 0;
}
std::string parse_line(const std::string& line) //purges whitespace
{
std::string outline = "";
for (size_t i = 0; i < line.size(); i++)
{
if (isdigit(line[i])) return ""; // no numerals allowed
if (!isspace(line[i])) // no spaces
{
outline += line[i];
}
}
return outline;
}
bool is_mono(const std::string& expr) // is monolithic bloc
{
// a*b/c is ok
// a+b/c is not
// but a*(b+c)*d is also
int par_lvl = 0;
if (expr[0] == '/')
{
return false;
}
for (size_t i = 1; i < expr.size(); i++)
{
char znak = expr[i];
if ((znak == '+' or znak == '-') and par_lvl <= 1)
{
return false;
}
if (znak == '(')
{
par_lvl++;
}
if (znak == ')')
{
par_lvl--;
}
}
return true;
}
std::string remove_parantheses(const std::string& line)
{
// go through line and find redundant parantheses
int par_lvl = 0;
int max_par_lvl = 0;
std::string out_string = line;
std::string wip_string = "";
while (out_string != wip_string) // i might have to remove in waves
{
wip_string = out_string;
out_string = "";
std::vector<bool> purge_param;
std::vector<size_t> param_beg;
// first go through file and find redundant parantheses
for (size_t i = 0; i < wip_string.size(); i++)
{
if (wip_string[i] == '(')
{
bool purge;
if (i == 0) // opening parantheses at the beginning
{
purge = true; // redundant parantheses
}// i = 0
else
{
if (wip_string[i - 1] == '+')
{
purge = true; // + before parantheses => redundant
}
else
{
purge = false; // *,-,/ before parantheses => important
}
if (isalnum(wip_string[i-1]))
{
return ""; // variable without operation in front of bracket
}
} // i != 0
if (par_lvl < max_par_lvl) // if on already visited level, just modify parameters
{
purge_param[par_lvl] = purge;
param_beg[par_lvl] = i;
}
else // if on new level, pushback
{
purge_param.push_back(purge);
param_beg.push_back(i);
}
par_lvl++;
max_par_lvl++;
} // char = (
if (wip_string[i] == ')') // closing parantheses
{
par_lvl--;
if (par_lvl < 0) // mismatched parantheses
{
return "";
}
if (i == wip_string.size() - 1) // closing at the end of line
{
purge_param[par_lvl] = purge_param[par_lvl] and true;
}
else
{
if (wip_string[i + 1] == '+' or wip_string[i + 1] == '-' or wip_string[i + 1] == ')')
{
purge_param[par_lvl] = purge_param[par_lvl] and true;
}
else
{
purge_param[par_lvl] = false;
}
if (isalnum(wip_string[i+1]))
{
return "";
}
}
// if the expression in the parantheses is a bloc (a*b/c*d) then i can remove them independently
std::string expr;
size_t beg_of_purge_param = param_beg[par_lvl];
if (beg_of_purge_param == 0)
{
expr = wip_string.substr(beg_of_purge_param, i - beg_of_purge_param);
}
else
{
expr = wip_string.substr(beg_of_purge_param - 1, i - beg_of_purge_param);
}
purge_param[par_lvl] = purge_param[par_lvl] or is_mono(expr);
if (purge_param[par_lvl]) // remove parantheses, replace strings with new version and move iterator to new position
{
std::string pre_par = wip_string.substr(0, beg_of_purge_param); //before parntheses
std::string par_con = wip_string.substr(beg_of_purge_param + 1, i - beg_of_purge_param - 1); // expression in parantheses
std::string post_par = wip_string.substr(i + 1); //after parantheses
out_string = pre_par + par_con + post_par;
wip_string = out_string;
i -= 2; // removed opening and closing bracket, so move iterator two steps back
}
} // char = )
if (out_string == "") // if nothing was removed, exit on while condition
{
out_string = wip_string;
}
} // find redundancy
if (par_lvl != 0) //mismatched parantheses
{
return "";
}
}
return out_string;
}