Esempio n. 1
0
/***************************************************************
* Function: CodeParser::parseCellArrayExpr()
* Purpose : Parse the XML code of a cell array expression
* Initial : Maxime Chevalier-Boisvert on February 23, 2009
****************************************************************
Revisions and bug fixes:
*/
Expression* CodeParser::parseCellArrayExpr(const XML::Element* pElement)
{
	// Declare a vector to store the rows
	CellArrayExpr::RowVector rowVector;

	// For each child element
	for (size_t i = 0; i < pElement->getNumChildren(); ++i)
	{
		// Declare a row to store elements
		CellArrayExpr::Row row;

		// Get a reference to this child element
		XML::Element* pRowElem = pElement->getChildElement(i);

		// If this is not a row element, throw an exception
		if (pRowElem->getName() != "Row")
			throw XML::ParseError("Invalid element found in cell array expression", pRowElem->getTextPos());

		// For each expression in this row
		for (size_t j = 0; j < pRowElem->getNumChildren(); ++j)
		{
			// Parse the expression and add it to the row
			row.push_back(parseExpression(pRowElem->getChildElement(j)));
		}

		// Add the row to the vector
		rowVector.push_back(row);
	}

	// Create and return the cell array expression
	return new CellArrayExpr(rowVector);
}
Esempio n. 2
0
/***************************************************************
* Function: CodeParser::parseLambdaExpr()
* Purpose : Parse the XML code of a lambda expression
* Initial : Maxime Chevalier-Boisvert on February 25, 2009
****************************************************************
Revisions and bug fixes:
*/
Expression* CodeParser::parseLambdaExpr(const XML::Element* pElement)
{
	// Create a vector for the input parameters
	LambdaExpr::ParamVector inParams;

	// Declare a pointer for the body expression
	Expression* pBodyExpr = NULL;

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

		// If this is a symbol
		if (pChildElem->getName() == "Name")
		{
			// Parse the symbol and add it to the input parameters
			inParams.push_back(SymbolExpr::getSymbol(pChildElem->getStringAttrib("nameId")));
		}

		// Otherwise, it must be the body expression
		else
		{
			// If the body expression was already parsed
			if (pBodyExpr != NULL)
			{
				// Throw an exception
				throw XML::ParseError("Duplicate body expression", pChildElem->getTextPos());
			}

			// Parse the body expression
			pBodyExpr = parseExpression(pChildElem);
		}
	}

	// If no body expression was found
	if (pBodyExpr == NULL)
	{
		// Throw an exception
		throw XML::ParseError("No body expression found", pElement->getTextPos());
	}

	// Create and return the new lambda expression
	return new LambdaExpr(
		inParams,
		pBodyExpr
	);
}
Esempio n. 3
0
/***************************************************************
* Function: CodeParser::parseFunction()
* Purpose : Parse the XML code of a function
* Initial : Maxime Chevalier-Boisvert on November 3, 2008
****************************************************************
Revisions and bug fixes:
*/
ProgFunction* CodeParser::parseFunction(const XML::Element* pElement)
{
	// Get the function name
	std::string funcName = pElement->getStringAttrib("name");

	// Declare a pointer for the sequence statement
	StmtSequence* pSequenceStmt = NULL;

	// Declare vectors for the input and output parameters
	ProgFunction::ParamVector inParams;
	ProgFunction::ParamVector outParams;

	// Declare a vector for the nested function list
	ProgFunction::FuncVector nestedFuncs;

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

		// If this is a symbol table
		if (pFuncElement->getName() == "Symboltable")
		{
			// Ignore for now
		}

		// If this is a parameter declaration list
		else if (pFuncElement->getName() == "ParamDeclList")
		{
			// Ignore for now
		}

		// If this is an input parameter list
		else if (pFuncElement->getName() == "InputParamList")
		{
			// For each child element
			for (size_t i = 0; i < pFuncElement->getNumChildren(); ++i)
			{
				// Get the parameter name
				const std::string& paramName = pFuncElement->getChildElement(i)->getStringAttrib("nameId");

				// Add the parameter to the list
				inParams.push_back(SymbolExpr::getSymbol(paramName));
			}
		}

		// If this is an output parameter list
		else if (pFuncElement->getName() == "OutputParamList")
		{
			// For each child element
			for (size_t i = 0; i < pFuncElement->getNumChildren(); ++i)
			{
				// Get the parameter name
				const std::string& paramName = pFuncElement->getChildElement(i)->getStringAttrib("nameId");

				// Add the parameter to the list
				outParams.push_back(SymbolExpr::getSymbol(paramName));
			}
		}

		// If this is a nested function list
		else if (pFuncElement->getName() == "NestedFunctionList")
		{
			// For each child element
			for (size_t i = 0; i < pFuncElement->getNumChildren(); ++i)
			{
				// Parse this function declaration
				ProgFunction* pFunction = parseFunction(pFuncElement->getChildElement(i));

				// Add the nested function to the list
				nestedFuncs.push_back(pFunction);
			}
		}

		// If this is the statement list
		else if (pFuncElement->getName() == "StmtList")
		{
			// If the statement list was already encountered, throw an exception
			if (pSequenceStmt != NULL)
				throw XML::ParseError("Duplicate statement list", pElement->getTextPos());

			// Parse the statement list
			pSequenceStmt = parseStmtList(pFuncElement);
		}

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

	// If the statement list is missing, throw an exception
	if (pSequenceStmt == NULL)
		throw XML::ParseError("Missing statement list", pElement->getTextPos());

	// Create a new program function object
	ProgFunction* pNewFunc = new ProgFunction(
		funcName,
		inParams,
		outParams,
		nestedFuncs,
		pSequenceStmt
	);

	// For each nested function
	for (ProgFunction::FuncVector::iterator nestItr = nestedFuncs.begin(); nestItr != nestedFuncs.end(); ++nestItr)
	{
		// Set the parent pointer to the newly created function object
		(*nestItr)->setParent(pNewFunc);
	}

	// Return the new program function object
	return pNewFunc;
}
Esempio n. 4
0
/***************************************************************
* Function: CodeParser::parseScript()
* Purpose : Parse the XML code of a script
* Initial : Maxime Chevalier-Boisvert on November 4, 2008
****************************************************************
Revisions and bug fixes:
*/
IIRNode* CodeParser::parseScript(const XML::Element* pElement)
{
	// Declare a pointer for the sequence statement
	StmtSequence* pSequenceStmt = NULL;

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

		// If this is a symbol table
		if (pFuncElement->getName() == "Symboltable")
		{
			// Ignore for now
		}

		// If this is the statement list
		else if (pFuncElement->getName() == "StmtList")
		{
			// If the statement list was already encountered, throw an exception
			if (pSequenceStmt != NULL)
				throw XML::ParseError("Duplicate statement list", pElement->getTextPos());

			// Parse the statement list
			pSequenceStmt = parseStmtList(pFuncElement);
		}

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

	// If the statement list is missing, throw an exception
	if (pSequenceStmt == NULL)
		throw XML::ParseError("Missing statement list", pElement->getTextPos());

	// Create and return a new program function object
	return new ProgFunction(
		"",
		ProgFunction::ParamVector(),
		ProgFunction::ParamVector(),
		ProgFunction::FuncVector(),
		pSequenceStmt,
		true
	);
}
Esempio n. 5
0
/***************************************************************
* Function: CodeParser::parseScript()
* Purpose : Parse the XML root element
* Initial : Maxime Chevalier-Boisvert on November 18, 2008
****************************************************************
Revisions and bug fixes:
*/
CompUnits CodeParser::parseXMLRoot(const XML::Element* pTreeRoot)
{
	// Create a list to store parsed functions
	CompUnits functionList;

	// If the root tag is not the compilation units, throw an exception
	if (pTreeRoot->getName() != "CompilationUnits")
	{
		// TODO: implement error list parsing
		std::cout << "XML tree: " << pTreeRoot->toString(true, 0) << std::endl;
		
		throw XML::ParseError("Expected compilation units: \"" + pTreeRoot->getName() + "\"", pTreeRoot->getTextPos());
	}

	// If the verbose output flag is set
	if (ConfigManager::s_verboseVar.getBoolValue() == true)
	{
		// Log the number of compilation units
		std::cout << "Number of compilation units: " << pTreeRoot->getNumChildren() << std::endl;
	}

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

		// If this is a function list
		if (pUnitElement->getName() == "FunctionList")
		{
			// Get the list of functions
			const std::vector<XML::Node*>& functions = pUnitElement->getChildren();

			// For each function
			for (std::vector<XML::Node*>::const_iterator itr = functions.begin(); itr != functions.end(); ++itr)
			{
				// If this is not an XML element, throw an exception
				if ((*itr)->getType() != XML::Node::ELEMENT)
					throw XML::ParseError("Unexpected XML node type in function list");

				// Get a pointer to this element
				XML::Element* pFuncElement = (XML::Element*)*itr;

				// If this ia a function declaration
				if (pFuncElement->getName() == "Function")
				{
					// Parse the function
					IIRNode* pNewNode = parseFunction(pFuncElement);

					// Add the function to the list
					functionList.push_back(pNewNode);
				}

				// If this is a symbol table
				else if (pFuncElement->getName() == "Symboltable")
				{
					// Ignore for now
				}

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

		// If this is a script
		else if (pUnitElement->getName() == "Script")
		{
			// Parse the script
			IIRNode* pNewNode = parseScript(pUnitElement);

			// Add the function to the list
			functionList.push_back(pNewNode);
		}

		// Otherwise
		else
		{
			// This is an invalid element, throw an exception
			throw XML::ParseError("Invalid element in compilation unit list: \"" + pUnitElement->getName() + "\"", pUnitElement->getTextPos());
		}
	}

	// If the verbose output flag is set
	if (ConfigManager::s_verboseVar.getBoolValue() == true)
	{
		// Output parsed IIR
		std::cout << std::endl;
		std::cout << "Constructed IIR:" << std::endl;
		for (CompUnits::iterator itr = functionList.begin(); itr != functionList.end(); ++itr)
			std::cout << ((*itr) == NULL? "NULL":(*itr)->toString()) << std::endl << std::endl;
		std::cout << std::endl;

		// Log that the parsing was successful
		std::cout << "Parsing successful" << std::endl;
	}

	// Return the parsed function list
	return functionList;
}
Esempio n. 6
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
	);
}
Esempio n. 7
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;
}