Пример #1
0
/***************************************************************
* Function: CodeParser::parseSwitchStmt()
* Purpose : Parse the XML code of a switch statement
* Initial : Maxime Chevalier-Boisvert on February 23, 2009
****************************************************************
Revisions and bug fixes:
*/
Statement* CodeParser::parseSwitchStmt(const XML::Element* pElement)
{
	// Parse the switch expression
	Expression* pSwitchExpr = parseExpression(pElement->getChildElement(0));

	// Declare a case list for the switch cases
	SwitchStmt::CaseList caseList;

	// Declare a statement sequence pointer for the default case
	StmtSequence* pDefaultCase = NULL;

	// For each remaining child element
	for (size_t i = 1; i < pElement->getNumChildren(); ++i)
	{
		// Get a pointer to this child element
		XML::Element* pChildElem = pElement->getChildElement(i);

		// If this is a switch case block
		if (pChildElem->getName() == "SwitchCaseBlock")
		{
			// Parse the switch case contents and add the case to the list
			caseList.push_back(
				SwitchStmt::SwitchCase(
					parseExpression(pChildElem->getChildElement(0)),
					parseStmtList(pChildElem->getChildElement(1))
				)
			);
		}

		// If this is a default case block
		else if (pChildElem->getName() == "DefaultCaseBlock")
		{
			// If a default case was already parsed
			if (pDefaultCase != NULL)
			{
				// Throw an exception
				throw XML::ParseError("Duplicate default case in switch statement", pChildElem->getTextPos());
			}

			// Parse the statement list
			pDefaultCase = parseStmtList(pChildElem->getChildElement(0));
		}

		// Otherwise
		else
		{
			// This is an invalid element type, throw an exception
			throw XML::ParseError("Invalid element in switch statement: \"" + pChildElem->getName() + "\"", pChildElem->getTextPos());
		}
	}

	// If there is no default case, create an empty one
	if (pDefaultCase == NULL)
		pDefaultCase = new StmtSequence();

	// Create and return the switch statement object
	return new SwitchStmt(
		pSwitchExpr,
		caseList,
		pDefaultCase
	);
}
Пример #2
0
/***************************************************************
* Function: CodeParser::parseIfStmt()
* Purpose : Parse the XML code of an if statement
* Initial : Maxime Chevalier-Boisvert on November 5, 2008
****************************************************************
Revisions and bug fixes:
*/
Statement* CodeParser::parseIfStmt(const XML::Element* pElement)
{
	// Declare a vector to store the if blocks
	std::vector<XML::Element*> ifBlocks;

	// Declare a pointer for the else block
	XML::Element* pElseBlock = NULL;

	// For each child element
	for (size_t i = 0; i < pElement->getNumChildren(); ++i)
	{
		// Get a pointer to this element
		XML::Element* pIfElement = pElement->getChildElement(i);

		// If this is an if block
		if (pIfElement->getName() == "IfBlock")
		{
			// Add it to the list
			ifBlocks.push_back(pIfElement);
		}

		// If this is an else block
		else if (pIfElement->getName() == "ElseBlock")
		{
			// If there is more than one else block, throw an exception
			if (pElseBlock)
				throw XML::ParseError("Duplicate else block", pIfElement->getTextPos());

			// Store a pointer to the else block
			pElseBlock = pIfElement;
		}

		// Otherwise
		else
		{
			// This is an invalid element type, throw an exception
			throw XML::ParseError("Invalid element in if statement: \"" + pIfElement->getName() + "\"", pIfElement->getTextPos());
		}
	}

	// If are are no if blocks, throw an exception
	if (ifBlocks.size() == 0)
		throw XML::ParseError("Missing if block", pElement->getTextPos());

	// Get a pointer to the last if block
	XML::Element* pLastIfBlock = ifBlocks.back();

	// remove the last if block from the list
	ifBlocks.pop_back();

	// Create the first if-else statement from the last if and else blocks
	IfElseStmt* pIfStmt = new IfElseStmt(
			parseExpression(pLastIfBlock->getChildElement(0)),
			parseStmtList(pLastIfBlock->getChildElement(1)),
			pElseBlock? parseStmtList(pElseBlock->getChildElement(0)):(new StmtSequence())
	);

	// For each if block, in reverse order
	for (std::vector<XML::Element*>::reverse_iterator itr = ifBlocks.rbegin(); itr != ifBlocks.rend(); ++itr)
	{
		// Get a pointer to this if block element
		XML::Element* pIfBlock = *itr;

		// Add this if block to the recursive structure
		pIfStmt = new IfElseStmt(
			parseExpression(pIfBlock->getChildElement(0)),
			parseStmtList(pIfBlock->getChildElement(1)),
			new StmtSequence(pIfStmt)
		);
	}

	// Return a pointer to the if-else statement
	return pIfStmt;
}