int main () { StackInt P (5); for (int x =0; x<10; x++){ P.push( x ); cout <<"Valor do topo: " << P.top() << endl; } //cout << "Valor Excluido: " << P.pop() << endl; try { cout << "Valor Excluido: " << P.pop() << endl; P.printArray(); } catch (std::length_error &e) { //cout << e.what() << endl; cout << "Capturei uma excessão: " << e.what() << endl; } }
int main(int argc, char const *argv[]) { ifstream IFileIn; ifstream IFileVars; int AND = -2; int OR = -3; int NOT = -4; int OpenParenth = -5; int OpenCount = 0; int ClosedCount = 0; int Answer = 0; int numberBeg; int numberEnd; string line; bool charBool; bool nextBool = NULL; bool currBool = NULL; string number; StackInt stack; map<string, bool> boolMap; map<string, bool>::iterator it; //stackint expressionStack; IFileVars.open(argv[1]); //open the variable expressions file if (IFileVars.fail()) { cout << "\n\n\nCould not open the file\n\n\n"; } else if (IFileVars.is_open()){ while ( getline (IFileVars,line)){ //read in each line character by character and store the keys and values separated by null spaces for (int i = 0; i < line.length(); ++i) { //find the end of each number if (isdigit(line[i]) != 0 && isdigit(line[i+1]) == 0){ numberEnd = i + 1; } //if the character is T or F store that as a bool if (line[i] == 'T'){ charBool = true; } if (line[i] == 'F'){ charBool = false; } } //store number into a string for (int j = 0; j < numberEnd; ++j){ number += line[j]; } //store the pair<string, bool> into the map boolMap.insert(pair<string, bool>(number, charBool)); //reset the number string number = ""; } IFileVars.close(); } //open the expr1.in file IFileIn.open(argv[2]); if (IFileIn.fail()){ cout << "Could not open file"; } else if(IFileIn.is_open()) { while(getline(IFileIn,line)){ Answer = 0; for (int i = 0; i < line.length(); ++i){ if (isdigit(line[i]) == 0 && isdigit(line[i+1]) != 0){ numberBeg = i +1; } if (isdigit(line[i]) != 0 && isdigit(line[i+1]) == 0){ numberEnd = i; for (int j = numberBeg; j <= numberEnd; ++j) { number += line[j]; } if (boolMap.count(number) == 1) { stack.push(boolMap[number]); } else if (boolMap.count(number) == 0 && Answer == 0){ Answer = 3; } //set the number string to null number = ""; } //store all of the boolean values and open parenthesis onto the stack if (line[i] == '&'){ stack.push(AND); } if (line[i] == '|'){ stack.push(OR); } if (line[i] == '~'){ stack.push(NOT); } if (line[i] == '('){ OpenCount += 1; stack.push(OpenParenth); } //evaluate at the ) character if (line[i] == ')' && stack.empty() != 0) { ClosedCount += 1; } if (line[i] == ')' && stack.empty() == 0){ ClosedCount += 1; if (stack.top() == AND || stack.top() == OR || stack.top() == NOT && Answer == 0) {Answer = 4;continue;} currBool = stack.top(); stack.pop(); while(stack.top() == -4){ stack.pop(); ~currBool; } while(!stack.empty()){ if (stack.top() == AND){ stack.pop(); if (stack.top() == AND || stack.top() == OR || stack.top() == OpenParenth || stack.top() == NOT){ if (Answer == 0){ Answer = 4; } } nextBool = stack.top(); stack.pop(); while(stack.top() == -4){ stack.pop(); ~nextBool; } if (stack.top() == OR && Answer == 0){ Answer = 4; continue; } currBool = currBool & nextBool; } if (stack.top() == OR){ stack.pop(); if (stack.top() == AND || stack.top() == OR || stack.top() == OpenParenth || stack.top() == NOT && Answer == 0){ if (Answer == 0){ Answer = 4; } } nextBool = stack.top(); stack.pop(); while(stack.top() == -4){ stack.pop(); ~nextBool; } if (stack.top() == AND && Answer == 0){ Answer = 4; continue; } currBool = currBool | nextBool; } if (stack.top() == OpenParenth){ stack.pop(); while(stack.top() == -4){ stack.pop(); ~currBool; } } } } } if (OpenCount != ClosedCount && Answer == 0){ Answer = 4; } if (Answer == 0 && line != "" && currBool == 1){ cout << "\nT"; }if (Answer == 0 && line != "" && currBool == 0){ cout << "\nF"; } else if (Answer == 3){ cout << "\nUnknown Variable"; } else if (Answer == 4){ cout << "\nMalformed"; } } } return 0; }
int main(int argc, char* argv[]){ ifstream input(argv[1]); string line; StackInt * stack = new StackInt(); bool check = true; // check is true if the line is valid (not malformed) while(getline(input, line)){ if(line == "" || line == " ") continue; // if empty line, or one contining a space stringstream ss; ss >> line; char ch; while(!ss.fail() || check){ ss << ch; if(ch == " ") continue; // to skip whitespace if(int(ch) >= 48 && int(ch) <= 57){ // if the char is a number stringstream intStream; // intStream will help turn char digits into an actual number intStream >> ch; while(int(ch) >= 48 && int(ch) <= 57){ // while the following char's are numbers ss << ch; if(ch == " ") break; // if there's whitespace intStream >> ch; } int number; intStream << number; stack.push(number); } if (int(ch) == 43) stack.push(-1); // '-1' is used in the stack to represent the + operator else if(int(ch) == 42) stack.push(-2); // '-2' used for the '*' operator else if(int(ch) == 60) stack.push(-3); // '-3' used for the '<' operator else if(int(ch) == 62) stack.push(-4); // '-4' used for the '>' operator else if(int(ch) == 40) stack.push(-5); // '-5' used for the '(' open paranthesis if(ch == ')'){ int w = stack.top(); if(w < 0){ // if it is not a number, but an operator instead cout << "Malformed" << endl; check = false; break; } else{ stack.pop(); int x = stack.top(); if(x == -3 || x == -4){ // if '<' or '>' if (x==-3) w*=2; // < operator, must multiply by 2 else {w=floor(w/2)}; // > operator, must divide by 2 } else{ if (x >= 0){ // you can't have 2 numbers in a row without operators or parentheses -> malformed cout << "Malformed" << endl; check = false; break; } else{ // where x is either '+' or '*', in the for -1 or -2 respectively stack.pop(); int y = stack.top(); if(y==-1 || y==-2){ // can't have 2 (+ or *) operators in a row -> malformed cout << "Malformed" << endl; check = false; break; } if(y>0){ // if y is a number if(x == -1) w +=y; else if(x == -2) {w*=y;} } stack.pop(); int z = stack.top(); if (z == -5){ // if z is a '(' , then we can process whats inside the current parentheses set stack.pop(); stack.push(w); // add the processed number back to the stack } } } } } }
int parse(string s){ StackInt stack; // for each character in the array for(unsigned int i=0; i < s.length(); i++) { if(s[i] == ' '){ if(!stack.empty()) // make sure theres no space between integers if(stack.top() >= 0) if(s[i+1] >= '0' && s[i+1] <= '9') return MAL; continue; // don't do anything on white space } else if(s[i] >= '0' && s[i] <= '9'){ // is int, add to stack int num = (int)s[i] - 48; if(!stack.empty()){ if(stack.top() >= 0){ // the previous int is the tens of current int num = num + stack.top()*10; stack.pop(); } } stack.push(num); } else if(s[i] == '>'){ // is >, add to stack if(stack.empty()) stack.push(RIGHT); else { // avoid throw exception if(stack.top() != CLOSE && stack.top() < 0) stack.push(RIGHT); else return MAL; // may not be preceeded by int or ) } } else if(s[i] == '<'){ // is <, add to stack if(stack.empty()) stack.push(LEFT); else { // avoid throw exception if (stack.top() != CLOSE && stack.top() < 0) stack.push(LEFT); else return MAL; // may not be preceeded by int or ) } } else if(s[i] == '*' || s[i] == '+'){ if(parseShift(stack) == 1) return MAL; // parseShift if(stack.empty()) return MAL; if(stack.top() < 0 && stack.top() != CLOSE) return MAL; if(s[i] == '*') stack.push(TIMES); else if(s[i] == '+') stack.push(PLUS); } else if(s[i] == '('){ if(!stack.empty() && (stack.top() >= 0 || stack.top() == CLOSE)) return MAL; stack.push(OPEN); } else if(s[i] == ')'){ if(parseShift(stack) == 1) return MAL; // parseShift if(parseExp(stack) == 1) return MAL; // parseExp } else return MAL; } if(parseShift(stack) == 1) return MAL; // parseShift, outside of () // last check for syntaxical errors int final; if(stack.top() >= 0) final = stack.top(); else return MAL;
AUT_RESULT AutoIt_Script::Parser_EvaluateExpression(VectorToken &vLineToks, unsigned int &ivPos, Variant &vResult) { StackInt opStack; // Operator parsing stack StackVariant valStack; // Value (variant) parsing stack int opTemp; Variant vTemp; int opPrev = OPR_NULL; bool bLastOpWasReduce; int nColTemp; // Initialise the operator stack with the END token opStack.push(OPR_END); // Store the column at the start of the expression for easy error output nColTemp = vLineToks[ivPos].m_nCol; for (;;) { // Must be either an operator, variant or function, otherwise end of expression reached // Convert to the type of tokens this routine uses. Also execute any functions to get their // return values (the function eval may itself call this function for evaluation - recursion // rocks! ;) ) switch ( vLineToks[ivPos].m_nType ) { case TOK_LESS: opTemp = OPR_LESS; ivPos++; // Move the position to the next token, ready for next iteration break; case TOK_GREATER: opTemp = OPR_GTR; ivPos++; break; case TOK_LESSEQUAL: opTemp = OPR_LESSEQUAL; ivPos++; break; case TOK_GREATEREQUAL: opTemp = OPR_GTREQUAL; ivPos++; break; case TOK_NOTEQUAL: opTemp = OPR_NOTEQUAL; ivPos++; break; case TOK_EQUAL: opTemp = OPR_EQUAL; ivPos++; break; case TOK_STRINGEQUAL: opTemp = OPR_STRINGEQUAL; ivPos++; break; case TOK_CONCAT: opTemp = OPR_CONCAT; ivPos++; break; case TOK_PLUS: // Check for unary plus if ( opPrev != OPR_VAL && opPrev != OPR_RPR) opTemp = OPR_UPL; else opTemp = OPR_ADD; ivPos++; break; case TOK_MINUS: // Check for unary minus if ( opPrev != OPR_VAL && opPrev != OPR_RPR) opTemp = OPR_UMI; else opTemp = OPR_SUB; ivPos++; break; case TOK_MULT: opTemp = OPR_MUL; ivPos++; break; case TOK_DIV: opTemp = OPR_DIV; ivPos++; break; case TOK_POW: opTemp = OPR_POW; ivPos++; break; case TOK_LEFTPAREN: opTemp = OPR_LPR; ivPos++; break; case TOK_RIGHTPAREN: opTemp = OPR_RPR; ivPos++; break; case TOK_STRING: vTemp = vLineToks[ivPos].szValue; if (m_bExpandEnvStrings) Parser_ExpandEnvString(vTemp); if (m_bExpandVarStrings) Parser_ExpandVarString(vTemp); opTemp = OPR_VAL; ivPos++; break; case TOK_INT32: vTemp = vLineToks[ivPos].nValue; opTemp = OPR_VAL; ivPos++; break; case TOK_INT64: vTemp = vLineToks[ivPos].n64Value; opTemp = OPR_VAL; ivPos++; break; case TOK_DOUBLE: vTemp = vLineToks[ivPos].fValue; opTemp = OPR_VAL; ivPos++; break; case TOK_KEYWORD: switch (vLineToks[ivPos].nValue) { case K_AND: opTemp = OPR_LOGAND; ivPos++; break; case K_OR: opTemp = OPR_LOGOR; ivPos++; break; case K_NOT: opTemp = OPR_NOT; ivPos++; break; default: // End of expression (non expression keyword encountered) opTemp = OPR_END; break; } break; case TOK_FUNCTION: // Call function if ( AUT_FAILED(Parser_FunctionCall(vLineToks, ivPos, vTemp)) ) return AUT_ERR; opTemp = OPR_VAL; break; case TOK_USERFUNCTION: // Call user function if ( AUT_FAILED(Parser_UserFunctionCall(vLineToks, ivPos, vTemp)) ) return AUT_ERR; opTemp = OPR_VAL; break; case TOK_VARIABLE: if ( AUT_FAILED(Parser_EvaluateVariable(vLineToks, ivPos, vTemp)) ) return AUT_ERR; opTemp = OPR_VAL; break; case TOK_MACRO: if ( AUT_FAILED(Parser_EvaluateMacro(vLineToks[ivPos++].szValue, vTemp)) ) { FatalError(IDS_AUT_E_MACROUNKNOWN, vLineToks[ivPos-1].m_nCol); return AUT_ERR; } opTemp = OPR_VAL; break; default: // End of expression (non expression character encountered) opTemp = OPR_END; break; } // Update previous operator (used for checking for unary minus and tracking AND/OR) opPrev = opTemp; // Input is value? if (opTemp == OPR_VAL) { // Shift token to value stack then continue valStack.push(vTemp); continue; } // Input is operator, check the rules table based on the last operator (top of stack) // and the current operator to find out what to do next bLastOpWasReduce = true; while (bLastOpWasReduce == true) { bLastOpWasReduce = false; // Exit on next loop unless a Reduce operator occurs switch ( m_PrecOpRules[opStack.top()][opTemp] ) { case R: // Reduce // Standard Reduce if ( AUT_FAILED( Parser_OprReduce(opStack, valStack) ) ) { // Print message and quit FatalError(IDS_AUT_E_EXPRESSION, nColTemp); return AUT_ERR; } bLastOpWasReduce = true; // Loop again with this operator break; case RP: // Reduce parenthesis // Special case for ), reduce until we find ( while (opStack.top() != OPR_LPR) { if (opStack.top() == OPR_END) { FatalError(IDS_AUT_E_UNBALANCEDPAREN, nColTemp); return AUT_ERR; } else { // Standard Reduce if ( AUT_FAILED( Parser_OprReduce(opStack, valStack) ) ) { // Print message and quit FatalError(IDS_AUT_E_EXPRESSION, nColTemp); return AUT_ERR; } } } opStack.pop(); // Pop the ( break; case S: // Shift opStack.push(opTemp); break; case A: // Accept (finish) if (valStack.size() != 1) { // Syntax error, print message and quit FatalError(IDS_AUT_E_EXPRESSION, nColTemp); return AUT_ERR; } else { vResult = valStack.top(); valStack.pop(); return AUT_OK; } case E1: FatalError(IDS_AUT_E_RIGHTPAREN, nColTemp); return AUT_ERR; case E2: FatalError(IDS_AUT_E_MISSINGOP, nColTemp); return AUT_ERR; case E3: FatalError(IDS_AUT_E_UNBALANCEDPAREN, nColTemp); return AUT_ERR; } // End Switch } // End While (reducing loop) // We have just done an operation, which may have resulted in the stacks being reduced. // Check if the last operator (opPrev) was a logical comparision AND/OR. If it was then // because AND/OR is the lowest precedence the stacks WILL have just been reduced above. // Make a note of the boolean result (either 1 or 0 based on current top of value stack) // and then decide if we need to skip up until the END or next boolean operation - // whichever comes first if (valStack.size() && (opPrev == OPR_LOGAND || opPrev == OPR_LOGOR) ) { vTemp = valStack.top(); // Get the current top value // Skip the rest of the comparision if true + OR, or false + AND //if ( (vTemp.nValue() && opPrev == OPR_LOGOR) || (!vTemp.nValue() && opPrev == OPR_LOGAND) ) if ( (vTemp.isTrue() && opPrev == OPR_LOGOR) || (!vTemp.isTrue() && opPrev == OPR_LOGAND) ) { if ( AUT_FAILED( Parser_SkipBoolean(vLineToks, ivPos) ) ) { FatalError(IDS_AUT_E_EXPRESSION, nColTemp); // Unbalanced () usually causes an error return AUT_ERR; } // "Fix" our value on the value stack to be 1 or 0 (as the Reduce algorithm would have) valStack.pop(); if (opPrev == OPR_LOGOR) vTemp = 1; // Must be 1 if we skipped for an OR operator! else vTemp = 0; // or 0 for an AND valStack.push(vTemp); // Put the result back on the value stack // Remove the And/Or from the operator stack and proceed as if nothing happened opStack.pop(); } } } // End While(1) return AUT_OK; } // Parser_EvaluateExpression()
AUT_RESULT AutoIt_Script::Parser_OprReduce(StackInt &opStack, StackVariant &valStack) { Variant vOp1, vOp2; // Check that minimum number of values are on the stack for the operator to // be used if ( (opStack.top() == OPR_NOT || opStack.top() == OPR_UMI || opStack.top() == OPR_UPL) && valStack.size() < 1 ) return AUT_ERR; if ( (opStack.top() != OPR_NOT && opStack.top() != OPR_UMI && opStack.top() != OPR_UPL ) && valStack.size() < 2 ) return AUT_ERR; // Now perform the required operator function switch ( opStack.top() ) { case OPR_GTR: // Comparision vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if (vOp1 > vOp2) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_LESS: // Comparision vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if (vOp1 < vOp2 ) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_GTREQUAL: // Comparision vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if ( (vOp1 > vOp2) || (vOp1 == vOp2) ) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_LESSEQUAL: // Comparision vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if ( (vOp1 < vOp2) || (vOp1 == vOp2) ) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_NOTEQUAL: // Comparision vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if (vOp1 == vOp2 ) vOp1 = 0; else vOp1 = 1; valStack.push(vOp1); break; case OPR_EQUAL: // Comparision (=) not case sensitive vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if (vOp1 == vOp2) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_STRINGEQUAL: // String comparision (==) (force string and case sense) vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if ( vOp1.StringCompare(vOp2) ) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_CONCAT: // Concatenation vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); vOp1.Concat(vOp2); valStack.push(vOp1); break; case OPR_LOGAND: // Logical AND vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if (vOp1 && vOp2) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_LOGOR: // Logical OR vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if (vOp1 || vOp2) vOp1 = 1; else vOp1 = 0; valStack.push(vOp1); break; case OPR_NOT: // Unary NOT vOp1 = valStack.top(); valStack.pop(); vOp1 = !vOp1; valStack.push(vOp1); break; case OPR_ADD: // Addition + vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); vOp1 += vOp2; valStack.push(vOp1); break; case OPR_UPL: // Unary plus break; case OPR_SUB: // Subraction - vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); vOp1 -= vOp2; valStack.push(vOp1); break; case OPR_UMI: // Unary minus vOp1 = valStack.top(); valStack.pop(); vOp2 = -1; vOp1 *= vOp2; valStack.push(vOp1); // Multiply by -1 break; case OPR_MUL: // Multiplication * vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); vOp1 *= vOp2; valStack.push(vOp1); break; case OPR_DIV: // Division / vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); vOp1 /= vOp2; valStack.push(vOp1); break; case OPR_POW: // ^ vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if ( vOp2.fValue() == 0.0 ) vOp1 = 1.0; else if ( vOp1.fValue() == 0.0 && vOp2.fValue() < 0.0) { //double fTmp = 0.0; // needed to prevent compiler error. //vOp1 = 1.0/fTmp; // invalid. Return 1.#INF by forcing divide by 0. GIVES COMPILER WARNING vOp1 = 0.0; } else if ( vOp1.fValue() < 0.0 && (vOp2.type() == VAR_INT32 || vOp2.type() == VAR_INT64) ) // integer (32 or 64 bit) { #ifdef _MSC_VER // MS Compiler vOp1 = qmathPow(qmathFabs(vOp1.fValue()), vOp2.fValue()); #else vOp1 = pow(fabs(vOp1.fValue()), vOp2.fValue()); #endif if (vOp2.nValue() & 1) // odd number { vOp2 = -1.0; vOp1 *= vOp2; } } else #ifdef _MSC_VER // MS Compiler vOp1 = qmathPow(vOp1.fValue(), vOp2.fValue()); #else vOp1 = pow(vOp1.fValue(), vOp2.fValue()); #endif valStack.push(vOp1); break; } // Remove top operator from stack opStack.pop(); return AUT_OK; } // Parser_OprReduce()
bool eval( int & answer, const string & line ) { bool shifter = false; int openparen = 0, leftshift = 0, rightshift = 0, ast = 0, plu = 0; StackInt st; int test1 = 0; string token; istringstream sin( line ); sin >> token; for(int i = 0; i < line.length(); i++) { if(shifter == true) { if(line[i] != '(' && !(line[i] >= '0' && line[i] <= '9')) { //cout << "Law Breaker: " << line[i] << endl; return false; } //shifter = false; } if(line[i] == '(') { openparen++; st.push(oparen); } else if(line[i] == '>' || line[i] == '<') { if(line[i] == '>') { rightshift++; } else if (line[i] == '<') { leftshift++; } while(line[i+1] == '>' || line[i+1] == '<') { if(line[i+1] == '>') { rightshift++; } else if (line[i+1] == '<') { leftshift++; } i++; } shifter = true; continue; } else if(line[i] == '*') { st.push(times); } else if(line[i] == '+') { st.push(plussign); } else if(line[i] >= '0' && line[i] <= '9') { test1 = (line[i] - 48); while(line[i+1] >= '0' && line[i+1] <= '9') { //cout << "Test 1: " << test1 << " Line i: " << line[i] << " i +1: " << line[i+1] << endl; test1 = (test1*10) + (line[i+1]-48); i++; } st.push(test1); if(shifter == true) { int power = 0; test1 = st.top(); st.pop(); if(rightshift < leftshift) { power = leftshift - rightshift; test1 = test1 * pow(2,power); //cout << test1 << endl; //st.push(test1); } else if (leftshift < rightshift) { power = rightshift - leftshift; test1 = test1 / pow(2, power); } st.push(test1); //cout << "TOP: " << st.top() << endl; leftshift = rightshift = 0; shifter = false; } } else if(line[i] == ')') { int lhs = 0, rhs = 0, oper = 0, temp = 0, val = -1; rhs = st.top(); st.pop(); //cout << "TEST SPOT : " << st.top() << endl; oper = st.top(); if( oper > 0) { return false; } else { st.pop(); lhs = st.top(); st.pop(); val = mathop(lhs, rhs, oper); if(val < 0) { return false; } if(st.top() == -1) { openparen--; st.pop(); } st.push(val); } } } if(openparen == 0) { answer = st.top(); st.pop(); if(st.empty()) { return true; } } else return false; /*cout << openparen << ", " << leftshift << ", " << rightshift << endl; cout << "Numbers: " << st.top() << endl; */ } // evaluate