void evaluate_stack(std::stack<stack_item*>* stack) { if (stack->size() <= 1) return; stack_item* top_item = stack->top(); stack->pop(); if (top_item->type == NODE) { assert(stack->top()->type == FUNC); if (stack->top()->function == '|') { stack->pop(); collapse_stack_strings(stack); evaluate_stack(stack); Node* newNode = new Node(ALTER); newNode->left = stack->top()->node; newNode->right = top_item->node; stack->top()->node = newNode; return; } else { evaluate_stack(stack); Node* newNode = new Node(CONCAT); newNode->left = stack->top()->node; newNode->right = top_item->node; stack->top()->node = newNode; return; } } else if (top_item->type == FUNC) { assert(stack->top()->type == NODE); if (top_item->function == '*') { Node* newNode = new Node(STAR); newNode->left = stack->top()->node; stack->top()->node = newNode; return; } else if (top_item->function == '+') { Node* newNode = new Node(PLUS); newNode->left = stack->top()->node; stack->top()->node = newNode; return; } else if (top_item->function == '?') { Node* newNode = new Node(QUESTION); newNode->left = stack->top()->node; stack->top()->node = newNode; return; } } }
void evaluate_stack_brackets(std::stack<stack_item*>* stack) { std::stack<stack_item*> stack1; while (stack->top()->function != '[') { stack1.push(stack->top()); stack->pop(); assert(!stack->empty()); } std::stack<stack_item*> itemStack; while (!stack1.empty()) { itemStack.push(stack1.top()); stack1.pop(); } std::stack<char> charStack; while (!itemStack.empty()) { assert(itemStack.top()->type != FUNC || itemStack.top()->function == '-'); if (itemStack.top()->type == NODE) { assert(itemStack.top()->node->type == CHR); charStack.push(itemStack.top()->node->data); itemStack.pop(); } else if (itemStack.top()->function == '-') { itemStack.pop(); assert(itemStack.top()->node->type == CHR); char firstChar = itemStack.top()->node->data; itemStack.pop(); char lastChar = charStack.top(); charStack.pop(); int a = std::min((int)firstChar, (int)lastChar); int b = std::max((int)firstChar, (int)lastChar); for (int i = a; i <= b; ++i) { charStack.push((char)i); } } } stack->pop(); while (!charStack.empty()) { stack->push(new stack_item(NODE, charStack.top())); stack->push(new stack_item(FUNC, '|')); charStack.pop(); } stack->pop(); //Remove trailing '|' evaluate_stack(stack); }
bool resolve_stack_from_parser(const object& operation_tree, bool resolve_entire_stack) { if(operation_tree.type == OPERATION_TREE) { Array* tree; // Copy for normal calls, DON'T copy if this is coming from the parser. We know this because the parser resolves the entire stack. // We don't copy the calls from the parser because it passes off ownership of the objects and doesn't free them itself. if(!resolve_entire_stack) { // object copy_tree = mem_copy(operation_tree); // object copy_tree = operation_tree; // tree = copy_tree.data.array; tree = operation_tree.data.array; } else { tree = operation_tree.data.array; } if(operation_tree.data.array->size() > 1) { std::reverse_copy(tree->begin(), tree->end(), std::inserter(optic_stack, optic_stack.end())); } else if(operation_tree.data.array->size() == 1) { optic_stack.push_back(tree->at(0)); } else { out() << "Error: No operations to put on the stack." << std::endl; correct_parsing = false; } // Free the Array* we created but not the actual contents because they will get freed on the stack // shallow_mem_free_array(tree, OPERATION_TREE); if(resolve_entire_stack) evaluate_stack(); else evaluate_top(); } }
void evaluate_stack_paren(std::stack<stack_item*>* stack) { std::stack<stack_item*> stack1; while (stack->top()->type == CHR || stack->top()->function != '(') { stack1.push(stack->top()); stack->pop(); assert(!stack->empty()); } std::stack<stack_item*> itemStack; while (!stack1.empty()) { itemStack.push(stack1.top()); stack1.pop(); } while (itemStack.size() > 1) { evaluate_stack(&itemStack); } stack->pop(); stack->push(itemStack.top()); }
Tree* build_tree_from_expression(std::string str) { int i = 0; std::stack<stack_item*> treeStack; int paren_depth = 0; int bracket_depth = 0; int brace_depth = 0; while (i < str.length()) { switch (str[i]) { case '\\': { i++; assert(i < str.length()); if (str[i] - '0' >= 0 && str[i] - '0' <= 9) { treeStack.push(new stack_item(FUNC, str[i])); } else { treeStack.push(new stack_item(NODE, control_character(str[i]))); } break; } case '(': { paren_depth++; treeStack.push(new stack_item(FUNC, str[i])); break; } case ')': { assert(paren_depth > 0); collapse_stack_strings(&treeStack); evaluate_stack_paren(&treeStack); paren_depth--; break; } case '[': { bracket_depth++; treeStack.push(new stack_item(FUNC, str[i])); break; } case ']': { assert(bracket_depth > 0); evaluate_stack_brackets(&treeStack); collapse_stack_strings(&treeStack); bracket_depth--; break; } case '{': { brace_depth++; treeStack.push(new stack_item(FUNC, str[i])); break; } case '}': { assert(brace_depth > 0); evaluate_stack_braces(&treeStack); collapse_stack_strings(&treeStack); brace_depth--; break; } case '^': { treeStack.push(new stack_item(FUNC, str[i])); break; } case '$': { treeStack.push(new stack_item(FUNC, str[i])); break; } case '.': { treeStack.push(new stack_item(FUNC, '[')); treeStack.push(new stack_item(NODE, (char)MIN_CHAR)); treeStack.push(new stack_item(FUNC, '-')); treeStack.push(new stack_item(NODE, (char)MAX_CHAR)); evaluate_stack_brackets(&treeStack); collapse_stack_strings(&treeStack); //treeStack.push(new stack_item(FUNC, str[i])); break; } case '*': { treeStack.push(new stack_item(FUNC, str[i])); break; } case '+': { treeStack.push(new stack_item(FUNC, str[i])); break; } case '?': { treeStack.push(new stack_item(FUNC, str[i])); break; } case '|': { treeStack.push(new stack_item(FUNC, str[i])); break; } case '-': { if (bracket_depth > 0) treeStack.push(new stack_item(FUNC, str[i])); else treeStack.push(new stack_item(NODE, str[i])); break; } default: { if (brace_depth > 0) { treeStack.push(new stack_item(FUNC, str[i])); assert(str[i] == ',' || (str[i] - '0' >= 0 && str[i] - '0' <= 9)); }else treeStack.push(new stack_item(NODE, str[i])); break; } } i++; } collapse_stack_strings(&treeStack); evaluate_stack(&treeStack); return new Tree(treeStack.top()->node); }