Glenpl

Parser

Nov 10th, 2014
349
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.37 KB | None | 0 0
  1. //basic mathematical parser v2.2.1
  2. //author jakub molinski
  3. //feel free to use, modify,
  4. //copy and sell this code
  5.  
  6. #include <iostream>
  7. #include <iomanip>
  8. #include <sstream>
  9. #include <cstdlib>
  10. #include <conio.h>
  11. #include <string>
  12. #include <math.h>
  13.  
  14. using namespace std;
  15.  
  16. // list of functions
  17. string parser(string);
  18. string switcher(string);
  19. string addition(string);
  20. string subtraction(string);
  21. string multiplication(string);
  22. string division(string);
  23. string exponentiation(string);
  24. string sqroot(string);
  25.  
  26. // main function
  27. int main()
  28. {
  29.     cout << setprecision(20);
  30.  
  31.     // parser tests
  32.     //cout << endl << "Wynik: " << parser("(M_E+M_PI)") << endl << endl;
  33.     //cout << endl << "Wynik: " << parser("((((5+5)+10)+(5*5))-(10*(11-6)))") << endl << endl;
  34.     //cout << endl << "Wynik: " << parser("((50/3)-(10*6))") << endl << endl;
  35.     //cout << endl << "Wynik: " << parser("(((5+5)+10)+(5*M_PI2))") << endl << endl;
  36.     //cout << endl << "Wynik: " << parser("((((((100+90)+80)+70)+60)+50)+1.55)") << endl << endl;
  37.     //cout << endl << "Wynik: " << parser("(5^2)") << endl << endl;
  38.     //cout << endl << "Wynik: " << parser("((sqrt(81))+50)") << endl << endl;
  39.  
  40.  
  41.     // subfunction tests
  42.     /*
  43.     cout << addition("10+15.5") << endl;
  44.     cout << subtraction("10-15.5") << endl;
  45.     cout << multiplication("10*15.5") << endl;
  46.     cout << division("10/15.5") << endl;
  47.     cout << exponentiation("10^3") << endl;
  48.     cout << sqroot("sqrt(81)") << endl;
  49.     */
  50.  
  51.     _getch();
  52.     return 0;
  53. }
  54.  
  55. //parser, main body
  56. string parser(string text)
  57. {
  58.  
  59.     // initiation, variables
  60.     string text_fixed = text;
  61.     int e;
  62.     int pi;
  63.     int pi2;
  64.     int bracket;
  65.     string operation;
  66.     int operation_length = 0;
  67.     bool done;
  68.     int operation_start = 0;
  69.     int operation_end = 0;
  70.  
  71.     // sources
  72.     const string M_E_str = "2.71828182846";
  73.     const string M_PI_str = "3.14159265358";
  74.     const string M_PI2_str = "6.28318530717";
  75.  
  76.     // first change, inserting constant values
  77.     e = text_fixed.find("M_E");
  78.     while (e != string::npos)
  79.     {
  80.         text_fixed.replace(e, 3, M_E_str);
  81.         e = text_fixed.find("M_E");
  82.     }
  83.     pi = text_fixed.find("M_PI");
  84.     while (pi != string::npos)
  85.     {
  86.         text_fixed.replace(pi, 4, M_PI_str);
  87.         pi = text_fixed.find("M_PI");
  88.     }
  89.     pi2 = text_fixed.find("M_PI2");
  90.     while (pi2 != string::npos)
  91.     {
  92.         text_fixed.replace(pi2, 5, M_PI2_str);
  93.         pi2 = text_fixed.find("M_PI2");
  94.     }
  95.  
  96.     // cutting into smaller operations, calculating them
  97.     bracket = text_fixed.find("(");
  98.     operation_start = bracket;
  99.  
  100.     while (
  101.         (text_fixed.find("(") != string::npos) ||
  102.         (text_fixed.find(")") != string::npos) ||
  103.         (text_fixed.find("+") != string::npos) ||
  104.         (text_fixed.find("-") != string::npos) ||
  105.         (text_fixed.find("*") != string::npos) ||
  106.         (text_fixed.find("/") != string::npos) ||
  107.         (text_fixed.find("^") != string::npos) ||
  108.         (text_fixed.find("sqrt") != string::npos))
  109.     {
  110.         //checks if text_fixed does not look like (45) or something
  111.         if((text_fixed[0] == '(') && (text_fixed[(text_fixed.length())-1] == ')'))
  112.         {
  113.             string text_onlynumbers = text_fixed;
  114.             text_onlynumbers.erase(0,1);
  115.             text_onlynumbers.erase((text_onlynumbers.length())-1,1);
  116.  
  117.             bool calculated = true;
  118.  
  119.             for(int i = 0; i < text_onlynumbers.length(); i++)
  120.             {
  121.                 if((text_onlynumbers[i] > 57) || (text_onlynumbers[i] < 48 ))
  122.                 {
  123.                     calculated = false;
  124.                     break;
  125.                 }
  126.             }
  127.             if(calculated)
  128.             {
  129.                 text_fixed.erase(0,1);
  130.                 text_fixed.erase((text_fixed.length())-1,1);
  131.                 break;
  132.             }
  133.         }
  134.  
  135.         // main
  136.         done = false;
  137.         while (done == false)
  138.         {
  139.             if (bracket != string::npos)
  140.             {
  141.                 for (int i = (bracket+1);; i++)
  142.                 {
  143.                     if (text_fixed[i] == ')')
  144.                     {
  145.                         if (operation[0] == 's')
  146.                         {
  147.                             operation_length++;
  148.                             operation += ')';
  149.                         }
  150.                         done = true;
  151.                         operation_end = ++i;
  152.  
  153.  
  154.  
  155.                         cout << "Text fixed1: " << text_fixed << endl;
  156.                         cout << "Operacja1: " << operation << endl;
  157.  
  158.                         // calculate the operation and replace it with its result
  159.                         text_fixed.replace(operation_start, (operation_length + 2), switcher(operation));
  160.                         bracket = text_fixed.find("(");
  161.                         operation_start = bracket;
  162.                         operation_length = 0;
  163.                         operation = "";
  164.                         break;
  165.                     }
  166.                     // sqrt exception
  167.                     if ((text_fixed[i] == '(') && (text_fixed[i - 1] != 't'))
  168.                     {
  169.                         bracket = i;
  170.                         operation_start = bracket;
  171.                         operation_length = 0;
  172.                         operation = "";
  173.                         break;
  174.                     }
  175.                     operation_length++;
  176.                     operation += text_fixed[i];
  177.                 }
  178.             }
  179.             else
  180.             {
  181.                 break;
  182.             }
  183.         }
  184.     }
  185.  
  186.     // returning modified text
  187.     return text_fixed;
  188. }
  189.  
  190. //sends operation to appropriate calculating function
  191. string switcher(string operation)
  192. {
  193.     if (operation.find("+") != string::npos)
  194.     {
  195.         return addition(operation);
  196.     }
  197.     if (operation.find("-") != string::npos)
  198.     {
  199.         return subtraction(operation);
  200.     }
  201.     if (operation.find("*") != string::npos)
  202.     {
  203.         return multiplication(operation);
  204.     }
  205.     if (operation.find("/") != string::npos)
  206.     {
  207.         return division(operation);
  208.     }
  209.     if (operation.find("^") != string::npos)
  210.     {
  211.         return exponentiation(operation);
  212.     }
  213.     if (operation.find("sqrt") != string::npos)
  214.     {
  215.         return sqroot(operation);
  216.     }
  217.     else
  218.     {
  219.         cout << "\n\n\n BLAD SWITCHERA!!! \n\n\n";
  220.         exit(0);
  221.     }
  222. }
  223.  
  224. //basic addition
  225. string addition(string to_add)
  226. {
  227.     // variables
  228.     int ch_place = to_add.find("+");
  229.     string leftside_str = "";
  230.     string rigthside_str = "";
  231.     double leftside;
  232.     double rigthside;
  233.     double result;
  234.     string result_str;
  235.  
  236.     // finding the left and the right side of "+" character
  237.     for (int i = 0; i < ch_place; i++)
  238.     {
  239.         leftside_str += to_add[i];
  240.     }
  241.     for (int i = ++ch_place; i < to_add.length(); i++)
  242.     {
  243.         rigthside_str += to_add[i];
  244.     }
  245.  
  246.     // converting string into double
  247.     leftside = atof(leftside_str.c_str());
  248.     rigthside = atof(rigthside_str.c_str());
  249.  
  250.     // calculating the result
  251.     result = leftside + rigthside;
  252.  
  253.     // converting double into string
  254.     ostringstream strs;
  255.     strs << result;
  256.     result_str = strs.str();
  257.  
  258.     // returning calculated value
  259.     return result_str;
  260. }
  261.  
  262. //basic substraction
  263. string subtraction(string to_sub)
  264. {
  265.     // variables
  266.     int ch_place = to_sub.find("-");
  267.     string leftside_str = "";
  268.     string rigthside_str = "";
  269.     double leftside;
  270.     double rigthside;
  271.     double result;
  272.     string result_str;
  273.  
  274.     // finding the left and the right side of "-" character
  275.     for (int i = 0; i < ch_place; i++)
  276.     {
  277.         leftside_str += to_sub[i];
  278.     }
  279.     for (int i = ++ch_place; i < to_sub.length(); i++)
  280.     {
  281.         rigthside_str += to_sub[i];
  282.     }
  283.  
  284.     // converting string into double
  285.     leftside = atof(leftside_str.c_str());
  286.     rigthside = atof(rigthside_str.c_str());
  287.  
  288.     // calculating the result
  289.     result = leftside - rigthside;
  290.  
  291.     // converting double into string
  292.     ostringstream strs;
  293.     strs << result;
  294.     result_str = strs.str();
  295.  
  296.     // returning calculated value
  297.     return result_str;
  298. }
  299.  
  300. //basic multiplication
  301. string multiplication(string to_mul)
  302. {
  303.     // variables
  304.     int ch_place = to_mul.find("*");
  305.     string leftside_str = "";
  306.     string rigthside_str = "";
  307.     double leftside;
  308.     double rigthside;
  309.     double result;
  310.     string result_str;
  311.  
  312.     // finding the left and the right side of "*" character
  313.     for (int i = 0; i < ch_place; i++)
  314.     {
  315.         leftside_str += to_mul[i];
  316.     }
  317.     for (int i = ++ch_place; i < to_mul.length(); i++)
  318.     {
  319.         rigthside_str += to_mul[i];
  320.     }
  321.  
  322.     // converting string into double
  323.     leftside = atof(leftside_str.c_str());
  324.     rigthside = atof(rigthside_str.c_str());
  325.  
  326.     // calculating the result
  327.     result = leftside * rigthside;
  328.  
  329.     // converting double into string
  330.     ostringstream strs;
  331.     strs << result;
  332.     result_str = strs.str();
  333.  
  334.     // returning calculated value
  335.     return result_str;
  336. }
  337.  
  338. //basic division
  339. string division(string to_div)
  340. {
  341.     // variables
  342.     int ch_place = to_div.find("/");
  343.     string leftside_str = "";
  344.     string rigthside_str = "";
  345.     double leftside;
  346.     double rigthside;
  347.     double result;
  348.     string result_str;
  349.  
  350.     // finding the left and the right side of "/" character
  351.     for (int i = 0; i < ch_place; i++)
  352.     {
  353.         leftside_str += to_div[i];
  354.     }
  355.     for (int i = ++ch_place; i < to_div.length(); i++)
  356.     {
  357.         rigthside_str += to_div[i];
  358.     }
  359.  
  360.     // converting string into double
  361.     leftside = atof(leftside_str.c_str());
  362.     rigthside = atof(rigthside_str.c_str());
  363.  
  364.     // calculating the result
  365.     result = leftside / rigthside;
  366.  
  367.     // converting double into string
  368.     ostringstream strs;
  369.     strs << result;
  370.     result_str = strs.str();
  371.  
  372.     // returning calculated value
  373.     return result_str;
  374. }
  375.  
  376. //basic exponentiation
  377. string exponentiation(string to_exp)
  378. {
  379.     // variables
  380.     int ch_place = to_exp.find("^");
  381.     string leftside_str = "";
  382.     string rigthside_str = "";
  383.     double leftside;
  384.     double rigthside;
  385.     double result;
  386.     string result_str;
  387.  
  388.     // finding the left and the right side of "^" character
  389.     for (int i = 0; i < ch_place; i++)
  390.     {
  391.         leftside_str += to_exp[i];
  392.     }
  393.     for (int i = ++ch_place; i < to_exp.length(); i++)
  394.     {
  395.         rigthside_str += to_exp[i];
  396.     }
  397.  
  398.     // converting string into double
  399.     leftside = atof(leftside_str.c_str());
  400.     rigthside = atof(rigthside_str.c_str());
  401.  
  402.     // calculating the result
  403.     result = pow(leftside, rigthside);
  404.  
  405.     // converting double into string
  406.     ostringstream strs;
  407.     strs << result;
  408.     result_str = strs.str();
  409.  
  410.     // returning calculated value
  411.     return result_str;
  412. }
  413.  
  414. //basic square root
  415. string sqroot(string to_root)
  416. {
  417.     // variables
  418.     double root;
  419.     double result;
  420.     string result_str;
  421.  
  422.     // extracting the number
  423.     to_root.erase(0, 5);
  424.     to_root.erase((to_root.length() - 1), 1);
  425.  
  426.     // converting string into double
  427.     root = atof(to_root.c_str());
  428.  
  429.     // calculating the result
  430.     result = pow(root, 0.5);
  431.  
  432.     // converting double into string
  433.     ostringstream strs;
  434.     strs << result;
  435.     result_str = strs.str();
  436.  
  437.     // returning calculated value
  438.     return result_str;
  439. }
Advertisement
Add Comment
Please, Sign In to add comment