void eval_exp(char *exp, int len){ //Using two stacks stack *n_stack=NULL;//number stack int i=0;//counter for the above array double n;//To store the converted number char c;//To store the character in the expression double x=1.0, y=1.0; //Making changes so that the end and beginning of the exoression can be identified stack *o_stack=NULL; push_operator('{', &o_stack);;//initializing the first value of o_stack strcat(exp,"}"); ++len; while(isnotempty(o_stack)){ c=exp[i]; if(isdigit(c)){ n=atof((exp+i));//Getting the entire number while(isdigit(c)||c=='.'){ ++i; c=exp[i]; } --i;//The last increment takes an extra character from the expression //Pushing into n stack push_number(n, &n_stack); } else{ if(c=='}'){//End of the expression while(top_operator(o_stack)!='{'){ //Updating stacks after computation eval(&n_stack, &o_stack, &x, &y); } pop_operator(&o_stack);//poping the '{' from the o_stack } else if(c==')'){//Priority of parenthesis while(top_operator(o_stack)!='('){ //updating stacks after computation eval(&n_stack, &o_stack, &x, &y); } pop_operator(&o_stack);//popping the '(' operator from the o_stack } else if(in_stack_priority(top_operator(o_stack))>=out_stack_priority(c)){ do{ //Pooping elements and taking temporary values eval(&n_stack, &o_stack, &x, &y); }while(in_stack_priority(top_operator(o_stack))>=out_stack_priority(c)); push_operator(c, &o_stack);//Pushing the new operator into the o_stack } else{//Pushing the operator in the o_stack push_operator(c, &o_stack); } } ++i;//incrementing the counter } //returning the final result printf("\nThe value of x is %lf and y is %lf.\nThe value of the expression is: %lf\n", x, y, pop_number(&n_stack)); }
std::string derivative(const std::string& polynomial) { std::map<std::string, coef_type, std::greater<std::string>> ans; std::vector<Token> stack; bool is_negative = false; for (auto cit = polynomial.cbegin(); cit != polynomial.cend(); ++cit) { if (isspace(*cit)) { skip_whitespace(cit); if (cit == polynomial.cend()) { break; } } switch (*cit) { case '+': case '-': { if (stack.size() > 0) { auto func = pop_function(stack); if (func.first != "0") { add_to_ans(ans, func); } } push_operator(stack, *cit); break; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { push_number(stack, get_int(cit), Token::Kind::COEF); // get back because we get over the last digit character --cit; break; } case '*': break; case 'x': push_variable(stack, *cit); break; case '^': // TODO: Now I do not want to deal with the separate power token, now it is skipped // But might be changed somehow ++cit; skip_whitespace(cit); push_number(stack, get_int(cit), Token::Kind::EXP); --cit; break; default: std::cerr << "Unknown character" << std::endl; break; } } if (stack.size()) { auto func = pop_function(stack); if (func.first != "0") { add_to_ans(ans, func); } } return answer(ans); }
void test_scored_subexpression() { // Create a database with the default options. auto db = grnxx::open_db(""); // Create a table with the default options. auto table = db->create_table("Table"); constexpr size_t NUM_ROWS = 1 << 16; // Generate random values. grnxx::Array<grnxx::Float> float_values; grnxx::Array<grnxx::Int> ref_values; float_values.resize(NUM_ROWS); ref_values.resize(NUM_ROWS); for (size_t i = 0; i < NUM_ROWS; ++i) { float_values[i] = grnxx::Float(1.0 * rng() / rng.max()); // ref_values[i] = mersenne_twister() % NUM_ROWS; ref_values[i] = grnxx::Int(0); } // Create columns for Float and Int values. auto float_column = table->create_column("Float", GRNXX_FLOAT); grnxx::ColumnOptions options; options.reference_table_name = "Table"; auto ref_column = table->create_column("Ref", GRNXX_INT, options); // Store generated values into columns. for (size_t i = 0; i < NUM_ROWS; ++i) { grnxx::Int row_id = table->insert_row(); assert(row_id.match(grnxx::Int(i))); float_column->set(row_id, float_values[i]); } for (size_t i = 0; i < NUM_ROWS; ++i) { ref_column->set(grnxx::Int(i), ref_values[i]); } // Generate a list of records. grnxx::Array<grnxx::Record> records; auto cursor = table->create_cursor(); assert(cursor->read_all(&records) == table->num_rows()); // Set scores (Float). auto builder = grnxx::ExpressionBuilder::create(table); builder->push_column("Float"); auto expression = builder->release(); expression->adjust(&records); // Test an expression (Ref.(_score > 0.5)). builder->push_column("Ref"); builder->begin_subexpression(); builder->push_score(); builder->push_constant(grnxx::Float(0.5)); builder->push_operator(GRNXX_GREATER); builder->end_subexpression(); expression = builder->release(); expression->filter(&records); size_t count = 0; for (size_t i = 0; i < NUM_ROWS; ++i) { if (float_values[i].raw() > 0.5) { assert(records[count].row_id.match(grnxx::Int(i))); ++count; } } assert(records.size() == count); }
double in_eval(char *exp) { int exp_length = strlen(exp), numOfVars = 0; struct operator_stack *os = create_operator_stack(exp_length / 2); char *token, *copy, *vars[10] = {NULL}, rpn_exp[1024] = ""; double value = 0; copy = (char *) malloc(sizeof(char) * exp_length); strcpy(copy, exp); token = strtok(copy, " "); bool previousIsOperator = false, previousIsLeftParenthese = false, varsSet = false; while (token != NULL) { errorOccurs = true; varsSet = false; if (isNumeric(token) && sscanf(token, "%lf", &value) > 0) { if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value; for (int i = 0; i < numOfVars; i++) { setVariable(vars[i], value); vars[i] = NULL; varsSet = true; } numOfVars = 0; errorOccurs = false; previousIsOperator = false; previousIsLeftParenthese = false; concat_double(rpn_exp, value); } else if (variableValid(token)) { if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value; char operator = *(token + strlen(token) + 1); if (operator == '=') { vars[numOfVars++] = token; errorOccurs = false; } else { value = getVariable(token); errorOccurs = !variableExists(token); concat_double(rpn_exp, value); } previousIsOperator = false; previousIsLeftParenthese = false; } else if (isOperator(token) || isParenthese(token)) { if ((isOperator(token) && previousIsOperator) || (strcmp(token, ")") == 0 && strlen(rpn_exp) == 0)) return value; if (numOfVars > 0) return value; char *op = NULL; if (strcmp(token, "(") == 0) { push_operator(os, token); previousIsLeftParenthese = true; } else if (strcmp(token, ")") == 0) { op = peek_operator(os); if (strcmp(op, "(") == 0) return value; op = pop_operator(os); while (strcmp(op, "(") != 0) { if (strcmp(op, ")") == 0) return value; concat_operator(rpn_exp, op); op = pop_operator(os); } previousIsLeftParenthese = false; } else { int pre1 = -1, pre2 = getOperatorPrecedence(token); if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os)); while (pre2 > pre1 && pre1 > 0 && os->top > -1) { concat_operator(rpn_exp, pop_operator(os)); if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os)); } push_operator(os, token); previousIsOperator = true; previousIsLeftParenthese = false; } errorOccurs = false; } else if (strcmp(token, "=") == 0) { errorOccurs = false; } else { return value; } if (errorOccurs) return value; token = strtok(NULL, " "); } while (os->top > -1) concat_operator(rpn_exp, pop_operator(os)); free(copy); free_operator_stack(os); if (!(varsSet || errorOccurs)) value = rpn_eval(rpn_exp); return value; }
Status push_multiplication(Stack **operands, Stack **operators) { return push_operator(get_operator('*', OPERATOR_BINARY), operands, operators); }
Status parse(const Token *tokens, Stack **operands, Stack **operators, Stack **functions) { Status status = OK; const Token *token, *previous, *next; for (token = tokens, previous = &NO_TOKEN, next = token + 1; token->type != TOKEN_NONE; previous = token, token = next++) { switch (token->type) { case TOKEN_OPEN_PARENTHESIS: { // Implicit multiplication: "(2)(2)". if (previous->type == TOKEN_CLOSE_PARENTHESIS) { status = push_multiplication(operands, operators); } stack_push(operators, get_operator('(', OPERATOR_OTHER)); break; } case TOKEN_CLOSE_PARENTHESIS: { // Apply operators until the previous open parenthesis is found. bool found_parenthesis = false; while (*operators && status == OK && !found_parenthesis) { const Operator *operator = stack_pop(operators); if (operator->symbol == '(') { found_parenthesis = true; } else { status = apply_operator(operator, operands); } } if (!found_parenthesis) { status = ERROR_CLOSE_PARENTHESIS; } else if (*functions) { status = apply_function(stack_pop(functions), operands); } break; } case TOKEN_OPERATOR: { status = push_operator( get_operator(*token->value, get_arity(*token->value, previous)), operands, operators); break; } case TOKEN_NUMBER: { if (previous->type == TOKEN_CLOSE_PARENTHESIS || previous->type == TOKEN_NUMBER || previous->type == TOKEN_IDENTIFIER) { status = ERROR_SYNTAX; } else { status = push_number(token->value, operands); // Implicit multiplication: "2(2)" or "2a". if (next->type == TOKEN_OPEN_PARENTHESIS || next->type == TOKEN_IDENTIFIER) { status = push_multiplication(operands, operators); } } break; } case TOKEN_IDENTIFIER: { // The identifier could be either a constant or function. status = push_constant(token->value, operands); if (status == ERROR_UNDEFINED_CONSTANT && next->type == TOKEN_OPEN_PARENTHESIS) { stack_push(functions, token->value); status = OK; } else if (next->type == TOKEN_OPEN_PARENTHESIS || next->type == TOKEN_IDENTIFIER) { // Implicit multiplication: "a(2)" or "a b". status = push_multiplication(operands, operators); } break; } default: { status = ERROR_UNRECOGNIZED; } } if (status != OK) { return status; } } // Apply all remaining operators. while (*operators && status == OK) { const Operator *operator = stack_pop(operators); if (operator->symbol == '(') { status = ERROR_OPEN_PARENTHESIS; } else { status = apply_operator(operator, operands); } } return status; }
static int compile(scriptlet *s, const char *src) { compiletime c = (compiletime)calloc(1, sizeof(struct compiletime_)); c->s = s; s->it_codes = 0; token tok; while ((src = get_token(src, tok)) != 0) { int precedence = get_precedence(tok); if (precedence) { DEBUG printf("operator '%s' precedence=%d\n", tok, precedence); } else { DEBUG printf("operand '%s'\n", tok); } if (!precedence) { push_operand(c, tok); continue; } if (!strcmp(tok, "(")) { push_operator(c, tok, precedence); continue; } int top_precedence, discard = 0, empty_list; const char *top_op; while ((top_op = head_operator(c, &top_precedence, &empty_list)), !empty_list) { if (!strcmp(top_op, "(") && !strcmp(tok, ")")) { int operand_count; pop_operator(c, &operand_count); discard = 1; continue; } DEBUG printf("top_op = '%s' with precedence = %d\n", top_op, top_precedence); if (precedence > top_precedence) break; if (!compile_operator(c)) { free(c); return 0; } if (discard) break; } if (!discard) push_operator(c, tok, precedence); } int top_precedence, empty_list; const char *top_op; while ((top_op = head_operator(c, &top_precedence, &empty_list)), !empty_list ) { DEBUG printf("top_op = '%s'\n", top_op); if (!compile_operator(c)) { free(c); return 0; } } free(c); return 1; }
command_stream_t make_command_stream (int (*get_next_byte) (void *), void *get_next_byte_argument) { char *operators[] = { "&&", "||", "|", "(", ")", ";" };//, "\n" }; int precedences[] = { 1, 1, 2, 4, -1, 0, 0 }; int i, j, isOperator, numChars = 0, inComment = 0; int operatorNumber = 0; int possibleNewCommand = 0; unsigned int currentWordSize = 16 * sizeof(char); int lastOperatorWasRightP = 0; char *operand, *lastCommand, *currentWord = checked_malloc(16 * sizeof(char)); char c = (char) get_next_byte(get_next_byte_argument); command_t operand1, operand2; // Initialize command stream command_stream_t commandStream = checked_malloc(10 * sizeof(struct command)); commandStream->currentStreamSize = 10 * sizeof(struct command); commandStream->numCommands = 0; commandStream->currentCommand = 0; g_lineNumber = 0; init_stacks(); while(c != EOF) { //printf("loop entered\n"); if( c == '\n') { g_lineNumber++; } if(inComment) { if( c == '\n' ) { inComment = 0; c = get_next_byte(get_next_byte_argument); continue; } else { c = get_next_byte(get_next_byte_argument); continue; } } else if( c == '#' ) { inComment = 1; c = get_next_byte(get_next_byte_argument); continue; } /** * Basically if there is a non-operator followed by a newline, there is a possibility * that the current command is done. The current command will be over if the newline * is then followed by another non-operator. Also ignore newlines inside commands. */ //printf("possible New COmmand is set to %i\n",possibleNewCommand); if ( (!isOperator || lastOperatorWasRightP) && c == '\n') { possibleNewCommand = 1; //printf("PossibleNewCommand set to 1 char is %c\n",c); // Used if a new command is actually started to finish the current one lastCommand = currentWord; fpos_t pos; fgetpos(get_next_byte_argument, &pos); c = get_next_byte(get_next_byte_argument); if (c != '\n') { //printf("continuing after setting possibleNewCommand to 1\n"); // if(c == EOF) // printf("new character is EOF and num of operands left is %i\n",g_iOperand_stack_size); fsetpos(get_next_byte_argument, &pos); lastOperatorWasRightP = 0; continue; } else { g_lineNumber++; } } else if (c == '\n') { c = get_next_byte(get_next_byte_argument); //printf("Operator followed by newlien detected. continiuing\n"); lastOperatorWasRightP = 0; continue; } //printf("Checkpoint 2\n"); /** * This loop checks if the current char is an operator. If it is, we create the operator word * and then we check the next char in case of double char operators such as || or && */ lastOperatorWasRightP = 0; isOperator = 0; for (i = 0; i < 6; i++) { // check if start of an operator if (c == operators[i][0]) { isOperator = 1; operand = currentWord; // Save old operand before creating operator currentWord = checked_malloc(3 * sizeof(char)); // Create the operator word currentWord[0] = c; fpos_t pos; fgetpos(get_next_byte_argument, &pos); if (c == '|' || c == '&') { if(g_iOperand_stack_size <= 0 && numChars <= 0) error(1,0,"%i: Did not expect binary operator",g_lineNumber); char current_char = c; c = get_next_byte(get_next_byte_argument); currentWord[1] = c; currentWord[2] = '\0'; if (c == '|' && c == current_char) { i = OR; } else if (c == '&' && c == current_char) { i = AND; } else if( current_char == '&' && c != current_char) { //TODO: Throw syntax error here. Single &! //fprintf(stderr,"%i: Isolated & found. Not a valid word character, and it is not an &&",lineNumber); error(1,0,"%i: Isolated & found",g_lineNumber); } else { i = PIPE; currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } } else if( c == '(') { //printf("Found leftP\n"); i = LEFTP; currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } else if( c == ')') { //printf("Found rightP\n"); lastOperatorWasRightP = 1; i = RIGHTP; currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } else if( c == ';') { if(g_iOperand_stack_size <= 0 && numChars <= 0) error(1,0,"%i: Did not expect binary operator",g_lineNumber); currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } else { currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } break; } } /** * When we encounter an operator, we can create a simple command out of the previous word * if there was a word (operand) there. This should always happen?? */ if (isOperator) { //printf("isOperator\n"); if (numChars > 0) { operand[numChars] = '\0'; //printf("Pushed %s on operand stack\n", operand); //get rid of whitespaces in operand here. int onlyWhite = getRidOfExtraWhitespaces(operand); if(onlyWhite == 0) push_operand(createSimpleCommand(operand)); // printf("simple out of operand %s\n", operand); numChars = 0; } /** * While the top of the stack contains an operator with equal or higher precedance than the * operator we are currently dealing with, keeping popping one operator and two operands, * creating a command out of them, and pushing it onto the operand stack. */ //printf("Charly:top of stack is %i\n",operator_stack_top()); // if(operator_stack_top() == RIGHTP ) //eval stack until a LEFTP is found if(i == RIGHTP) { //printf("EvalStackuntilLeftP found. possibleNewCommand is %i\n",possibleNewCommand); evalStackUntilLeftP(); //printf("current char is %c\n",c); c = get_next_byte(get_next_byte_argument); //printf("nextchar is %c\n",c); continue; } while(g_iOperator_stack_size > 0 && g_iOperand_stack_size > 1 && (precedences[operator_stack_top()] >= precedences[i]) && ((operator_stack_top() != LEFTP) && i != RIGHTP )) { operand2 = pop_operand(); operand1 = pop_operand(); operatorNumber = pop_operator(); //printf("popped operands types %d %d\n", operand1->type, operand2->type); //printf("popped operator %s\n", operators[operatorNumber]); //printf("pushed type %d operand on stack\n", operatorNumber); push_operand(createCommand(operand1, operand2, operatorNumber)); } // Get the operator number for the current word for (j = 0; j < 6; j++) { if (strcmp(currentWord, operators[j]) == 0) { break; } } //printf("pushed operators %s %d on stack\n", currentWord, j); push_operator(j); currentWord = checked_malloc(3 * sizeof(char)); } else if (!possibleNewCommand) { //if last operator was rightP. do not run this. //printf("not a new command. new char is %c, numChars is %i, currentWordSize is %i\n",c,numChars,currentWordSize); if(c != ' ' || numChars > 0) { //printf("growing current word %s currentWordSize is %i and numChars is %i\n",currentWord,currentWordSize,numChars); // Grow current word which is an operand if necessary if ((numChars * sizeof(char)) >= currentWordSize) { //printf("doubling size of word %s\n",currentWord); currentWordSize *= 2; //char * buffer = checked_malloc(currentWordSize); //strncpy(buffer,currentWord,numChars); //free((void *)currentWord); //currentWord = checked_malloc(currentWordSize); //strncpy(currentWord,buffer,numChars); currentWord = checked_realloc(currentWord, currentWordSize );// for some reason this was messing up //printf("it is now %s\n",currentWord); } currentWord[numChars] = c; numChars++; } } else { //printf("Going to new command. operand stack size is %i\n",g_iOperand_stack_size); //printf("Operator stack size is %i. numChars is %i\n",g_iOperator_stack_size,numChars); //if(g_iOperand_stack_size <= 0) //{ // c = get_next_byte(get_next_byte_argument); // possibleNewCommand = 0; //continue; //} /** * This means that we are about to go onto a new command. We stop the current command and * finish building it with the lastCommand variable, and an operand/operator if necessary. * This command is then put into the command stream. */ lastCommand[numChars] = '\0'; //printf("Last Command getting rid of whites\n"); if(numChars > 0) { //printf("numchars is > 0 so word is %s\n",lastCommand); getRidOfExtraWhitespaces(lastCommand); push_operand(createSimpleCommand(lastCommand)); } else if(g_iOperand_stack_size <= 0) { c = get_next_byte(get_next_byte_argument); possibleNewCommand = 0; continue; } //else //{ // printf("numChars == 0 so we are continuing\n"); //continue // c = get_next_byte(get_next_byte_argument); // possibleNewCommand = 0; // continue; //} evalStack(); //printf("%s\n", "Finished one command"); if ((commandStream->numCommands * sizeof(struct command)) == commandStream->currentStreamSize) { commandStream->currentStreamSize *= 2; commandStream = checked_realloc(commandStream, commandStream->currentStreamSize); } command_t commandToPushToStream = pop_operand(); commandToPushToStream->status = -1; commandStream->stream[commandStream->numCommands] = commandToPushToStream; // TODO: if stack not empty, there was an error? commandStream->numCommands++; numChars = 0; currentWord = checked_malloc(3 * sizeof(char)); // prevent overwriting } //printf("PossibleNewCOmmand set to 0 right before checkpoint1\n"); c = get_next_byte(get_next_byte_argument); possibleNewCommand = 0; } //printf("Checkpoint1. possibleNEwCommand is %i num of operands is %i\n",possibleNewCommand,g_iOperand_stack_size); // Push last word onto operand stack and evaluate the rest if (!isOperator) { currentWord[numChars] = '\0'; //printf("pushed simple word %s with word count %i strlen is %i\n", currentWord,numChars,(int)strlen(currentWord)); getRidOfExtraWhitespaces(currentWord); if(strlen(currentWord) > 0) push_operand(createSimpleCommand(currentWord)); } else { // if a semicolon, valid? } //printf("evalstack at the end of loop\n"); evalStack(); // Put last command in command stream // if there is one! if(operand_stack_top() != NULL) { command_t commandToPushToStream = pop_operand(); commandToPushToStream->status = -1; commandStream->stream[commandStream->numCommands] = commandToPushToStream; commandStream->numCommands++; } //printf("Stack sizes: %d, %d\n", g_iOperator_stack_size, g_iOperand_stack_size); //printf("Final command type is %d\n", commandStream->stream[0]->type); return commandStream; }