/*************************************************************** * 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); }
/*************************************************************** * 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 ); }
/*************************************************************** * 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; }
/*************************************************************** * 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 ); }
/*************************************************************** * 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; }
/*************************************************************** * 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 ); }
/*************************************************************** * 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; }