/*************************************************************** * 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::parseAssignStmt() * Purpose : Parse the XML code of an assignment statement * Initial : Maxime Chevalier-Boisvert on November 5, 2008 **************************************************************** Revisions and bug fixes: */ Statement* CodeParser::parseAssignStmt(const XML::Element* pElement) { // Get the element corresponding to the left-expression XML::Element* pLeftElem = pElement->getChildElement(0); // Create a vector to store the left expressions AssignStmt::ExprVector leftExprs; // If the left expression is a matrix expression if (pLeftElem->getName() == "MatrixExpr") { // If the number of rows is not 1, throw an exception if (pLeftElem->getNumChildren() != 1) throw XML::ParseError("invalid matrix expression on assignment lhs"); // Get the row element XML::Element* pRowElem = pLeftElem->getChildElement(0); // For each left expression element for (size_t i = 0; i < pRowElem->getNumChildren(); ++i) { // Get the child element for this expression XML::Element* pExprElem = pRowElem->getChildElement(i); // Parse this left-expression leftExprs.push_back(parseExpression(pExprElem)); } } else { // Parse the left expression directly leftExprs.push_back(parseExpression(pLeftElem)); } // Parse the right expression Expression* pRightExpr = parseExpression(pElement->getChildElement(1)); // Get the output suppression flag bool suppressOut = pElement->getBoolAttrib("outputSuppressed"); // Create and return the new assignment statement object return new AssignStmt(leftExprs, pRightExpr, suppressOut); }
/*************************************************************** * 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::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; }