piromanas
public cpp v1 · immutable#include <iostream>#include <string>#include <sstream>#include <algorithm>#include <cmath>#include <stdlib.h>#include <list> using namespace std;namespace state { const int control = 1 ; const int id = 2 ; const int value = 3 ; const int operation = 4 ; const int floating_point = 5 ; const int exp = 6 ; const int empty = 7 ; const int binary = 8 ; const int unary = 9 ; const int paranthesis = 10 ; const int function = 11 ; const int expression = 12 ; const int ERROR = 13 ; const int quit = 14 ; }struct node { node *right, *left ; float value ; string token ; int type ; node (std::string::iterator b,std::string::iterator e,int type) : token (b,e), value (0.0f), type (type), right (NULL), left (NULL) { if (type == state::value) { std::stringstream ss (token) ; ss >> value ; } } } ; void lexer (string::iterator begin, string::iterator end, list<node *> & output) { std::string::iterator i = begin, b, e ; int state = state::control ; int count = 0 ; while ( i != end ) { switch (state) { case state::control : if ( i != end && isalpha(*i) ) { b = i ; state = state::id ; } else if ( i != end && isdigit(*i) ) { b = i ; state = state::value ; } else if ( i != end && ((*i == '+') || (*i == '-') || (*i == '*') || (*i == '/') || (*i == '^') || (*i == '(') || (*i == ')')) ) { b = i ; state = state::operation ; } else if ( i != end && (*i == ' ') ) { state = state::empty ; } else state = state::ERROR ; break ; case state::id : if ( i != end && (isalpha(*i) || isdigit(*i)) ) { state = state::id ; ++i ; } else { output.push_back(new node(b,i,state::id)) ; state = state::control ; } break ; case state::value : if ( i != end && isdigit(*i) ) { state = state::value ; ++i ; continue ; } else if ( i != end && (((*i) == ',') || ((*i) == '.')) ) { state = state::floating_point ; *i = '.' ; ++count ; ++i ; continue ; } else if ( i < end && ((*i == 'E') || (*i == 'e')) ) { state = state::exp ; ++i ; continue ; } else if ( i!= end && *i == ' ' ) { state = state::control ; output.push_back(new node(b,i,state::value)) ; } else { output.push_back(new node(b,i,state::value)) ; count = 0 ; state = state::control ; } break ; case state::operation : if ( i != end && ((*i == '+') || (*i == '-') || (*i == '*') || (*i == '/') || (*i == '^') || (*i == '(') || (*i == ')')) ) { ++i ; output.push_back(new node(b,i,state::operation)) ; state = state::control ; continue ; } break ; case state::floating_point : if ( i != end && isdigit(*i) && count < 2 ) { state = state::value ; ++i ; continue ; } else state = state::ERROR ; break ; case state::exp : if ( i != end && isdigit(*i) || (*i == '+') || (*i == '-') ) { state = state::value ; ++i ; continue ; } else state = state::ERROR ; break ; case state::empty : if ( i != end && *i == ' ' ) { state = state::empty ; ++i ; continue ; } else state = state::control ; break ; case state::ERROR : default : cout << "aaa" ; } } if ( i == end && state != state::ERROR && state != state::control && state != state::empty ) { if ( state == state::id ) { output.push_back(new node(b,i,state::id)) ; } else if ( state == state::operation ) { output.push_back(new node(b,i,state::operation)) ; } else if ( state == state::value ) { output.push_back(new node(b,i,state::value)) ; } } } void parser ( list<node *> & input ) { int count = 0 ; list<node *>::iterator i = input.begin(), i1 ; char const * op [] = {"*","/","-","+"} ; list<string> operators(op,op+sizeof(op)/sizeof(op[0])) ; list<string>::iterator str_i = operators.begin() ; int state = state::unary ; while ( state != state::quit ) { switch (state) { case state::binary : if ( i != input.end() && ((*i)->type == state::value || (*i)->type == state::expression || (*i)->type == state::id ) ) { i1 = i ; ++i ; if ( i != input.end() && ((*i)->type == state::operation || (*i)->type == state::expression) && (*i)->token == *str_i ) { node *o = *i ; ++i ; if ( i != input.end() && ((*i)->type == state::value || (*i)->type == state::expression || (*i)->type == state::id ) ) { o->left = *i1 ; o->right = *i; o->type = state::expression ; input.erase(i1) ; input.erase( find(input.begin(), input.end(), o->right ) ) ; i = input.begin() ; state = state::binary ; ++count ; } } } else if ( i != input.end() ) { state = state::binary ; ++i ; } else if ( i == input.end() && str_i != operators.end() ) { i = input.begin() ; state = state::binary ; ++str_i ; } else { state = state::quit ; } break ; case state::unary : if ( i != input.end() && (*i)->type == state::operation ) { i1 = i ; ++i ; if ( i != input.end() && (((*i)->type == state::operation && ( (*i)->token == "+" || (*i)->token == "-" )) || (*i)->type == state::function) ) { node *o = *i ; ++i ; if ( i != input.end() && ((*i)->type == state::value || (*i)->type == state::expression || (*i)->type == state::id ) ) { if ( i1 == input.begin() ) { (*i1)->right = o ; o->right = *i ; (*i1)->type = state::expression ; input.erase(i) ; input.erase(find(input.begin(),input.end(),(*i1)->right)) ; } else { o->right = *i ; o->type = state::expression ; input.erase(i) ; } i = input.begin() ; state = state::unary ; ++count ; } } } else if ( i != input.end() ) { state = state::unary ; ++i ; } else if ( i == input.end() && count > 0 ) { i = input.begin() ; state = state::binary ; count = 0 ; } else state = state::binary ; break ; /*case state::paranthesis : if ( i != input.end() && (*i)->type == state::operation && (*i)->token == "(" ) { (*i1) = *i ; ++i ; if ( i != input.end() && ( (*i)->type == state::expression || (*i)->type == state::value ) ) { ++i ; if ( i != input.end() && (*i)->type == state::operation && (*i)->token == ")" ) { input.erase(i) ; input.erase(i1) ; i = input.begin() ; state = state::paranthesis ; } } } else state = state::quit ; break ; */ } } } std::ostream & operator << (std::ostream & out,node const & n) { if (n.type == state::value) out << n.value ; else out << n.token ; } int main() { list<node *>::iterator i ; string str ; list<node *> output ; getline(cin,str) ; lexer(str.begin(),str.end(),output) ; parser(output) ; i = output.begin() ; while ( i != output.end() ) { cout << **i ; ++i ; } cin.get() ;}