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);
}
Exemple #3
0
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);
}