Пример #1
0
	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;
	}
Пример #2
0
	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;
	}
Пример #3
0
	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;
	}
Пример #4
0
/***************************************************************
* 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);
}
Пример #5
0
/***************************************************************
* 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);
}
Пример #6
0
	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;
	}
Пример #7
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
	);
}
Пример #8
0
	//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;
		}
	}
Пример #9
0
	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;
	}
Пример #10
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;
}
Пример #11
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
	);
}
Пример #12
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;
}