PNode* SLRParser::reduceExp(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Exp";

	//Simple-exp
	auto q_simpleexp = parsing_stack.top().node;
	//res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	if(parsing_stack.top().cell.row.id == "Comparison-op")
	{
		//Comparison-op
		auto q_comparisonop = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();
		//Simple-exp
		auto q_simpleexp2 = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();

		res->addChild(q_simpleexp2);
		res->addChild(q_comparisonop);
		res->addChild(q_simpleexp);
	}else{
		res->addChild(q_simpleexp);
	}
	return res;
}
PNode* SLRParser::reduceRepeatstmt(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Repeatstmt";

	//Exp
	auto q_exp = parsing_stack.top().node;
	//res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	//UNTIL
	reduceMatch(parsing_stack);
	//res->addChild(reduceMatch(parsing_stack));
	//StSeq
	auto q_stseq = parsing_stack.top().node;
	//res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	//REPEAT
	reduceMatch(parsing_stack);
	//res->addChild(reduceMatch(parsing_stack));

	res->addChild(q_stseq);
	res->addChild(q_exp);

	return res;
}
PNode* SLRParser::reduceTerm(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Term";

	//Factor
	auto q_factor = parsing_stack.top().node;
	//res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	if(parsing_stack.top().cell.row.id == "Mulop")
	{
		//Mulop
		auto q_mulop = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();
		//Term
		auto q_term = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();

		res->addChild(q_term);
		res->addChild(q_mulop);
		res->addChild(q_factor);
	}else
	{
		res->addChild(q_factor);
	}

	return res;
}
PNode* SLRParser::reduceFactor(std::stack<stackElement>& parsing_stack)
{
	stackElement e= parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Factor";

	if(e.cell.row.id == "OPEN_PAREN")
	{
		//OPEN_PAREN
		//res->addChild(reduceMatch(parsing_stack));
		auto q_openparen = reduceMatch(parsing_stack);
		//Exp
		res->addChild(parsing_stack.top().node);
		parsing_stack.pop();
		//CLOSE_PAREN
		//res->addChild(reduceMatch(parsing_stack));
		auto q_closeparen = reduceMatch(parsing_stack);
	}else if(e.cell.row.id == "NUMBER")
	{
		//NUMBER
		res->addChild(reduceMatch(parsing_stack));
	}else if(e.cell.row.id == "ID")
	{
		//ID
		res->addChild(reduceID(parsing_stack));
	}
	return res;
}
PNode* SLRParser::reduceIFstmt(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "IFstmt";

	//END
	reduceMatch(parsing_stack);
	//res->addChild(reduceMatch(parsing_stack));
	//StSeq
	auto q_stseq1 = parsing_stack.top().node;
	//res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	if(parsing_stack.top().cell.row.id == "THEN")
	{
		//THEN
		reduceMatch(parsing_stack);
		//res->addChild(reduceMatch(parsing_stack));
		//Exp
		auto q_exp = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();
		//IF
		reduceMatch(parsing_stack);
		//res->addChild(reduceMatch(parsing_stack));

		res->addChild(q_exp);
		res->addChild(q_stseq1);
	}else if(parsing_stack.top().cell.row.id == "ELSE")
	{
		//ELSE
		reduceMatch(parsing_stack);
		//res->addChild(reduceMatch(parsing_stack));
		//StSeq
		auto q_stseq2 = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();
		//THEN
		reduceMatch(parsing_stack);
		//res->addChild(reduceMatch(parsing_stack));
		//Exp
		auto q_exp = parsing_stack.top().node;
		//res->addChild(parsing_stack.top().node);
		parsing_stack.pop();
		//IF
		reduceMatch(parsing_stack);
		//res->addChild(reduceMatch(parsing_stack));

		res->addChild(q_exp);
		res->addChild(q_stseq2);
		res->addChild(q_stseq1);
	}

	return res;
}
PNode* SLRParser::reduceStatement(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "";
	res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	return res;
}
PNode* SLRParser::reduceReadstmt(std::stack<stackElement>& parsing_stack)
{
	PNode* id = reduceID(parsing_stack);
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "read-stmt";
	res->addChild(id);
	parsing_stack.pop();
	return res;
}
PNode* SLRParser::reduceComparison(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Comparison-op";

	//LESS_THAN || EQUAL
	res->addChild(reduceMatch(parsing_stack));

	return res;
}
PNode* SLRParser::reduceAddop(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Addop";

	//ADD_OP || MINUS_OP
	res->addChild(reduceMatch(parsing_stack));

	return res;
}
PNode* SLRParser::reduceAssignstmt(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Assignstmt";

	//Exp
	auto q_exp = parsing_stack.top().node;
	//res->addChild(parsing_stack.top().node);
	parsing_stack.pop();
	//ASSIGNMENT_OP
	reduceMatch(parsing_stack);
	//res->addChild(reduceMatch(parsing_stack));
	//ID
	auto q_id = reduceID(parsing_stack);
	//res->addChild(reduceID(parsing_stack));

	res->addChild(q_id);
	res->addChild(q_exp);

	return res;
}
PNode* SLRParser::reduceStSeq(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "StSeq";
	//statement
	auto q_stmt = parsing_stack.top().node;
	parsing_stack.pop();
	if(parsing_stack.top().cell.row.id == "SEMICOLON"){
		//semicolon
		//res->addChild(reduceMatch(parsing_stack));
		auto q_semicolon = reduceMatch(parsing_stack);
		//stseq
		auto q_stseq = parsing_stack.top().node;
		parsing_stack.pop();

		res->addChild(q_stseq);
		res->addChild(q_stmt);
	}else{
		res->addChild(q_stmt);
	}
	return res;
}
PNode* SLRParser::reduceWritestmt(std::stack<stackElement>& parsing_stack)
{
	stackElement e = parsing_stack.top();
	PNode* res = Services::memory->alloc<PNode>();
	new (res) PNode();
	res->Tag = "Writestmt";

	//Exp
	res->addChild(parsing_stack.top().node);
	parsing_stack.pop();

	//WRITE
	reduceMatch(parsing_stack);
	//res->addChild(reduceMatch(parsing_stack));

	return res;
}