Advertisement
pablo7890

Math Parser FINAL VERSION :D

Apr 26th, 2013
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.16 KB | None | 0 0
  1. #include <cstdlib>
  2. #include <cstdio>
  3. #include <string>
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <algorithm>
  7. #include <cstdarg>
  8. #include <cstring>
  9. #include <cctype>
  10. #include <cmath>
  11. #include <vector>
  12. using namespace std;
  13.  
  14. const int NAME_LEN_MAX = 30;
  15. const int EXPR_LEN_MAX = 1001;
  16. const int ERR_LEN_MAX = 255;
  17.  
  18. void toupper(char upper[], const char str[]);
  19. class Variablelist {
  20.     public:
  21.         bool exist(const char* name);
  22.         bool add(const char* name, double value);
  23.         bool del(const char* name);
  24.  
  25.         bool get_value(const char* name, double* value);
  26.         bool get_value(const int id, double* value);
  27.         int  get_id(const char* name);
  28.         bool set_value(const char* name, const double value);
  29.  
  30.     private:
  31.         struct VAR
  32.         {
  33.             char name[NAME_LEN_MAX+1];
  34.             double value;
  35.         };
  36.  
  37.         vector<VAR> var;
  38. };
  39.  
  40. class Error {
  41.     public:
  42.         Error(const int row, const int col, const int id, ...);
  43.  
  44.         int get_row() {return err_row;} // Returns the row of the error
  45.         int get_col() {return err_col;} // Returns the column of the error
  46.         int get_id() {return err_id;}   // Returns the id of the error
  47.         char* get_msg() {return msg;}   // Returns a pointer to the error msg
  48.  
  49.     private:
  50.         int err_row;    // row where the error occured
  51.         int err_col;    // column (position) where the error occured
  52.         int err_id;     // id of the error
  53.         char msg[255];
  54.  
  55.         const char* msgdesc(const int id);
  56. };
  57.  
  58.  
  59. double factorial(double value);
  60. double sign(double value);
  61.  
  62.  
  63. class Parser
  64. {
  65.     // public functions
  66.     public:
  67.         Parser();
  68.         char* parse(const char expr[]);
  69.  
  70.     // enumerations
  71.     private:
  72.  
  73.         enum TOKENTYPE {NOTHING = -1, DELIMETER, NUMBER, VARIABLE, FUNCTION, UNKNOWN};
  74.  
  75.         enum OPERATOR_ID {AND, OR, BITSHIFTLEFT, BITSHIFTRIGHT,                 // level 2
  76.                        EQUAL, UNEQUAL, SMALLER, LARGER, SMALLEREQ, LARGEREQ,    // level 3
  77.                        PLUS, MINUS,                     // level 4
  78.                        MULTIPLY, DIVIDE, MODULUS, XOR,  // level 5
  79.                        POW,                             // level 6
  80.                        FACTORIAL};                      // level 7
  81.  
  82.     // data
  83.     private:
  84.         char expr[EXPR_LEN_MAX+1];    // holds the expression
  85.         char* e;                      // points to a character in expr
  86.  
  87.         char token[NAME_LEN_MAX+1];   // holds the token
  88.         TOKENTYPE token_type;         // type of the token
  89.  
  90.         double ans;                   // holds the result of the expression
  91.         char ans_str[255];            // holds a string containing the result
  92.                                       // of the expression
  93.  
  94.         Variablelist user_var;        // list with variables defined by user
  95.  
  96.     // private functions
  97.     private:
  98.         void getToken();
  99.  
  100.         double parse_level1();
  101.         double parse_level2();
  102.         double parse_level3();
  103.         double parse_level4();
  104.         double parse_level5();
  105.         double parse_level6();
  106.         double parse_level7();
  107.         double parse_level8();
  108.         double parse_level9();
  109.         double parse_level10();
  110.         double parse_number();
  111.  
  112.         int get_operator_id(const char op_name[]);
  113.         double eval_operator(const int op_id, const double &lhs, const double &rhs);
  114.         double eval_function(const char fn_name[], const double &value);
  115.         double eval_variable(const char var_name[]);
  116.  
  117.         int row();
  118.         int col();
  119. };
  120.  
  121. double factorial(double value)
  122. {
  123.     double res;
  124.     int v = static_cast<int>(value);
  125.  
  126.     if (value != static_cast<double>(v))
  127.     {
  128.         throw Error(-1, -1, 400, "factorial");
  129.     }
  130.  
  131.     res = v;
  132.     v--;
  133.     while (v > 1)
  134.     {
  135.         res *= v;
  136.         v--;
  137.     }
  138.  
  139.     if (res == 0) res = 1;        // 0! is per definition 1
  140.     return res;
  141. }
  142.  
  143. double sign(double value)
  144. {
  145.     if (value > 0) return 1;
  146.     if (value < 0) return -1;
  147.     return 0;
  148. }
  149.  
  150.  
  151. Error::Error(const int row, const int col, const int id, ...)
  152. : err_row(row), err_col(col), err_id(id)
  153. {
  154.     //sprintf(msg, msgdesc(id));
  155.     const char* msg_desc = msgdesc(id);
  156.  
  157.     va_list args;
  158.     va_start(args, msg_desc);
  159.     vsnprintf(msg, sizeof(msg)-1, msg_desc, args);
  160.     msg[sizeof(msg)-1] = '\0';
  161.     va_end(args);
  162. }
  163.  
  164. const char* Error::msgdesc(const int id)
  165. {
  166.     switch (id)
  167.     {
  168.         // syntax errors
  169.         case 1: return "error";
  170.         case 2: return "error";
  171.         case 3: return "error";
  172.         case 4: return "error";
  173.         case 5: return "error";
  174.         case 6: return "error";
  175.         case 7: return "error";
  176.  
  177.         // wrong or unknown operators, functions, variables
  178.         case 101: return "error";
  179.         case 102: return "error";
  180.         case 103: return "error";
  181.  
  182.         // domain errors
  183.         case 200: return "error";
  184.  
  185.         // error in assignments of variables
  186.         case 300: return "error";
  187.  
  188.         // error in functions
  189.         case 400: return "error";
  190.     }
  191.  
  192.     return "error";
  193. }
  194.  
  195. Parser::Parser()
  196. {
  197.     expr[0] = '\0';
  198.     e = NULL;
  199.  
  200.     token[0] = '\0';
  201.     token_type = NOTHING;
  202. }
  203.  
  204. char* Parser::parse(const char new_expr[])
  205. {
  206.     try
  207.     {
  208.         // check the length of expr
  209.         if ((int)strlen(new_expr) > EXPR_LEN_MAX)
  210.         {
  211.             throw Error(row(), col(), 200);
  212.         }
  213.  
  214.         // initialize all variables
  215.         strncpy(expr, new_expr, EXPR_LEN_MAX - 1);  // copy the given expression to expr
  216.         e = expr;                                  // let e point to the start of the expression
  217.         ans = 0;
  218.  
  219.         getToken();
  220.         if (token_type == DELIMETER && *token == '\0')
  221.         {
  222.             throw Error(row(), col(), 4);
  223.         }
  224.  
  225.         ans = parse_level1();
  226.  
  227.         // check for garbage at the end of the expression
  228.         // an expression ends with a character '\0' and token_type = delimeter
  229.         if (token_type != DELIMETER || *token != '\0')
  230.         {
  231.             if (token_type == DELIMETER)
  232.             {
  233.                 // user entered a not existing operator like "//"
  234.                 throw Error(row(), col(), 101, token);
  235.             }
  236.             else
  237.             {
  238.                 throw Error(row(), col(), 5, token);
  239.             }
  240.         }
  241.  
  242.         // add the answer to memory as variable "Ans"
  243.         user_var.add("Ans", ans);
  244.  
  245.       //snprintf(ans_str, sizeof(ans_str), "Ans = %g", ans);
  246.         snprintf(ans_str, sizeof(ans_str), "%g", ans);
  247.     }
  248.     catch (Error err)
  249.     {
  250.         if (err.get_row() == -1)
  251.         {
  252. //            snprintf(ans_str, sizeof(ans_str), "Error: %s (col %i)", err.get_msg(), err.get_col());
  253.             snprintf(ans_str, sizeof(ans_str), "error", err.get_msg(), err.get_col());
  254.         }
  255.         else
  256.         {
  257. //            snprintf(ans_str, sizeof(ans_str), "Error: %s (ln %i, col %i)", err.get_msg(), err.get_row(), err.get_col());
  258.             snprintf(ans_str, sizeof(ans_str), "error", err.get_msg(), err.get_row(), err.get_col());
  259.         }
  260.     }
  261.  
  262.     return ans_str;
  263. }
  264.  
  265. bool isMinus(const char c)
  266. {
  267.     if (c == 0) return 0;
  268.     return c == '-';
  269. }
  270.  
  271. bool isWhiteSpace(const char c)
  272. {
  273.     if (c == 0) return 0;
  274.     return c == 32 || c == 9;  // space or tab
  275. }
  276.  
  277. bool isDelimeter(const char c)
  278. {
  279.     if (c == 0) return 0;
  280.     return strchr("&|<>=+/*%^!", c) != 0;
  281. }
  282.  
  283. bool isNotDelimeter(const char c)
  284. {
  285.     if (c == 0) return 0;
  286.     return strchr("&|<>=+-/*%^!()", c) != 0;
  287. }
  288.  
  289. bool isAlpha(const char c)
  290. {
  291.     if (c == 0) return 0;
  292.     return strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ_", toupper(c)) != 0;
  293. }
  294.  
  295. bool isDigitDot(const char c)
  296. {
  297.     if (c == 0) return 0;
  298.     return strchr("0123456789.", c) != 0;
  299. }
  300.  
  301. bool isDigit(const char c)
  302. {
  303.     if (c == 0) return 0;
  304.     return strchr("0123456789", c) != 0;
  305. }
  306.  
  307. void Parser::getToken()
  308. {
  309.     token_type = NOTHING;
  310.     char* t;           // points to a character in token
  311.     t = token;         // let t point to the first character in token
  312.     *t = '\0';         // set token empty
  313.  
  314.     //printf("\tgetToken e:{%c}, ascii=%i, col=%i\n", *e, *e, e-expr);
  315.  
  316.     // skip over whitespaces
  317.     while (*e == ' ' || *e == '\t')     // space or tab
  318.     {
  319.         e++;
  320.     }
  321.  
  322.     // check for end of expression
  323.     if (*e == '\0')
  324.     {
  325.         // token is still empty
  326.         token_type = DELIMETER;
  327.         return;
  328.     }
  329.  
  330.     // check for minus
  331.     if (*e == '-')
  332.     {
  333.         token_type = DELIMETER;
  334.         *t = *e;
  335.         e++;
  336.         t++;
  337.         *t = '\0';  // add a null character at the end of token
  338.         return;
  339.     }
  340.  
  341.     // check for parentheses
  342.     if (*e == '(' || *e == ')')
  343.     {
  344.         token_type = DELIMETER;
  345.         *t = *e;
  346.         e++;
  347.         t++;
  348.         *t = '\0';
  349.         return;
  350.     }
  351.  
  352.     // check for operators (delimeters)
  353.     if (isDelimeter(*e))
  354.     {
  355.         token_type = DELIMETER;
  356.         while (isDelimeter(*e))
  357.         {
  358.             *t = *e;
  359.             e++;
  360.             t++;
  361.         }
  362.         *t = '\0';  // add a null character at the end of token
  363.         return;
  364.     }
  365.  
  366.     // check for a value
  367.     if (isDigitDot(*e))
  368.     {
  369.         token_type = NUMBER;
  370.         while (isDigitDot(*e))
  371.         {
  372.             *t = *e;
  373.             e++;
  374.             t++;
  375.         }
  376.  
  377.         // check for scientific notation like "2.3e-4" or "1.23e50"
  378.         if (toupper(*e) == 'E')
  379.         {
  380.             *t = *e;
  381.             e++;
  382.             t++;
  383.  
  384.             if (*e == '+' || *e == '-')
  385.             {
  386.                 *t = *e;
  387.                 e++;
  388.                 t++;
  389.             }
  390.  
  391.             while (isDigit(*e))
  392.             {
  393.                 *t = *e;
  394.                 e++;
  395.                 t++;
  396.             }
  397.         }
  398.  
  399.         *t = '\0';
  400.         return;
  401.     }
  402.  
  403.     // check for variables or functions
  404.     if (isAlpha(*e))
  405.     {
  406.         while (isAlpha(*e) || isDigit(*e))
  407.         //while (isNotDelimeter(*e))
  408.         {
  409.             *t = *e;
  410.             e++;
  411.             t++;
  412.         }
  413.         *t = '\0';  // add a null character at the end of token
  414.  
  415.         // check if this is a variable or a function.
  416.         // a function has a parentesis '(' open after the name
  417.         char* e2 = NULL;
  418.         e2 = e;
  419.  
  420.         // skip whitespaces
  421.         while (*e2 == ' ' || *e2 == '\t')     // space or tab
  422.         {
  423.             e2++;
  424.         }
  425.  
  426.         if (*e2 == '(')
  427.         {
  428.             token_type = FUNCTION;
  429.         }
  430.         else
  431.         {
  432.             token_type = VARIABLE;
  433.         }
  434.         return;
  435.     }
  436.  
  437.     // something unknown is found, wrong characters -> a syntax error
  438.     token_type = UNKNOWN;
  439.     while (*e != '\0')
  440.     {
  441.         *t = *e;
  442.         e++;
  443.         t++;
  444.     }
  445.     *t = '\0';
  446.     throw Error(row(), col(), 1, token);
  447.  
  448.     return;
  449. }
  450.  
  451. double Parser::parse_level1()
  452. {
  453.     if (token_type == VARIABLE)
  454.     {
  455.         // copy current token
  456.         char* e_now = e;
  457.         TOKENTYPE token_type_now = token_type;
  458.         char token_now[NAME_LEN_MAX+1];
  459.         strcpy(token_now, token);
  460.  
  461.         getToken();
  462.         if (strcmp(token, "=") == 0)
  463.         {
  464.             // assignment
  465.             double ans;
  466.             getToken();
  467.             ans = parse_level2();
  468.             if (user_var.add(token_now, ans) == false)
  469.             {
  470.                 throw Error(row(), col(), 300);
  471.             }
  472.             return ans;
  473.         }
  474.         else
  475.         {
  476.             // go back to previous token
  477.             e = e_now;
  478.             token_type = token_type_now;
  479.             strcpy(token, token_now);
  480.         }
  481.     }
  482.  
  483.     return parse_level2();
  484. }
  485.  
  486. double Parser::parse_level2()
  487. {
  488.     int op_id;
  489.     double ans;
  490.     ans = parse_level3();
  491.  
  492.     op_id = get_operator_id(token);
  493.     while (op_id == AND || op_id == OR || op_id == BITSHIFTLEFT || op_id == BITSHIFTRIGHT)
  494.     {
  495.         getToken();
  496.         ans = eval_operator(op_id, ans, parse_level3());
  497.         op_id = get_operator_id(token);
  498.     }
  499.  
  500.     return ans;
  501. }
  502.  
  503. double Parser::parse_level3()
  504. {
  505.     int op_id;
  506.     double ans;
  507.     ans = parse_level4();
  508.  
  509.     op_id = get_operator_id(token);
  510.     while (op_id == EQUAL || op_id == UNEQUAL || op_id == SMALLER || op_id == LARGER || op_id == SMALLEREQ || op_id == LARGEREQ)
  511.     {
  512.         getToken();
  513.         ans = eval_operator(op_id, ans, parse_level4());
  514.         op_id = get_operator_id(token);
  515.     }
  516.  
  517.     return ans;
  518. }
  519.  
  520. double Parser::parse_level4()
  521. {
  522.     int op_id;
  523.     double ans;
  524.     ans = parse_level5();
  525.  
  526.     op_id = get_operator_id(token);
  527.     while (op_id == PLUS || op_id == MINUS)
  528.     {
  529.         getToken();
  530.         ans = eval_operator(op_id, ans, parse_level5());
  531.         op_id = get_operator_id(token);
  532.     }
  533.  
  534.     return ans;
  535. }
  536.  
  537. double Parser::parse_level5()
  538. {
  539.     int op_id;
  540.     double ans;
  541.     ans = parse_level6();
  542.  
  543.     op_id = get_operator_id(token);
  544.     while (op_id == MULTIPLY || op_id == DIVIDE || op_id == MODULUS || op_id == XOR)
  545.     {
  546.         getToken();
  547.         ans = eval_operator(op_id, ans, parse_level6());
  548.         op_id = get_operator_id(token);
  549.     }
  550.  
  551.     return ans;
  552. }
  553.  
  554. double Parser::parse_level6()
  555. {
  556.     int op_id;
  557.     double ans;
  558.     ans = parse_level7();
  559.  
  560.     op_id = get_operator_id(token);
  561.     while (op_id == POW)
  562.     {
  563.         getToken();
  564.         ans = eval_operator(op_id, ans, parse_level7());
  565.         op_id = get_operator_id(token);
  566.     }
  567.  
  568.     return ans;
  569. }
  570.  
  571. double Parser::parse_level7()
  572. {
  573.     int op_id;
  574.     double ans;
  575.     ans = parse_level8();
  576.  
  577.     op_id = get_operator_id(token);
  578.     while (op_id == FACTORIAL)
  579.     {
  580.         getToken();
  581.         // factorial does not need a value right from the
  582.         // operator, so zero is filled in.
  583.         ans = eval_operator(op_id, ans, 0.0);
  584.         op_id = get_operator_id(token);
  585.     }
  586.  
  587.     return ans;
  588. }
  589.  
  590. double Parser::parse_level8()
  591. {
  592.     double ans;
  593.  
  594.     int op_id = get_operator_id(token);
  595.     if (op_id == MINUS)
  596.     {
  597.         getToken();
  598.         ans = parse_level9();
  599.         ans = -ans;
  600.     }
  601.     else
  602.     {
  603.         ans = parse_level9();
  604.     }
  605.  
  606.     return ans;
  607. }
  608.  
  609. double Parser::parse_level9()
  610. {
  611.     char fn_name[NAME_LEN_MAX+1];
  612.     double ans;
  613.  
  614.     if (token_type == FUNCTION)
  615.     {
  616.         strcpy(fn_name, token);
  617.         getToken();
  618.         ans = eval_function(fn_name, parse_level10());
  619.     }
  620.     else
  621.     {
  622.         ans = parse_level10();
  623.     }
  624.  
  625.     return ans;
  626. }
  627.  
  628. double Parser::parse_level10()
  629. {
  630.     // check if it is a parenthesized expression
  631.     if (token_type == DELIMETER)
  632.     {
  633.         if (token[0] == '(' && token[1] == '\0')
  634.         {
  635.             getToken();
  636.             double ans = parse_level2();
  637.             if (token_type != DELIMETER || token[0] != ')' || token[1] || '\0')
  638.             {
  639.                 throw Error(row(), col(), 3);
  640.             }
  641.             getToken();
  642.             return ans;
  643.         }
  644.     }
  645.  
  646.     // if not parenthesized then the expression is a value
  647.     return parse_number();
  648. }
  649.  
  650. double Parser::parse_number()
  651. {
  652. double ans = 0;
  653.  
  654.     switch (token_type)
  655.     {
  656.         case NUMBER:
  657.             // this is a number
  658.             ans = strtod(token, NULL);
  659.             getToken();
  660.             break;
  661.  
  662.         case VARIABLE:
  663.             // this is a variable
  664.             ans = eval_variable(token);
  665.             getToken();
  666.             break;
  667.  
  668.         default:
  669.             // syntax error or unexpected end of expression
  670.             if (token[0] == '\0')
  671.             {
  672.                 throw Error(row(), col(), 6);
  673.             }
  674.             else
  675.             {
  676.                 throw Error(row(), col(), 7);
  677.             }
  678.             break;
  679.     }
  680.  
  681.     return ans;
  682. }
  683.  
  684. int Parser::get_operator_id(const char op_name[])
  685. {
  686.     // level 2
  687.     if (!strcmp(op_name, "&")) {return AND;}
  688.     if (!strcmp(op_name, "|")) {return OR;}
  689.     if (!strcmp(op_name, "<<")) {return BITSHIFTLEFT;}
  690.     if (!strcmp(op_name, ">>")) {return BITSHIFTRIGHT;}
  691.  
  692.     // level 3
  693.     if (!strcmp(op_name, "=")) {return EQUAL;}
  694.     if (!strcmp(op_name, "<>")) {return UNEQUAL;}
  695.     if (!strcmp(op_name, "<")) {return SMALLER;}
  696.     if (!strcmp(op_name, ">")) {return LARGER;}
  697.     if (!strcmp(op_name, "<=")) {return SMALLEREQ;}
  698.     if (!strcmp(op_name, ">=")) {return LARGEREQ;}
  699.  
  700.     // level 4
  701.     if (!strcmp(op_name, "+")) {return PLUS;}
  702.     if (!strcmp(op_name, "-")) {return MINUS;}
  703.  
  704.     // level 5
  705.     if (!strcmp(op_name, "*")) {return MULTIPLY;}
  706.     if (!strcmp(op_name, "/")) {return DIVIDE;}
  707.     if (!strcmp(op_name, "%")) {return MODULUS;}
  708.     if (!strcmp(op_name, "||")) {return XOR;}
  709.  
  710.     // level 6
  711.     if (!strcmp(op_name, "^")) {return POW;}
  712.  
  713.     // level 7
  714.     if (!strcmp(op_name, "!")) {return FACTORIAL;}
  715.  
  716.     return -1;
  717. }
  718.  
  719. double Parser::eval_operator(const int op_id, const double &lhs, const double &rhs)
  720. {
  721.     switch (op_id)
  722.     {
  723.         // level 2
  724.         case AND:           return static_cast<int>(lhs) & static_cast<int>(rhs);
  725.         case OR:            return static_cast<int>(lhs) | static_cast<int>(rhs);
  726.         case BITSHIFTLEFT:  return static_cast<int>(lhs) << static_cast<int>(rhs);
  727.         case BITSHIFTRIGHT: return static_cast<int>(lhs) >> static_cast<int>(rhs);
  728.  
  729.         // level 3
  730.         case EQUAL:     return lhs == rhs;
  731.         case UNEQUAL:   return lhs != rhs;
  732.         case SMALLER:   return lhs < rhs;
  733.         case LARGER:    return lhs > rhs;
  734.         case SMALLEREQ: return lhs <= rhs;
  735.         case LARGEREQ:  return lhs >= rhs;
  736.  
  737.         // level 4
  738.         case PLUS:      return lhs + rhs;
  739.         case MINUS:     return lhs - rhs;
  740.  
  741.         // level 5
  742.         case MULTIPLY:  return lhs * rhs;
  743.         case DIVIDE:    return lhs / rhs;
  744.         case MODULUS:   return static_cast<int>(lhs) % static_cast<int>(rhs); // todo: give a warning if the values are not integer?
  745.         case XOR:       return static_cast<int>(lhs) ^ static_cast<int>(rhs);
  746.  
  747.         // level 6
  748.         case POW:       return pow(lhs, rhs);
  749.  
  750.         // level 7
  751.         case FACTORIAL: return factorial(lhs);
  752.     }
  753.  
  754.     throw Error(row(), col(), 104, op_id);
  755.     return 0;
  756. }
  757.  
  758. double Parser::eval_function(const char fn_name[], const double &value)
  759. {
  760.     try
  761.     {
  762.         // first make the function name upper case
  763.         char fnU[NAME_LEN_MAX+1];
  764.         toupper(fnU, fn_name);
  765.  
  766.         // arithmetic
  767.         if (!strcmp(fnU, "ABS")) {return abs(value);}
  768.         if (!strcmp(fnU, "EXP")) {return exp(value);}
  769.         if (!strcmp(fnU, "SIGN")) {return sign(value);}
  770.         if (!strcmp(fnU, "SQRT")) {return sqrt(value);}
  771.         if (!strcmp(fnU, "LOG")) {return log(value);}
  772.         if (!strcmp(fnU, "LOG10")) {return log10(value);}
  773.  
  774.         // trigonometric
  775.         if (!strcmp(fnU, "SIN")) {return sin(value);}
  776.         if (!strcmp(fnU, "COS")) {return cos(value);}
  777.         if (!strcmp(fnU, "TAN")) {return tan(value);}
  778.         if (!strcmp(fnU, "ASIN")) {return asin(value);}
  779.         if (!strcmp(fnU, "ACOS")) {return acos(value);}
  780.         if (!strcmp(fnU, "ATAN")) {return atan(value);}
  781.  
  782.         // probability
  783.         if (!strcmp(fnU, "FACTORIAL")) {return factorial(value);}
  784.     }
  785.     catch (Error err)
  786.     {
  787.         // retrow error, add information about column and row of occurance
  788.         // TODO: doesnt work yet
  789.         throw Error(col(), row(), err.get_id(), err.get_msg());
  790.     }
  791.  
  792.     // unknown function
  793.     throw Error(row(), col(), 102, fn_name);
  794.     return 0;
  795. }
  796.  
  797. double Parser::eval_variable(const char var_name[])
  798. {
  799.     // first make the variable name uppercase
  800.     char varU[NAME_LEN_MAX+1];
  801.     toupper(varU, var_name);
  802.  
  803.     // check for built-in variables
  804.     if (!strcmp(varU, "E")) {return 2.7182818284590452353602874713527;}
  805.     if (!strcmp(varU, "PI")) {return 3.1415926535897932384626433832795;}
  806.  
  807.     // check for user defined variables
  808.     double ans;
  809.     if (user_var.get_value(var_name, &ans))
  810.     {
  811.         return ans;
  812.     }
  813.  
  814.     // unknown variable
  815.     throw Error(row(), col(), 103, var_name);
  816.     return 0;
  817. }
  818.  
  819. int Parser::row()
  820. {
  821.     return -1;
  822. }
  823.  
  824. int Parser::col()
  825. {
  826.     return e-expr-strlen(token)+1;
  827. }
  828.  
  829.  
  830. bool Variablelist::exist(const char* name)
  831. {
  832.     return (get_id(name) != -1);
  833. }
  834.  
  835. bool Variablelist::add(const char* name, double value)
  836. {
  837.     VAR new_var;
  838.     strncpy(new_var.name, name, 30);
  839.     new_var.value = value;
  840.  
  841.     int id = get_id(name);
  842.     if (id == -1)
  843.     {
  844.         // variable does not yet exist
  845.         var.push_back(new_var);
  846.     }
  847.     else
  848.     {
  849.         // variable already exists. overwrite it
  850.         var[id] = new_var;
  851.     }
  852.     return true;
  853. }
  854.  
  855. bool Variablelist::del(const char* name)
  856. {
  857.     int id = get_id(name);
  858.     if (id != -1)
  859.     {
  860.         var[id] = var[var.size()-1]; // move last item to deleted item
  861.         var.pop_back();              // remove last item
  862.         return true;
  863.     }
  864.     return false;
  865. }
  866.  
  867. bool Variablelist::get_value(const char* name, double* value)
  868. {
  869.     int id = get_id(name);
  870.     if (id != -1)
  871.     {
  872.         *value = var[id].value;
  873.         return true;
  874.     }
  875.     return false;
  876. }
  877.  
  878.  
  879. bool Variablelist::get_value(const int id, double* value)
  880. {
  881.     if (id >= 0 && id < (int)var.size())
  882.     {
  883.         *value = var[id].value;
  884.         return true;
  885.     }
  886.     return false;
  887. }
  888.  
  889.  
  890. bool Variablelist::set_value(const char* name, const double value)
  891. {
  892.     return add(name, value);
  893. }
  894.  
  895. int Variablelist::get_id(const char* name)
  896. {
  897.     // first make the name uppercase
  898.     char nameU[NAME_LEN_MAX+1];
  899.     char varU[NAME_LEN_MAX+1];
  900.     toupper(nameU, name);
  901.  
  902.     for (unsigned int i = 0; i < var.size(); i++)
  903.     {
  904.         toupper(varU, var[i].name);
  905.         if (strcmp(nameU, varU) == 0)
  906.         {
  907.             return i;
  908.         }
  909.     }
  910.     return -1;
  911. }
  912.  
  913. void toupper(char upper[], const char str[])
  914. {
  915.     int i = -1;
  916.     do
  917.     {
  918.         i++;
  919.         upper[i] = std::toupper(str[i]);
  920.     }
  921.     while (str[i] != '\0');
  922. }
  923.  
  924.  
  925. ////////////////////////////////
  926.  
  927. void STRtoCHAR(char* ain, string bin)
  928. {
  929.     int len=bin.length();
  930.     for(int i=0; i<len; ++i)
  931.     {
  932.         ain[i]=bin[i];
  933.     }
  934.     ain[len]=NULL;
  935. }
  936.  
  937. int main(int argc, char *argv[])
  938. {
  939.     int n;
  940.     cin >> n;
  941.  
  942.     for (int i=0; i<n; i++)
  943.     {
  944.         char expr[1001];
  945.         string input;
  946.         char x,y;
  947.         char xx[777], yy[777];
  948.         Parser prs;
  949.  
  950.         cin >> input >> x >> y;
  951.        
  952.         std::replace(input.begin(), input.end(), 'x', x);
  953.         std::replace(input.begin(), input.end(), 'y', y);
  954.  
  955.         STRtoCHAR(expr, input);
  956.  
  957.         if (strcmp(expr, "") != 0)
  958.         {
  959.             try
  960.             {
  961.                 char* result;
  962.                 result = prs.parse(expr);
  963.                 if (result == "error")
  964.                 {
  965.                     cout << "error" << endl;
  966.                 }
  967.                 else
  968.                 {
  969.                     double wynik = strtod(result,NULL);
  970.                     cout << fixed << setprecision(2) << wynik << endl;
  971.                 }
  972.             }
  973.             catch (...)
  974.             {
  975.                 printf("\terror\n");
  976.             }
  977.         }
  978.     } //while (strcmp(expr, "") != 0);
  979.  
  980.     return EXIT_SUCCESS;
  981. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement