shared_ptr<Statement> Parser::parseWhile() { shared_ptr<WhileStmt> whStmt = make_shared<WhileStmt>(); whStmt->value = *it; currNode = whStmt; it++; shared_ptr<Expression> cond = parseExpression(); whStmt->condition = cond; //it++; match(DO); it++; if (match(BEGIN)) { shared_ptr<Statement> body = parseStmtList(END); whStmt->body=body; match(END); it++; match(SEMI); } else { shared_ptr<Statement> body1 = parseStatement(); whStmt->body = body1; } return whStmt; }
shared_ptr<Statement> Parser::parseIf() { shared_ptr<IfStmt> ifstmt = make_shared<IfStmt>(); ifstmt->value = *it; currNode = ifstmt; it++; auto cond = parseExpression(); ifstmt->condition = cond; match(THEN); it++; if (match(BEGIN)) { currNode = ifstmt; shared_ptr<Statement> body = parseStmtList(END); ifstmt->thenBody=body; match(END); it++; match(SEMI); } else { shared_ptr<Statement> body1 = parseStatement(); ifstmt->thenBody = body1; } ifstmt->haveElse = false; while (advance(ELSE)) { ifstmt->haveElse = true; it++; shared_ptr<ElseStmt> elseStmt = static_pointer_cast<ElseStmt>(parseElse()); ifstmt->elseBody = elseStmt; } return ifstmt; }
shared_ptr<Statement> Parser::parseElse() { shared_ptr<ElseStmt> elseStmt = make_shared<ElseStmt>(); elseStmt->value = *it; it++; if (match(IF))//match if { shared_ptr<IfStmt> elseifnode = static_pointer_cast<IfStmt>(parseIf()); elseStmt->addNode(elseifnode); } else if (match(BEGIN))//match begin Compound Statement 复合语句 { shared_ptr<Statement> body = parseStmtList(END); elseStmt->body = body; match(END); it++; match(SEMI); } else//单行语句 { shared_ptr<Statement> body1 = parseStatement(); elseStmt->addNode(body1); } return elseStmt; }
/*************************************************************** * Function: CodeParser::parseWhileStmt() * Purpose : Parse the XML code of a while loop statement * Initial : Maxime Chevalier-Boisvert on November 8, 2008 **************************************************************** Revisions and bug fixes: */ Statement* CodeParser::parseWhileStmt(const XML::Element* pElement) { unsigned loopDepth = ++maxLoopDepth; // Parse the condition expression Expression* pCondExpr = parseExpression(pElement->getChildElement(0)); // Parse the loop body StmtSequence* pLoopBody = parseStmtList(pElement->getChildElement(1)); unsigned annotations = 0; // reset maxLoopDepth && currentDepth if (loopDepth == maxLoopDepth) { // isInnermost loop is true; annotations |= Statement::INNERMOST; } if (loopDepth == 1) { // isOutermost loop is true; annotations |= Statement::OUTERMOST; // reset the loop depth counter maxLoopDepth = 0; } // return the new for statement object return new WhileStmt(pCondExpr, pLoopBody, annotations); }
/*************************************************************** * Function: CodeParser::parseForStmt() * Purpose : Parse the XML code of a for loop statement * Initial : Maxime Chevalier-Boisvert on November 8, 2008 **************************************************************** Revisions and bug fixes: */ Statement* CodeParser::parseForStmt(const XML::Element* pElement) { unsigned loopDepth = ++maxLoopDepth; // Parse the assignment statement Statement* pAssignStmt = parseStatement(pElement->getChildElement(0)); // Ensure that this statement really is an assignment statement if (pAssignStmt->getStmtType() != Statement::ASSIGN) throw XML::ParseError("Invalid statement type", pElement->getChildElement(0)->getTextPos()); // Parse the loop body StmtSequence* pLoopBody = parseStmtList(pElement->getChildElement(1)); unsigned annotations = 0; // reset maxLoopDepth if (loopDepth == maxLoopDepth) { // isInnermost loop is true; annotations |= Statement::INNERMOST; } if (loopDepth == 1) { // isOutermost loop is true; annotations |= Statement::OUTERMOST; // reset the counters maxLoopDepth = 0; } // return the new for statement object return new ForStmt((AssignStmt*)pAssignStmt, pLoopBody, annotations); }
shared_ptr<Statement> Parser::parseRepeat() { shared_ptr<RepeatStmt> repeatStmt = make_shared<RepeatStmt>(); currNode = repeatStmt; shared_ptr<Statement> body=parseStmtList(UNTIL); repeatStmt->body = body; match(UNTIL); shared_ptr<Expression> cond = parseExpression(); repeatStmt->untilCond = cond; return repeatStmt; }
/*************************************************************** * 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 ); }
//lead into the program void Parser::parseBlock() { ++it; switch (it->tag) { case CONSTANT: parseConstant(); parseBlock(); break; case VAR: parseVariables(); parseBlock(); break; case TYPE: parseType(); parseBlock(); break; case FUNCTION: parseFunction(); parseBlock(); break; case PROCEDURE: parseProcedure(); parseBlock(); break; case BEGIN: { shared_ptr<Statement> block = parseStmtList(currNode == root ? FINISH : END); //root的block与函数的block if (currNode != root) { (static_pointer_cast<FunctionStmt>(currNode))->body=block; } else { block->value.value = "__Main__"; currNode->addNode(block); } bool tmp=it->tag == FINISH || it->tag == END; if (it->tag == END) { it++; match(SEMI); } } break; } }
shared_ptr<Statement> Parser::parseFor() { //for k=1 to 10 do shared_ptr<ForStmt> forStmt = make_shared<ForStmt>(); forStmt->value = *it; currNode = forStmt; it++; shared_ptr<AssignStmt> startVal = static_pointer_cast<AssignStmt>(parseStatement()); forStmt->startStmt = startVal; Tag direction=it->tag; forStmt->direction = direction; bool tmpCheck=find(TO)||find(DOWNTO); if (!tmpCheck) { Error err("syntax error", *it); errList.push_back(err); } it++; auto endVal = parseExpression(); forStmt->endValue = endVal; match(DO); it++; if (match(BEGIN)) { shared_ptr<Statement> body = parseStmtList(END); forStmt->body = body ; match(END); it++; match(SEMI); } else { shared_ptr<Statement> body1 = parseStatement(); forStmt->body = body1; } return forStmt; }
/*************************************************************** * 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; }