#include "syntax.h"


//	**********************************************
//	********   The SyntaxAnalyzer class  ************
//	**********************************************

//Constructor to initialize the syntax analyzer with the debug mode
SyntaxAnalyzer::SyntaxAnalyzer(bool debugMode )
{debugModeStatus = debugMode;
}

void SyntaxAnalyzer::clearAllLexicalSyntacticSemanticInfo()
{
	tokenVectsSourcCodeAllLines.clear();
	categoryVectsSourcCodeAllLines.clear();
	vectInterpreterInstructions.clear();
	categoryVectOfAllInterpreterInstructions.clear();
	mapForNextInterpreterInstruction.clear();
	tableOfFunctionNamesAndCodeRecords.clear();

}

bool SyntaxAnalyzer::parseSourceCode(vector<string> & sourceProgram)
{

	//*************************************************************************
	//	Rebuild the lexical, syntactic, and semantic information first.
	//*************************************************************************
	clearAllLexicalSyntacticSemanticInfo(); //First clear all the existing information
	if	(	buildLexicalInformation(sourceProgram) == false	||
			buildSyntaxSemanticsInformation() == false
		)	
		//If something is wrong, outpuyt an error message
	{
		cout << "********************************************************************" << endl
			 << "Syntax Errors detected.!The parsing and indentation process aborted." << endl
			 << "********************************************************************" << endl;
		cout << endl;
		return false;
	}
	
	cout << endl << endl << endl;
	cout << "Parsing done through the source code successfully! Syntax is fine." << endl; 

	cout << endl << endl << endl
		 << "Start indenting the source code "<< endl
		 << "***************************************************" << endl;


	//Store the final result into the source code
	sourceProgram.clear();

	string line;
	int index = 0;
	int scopeCount = 0;
	for (	vectOfTokenVects::iterator itr1 = vectInterpreterInstructions.begin();
			itr1 != vectInterpreterInstructions.end();
			++itr1
		)
	{
		cout << "[" << index++ << "]:";

		if	(	(*itr1)[0] == "}"	)
			--scopeCount;
		
		//Output one tab in the beginning of each line
		line.clear();
		line = line + " ";

		//show the tab on the console also
		cout << '\t';	

		//output two spaces for each scope
		for (int i=0; i< scopeCount; ++i)
		{	line = line + "  ";	

			//show the spaces on the console also
			cout << "  ";	
		}

		//Append the contents of the interpreter instruction to the line
		for (size_t i=0; i < itr1->size(); ++i)
			line = line + (*itr1)[i] + " ";

		//show the instruction on the console also
		displayOneInterpreterInstruction(*itr1); 

		//Store the final result into the source code
		sourceProgram.push_back(line);

		if	(	(*itr1)[0] == "{"		|| 
				(*itr1)[0] == "if"		||
				(*itr1)[0] == "else"	||
				(*itr1)[0] == "while"	||
				(*itr1)[0] == "function"		
			)
			++scopeCount;

		if	(	(*itr1)[0] == "}"	)
			--scopeCount;

		if	(	(	(*itr1)[0] != "if"			&&
					(*itr1)[0] != "else"		&&
					(*itr1)[0] != "while"		&&
					(*itr1)[0] != "function"	&&		
					(*itr1)[0] != "{"			&&		
					(*itr1)[0] != "}"				
				)	//i.e. it is a simple BIOLA statement
			 && 
				(	(*(itr1-1))[0] == "if"		||
					(*(itr1-1))[0] == "else"	||
					(*(itr1-1))[0] == "while"	
				)	//i.e the last instruction is an if, an else, or a while header
			)
			--scopeCount;
	}
	cout << "***************************************************" << endl;
	cout << "Finish indenting the source code" << endl
		 << "The source code has been now updateded as shown above."
		 << endl ;

	return true;

}



bool SyntaxAnalyzer::buildLexicalInformation(const vector<string> & sourceProgram)
//Call the getLexicalInfo function from the lexicalScanner.cpp
//to conduct lexical analysis
{	cout << endl
		 << "****  Start building lexical information  ****" 
		 << endl
		 << "        ... ... ..." 
		 << endl;
	LexicalScanner::getLexicalInfo
		(	sourceProgram, 
			tokenVectsSourcCodeAllLines,
			categoryVectsSourcCodeAllLines
		);

	//LexicalScanner::displayLexicalInfo
	//	(	tokenVectsSourcCodeAllLines,
	//		categoryVectsSourcCodeAllLines
	//	);

	cout << "**********  Finish building lexical information ********" << endl;
	return true;
}


bool  SyntaxAnalyzer::buildSyntaxSemanticsInformation()
{	
	size_t fromLine = 0, fromTokenIndex = 0;
	size_t lineToStartNextTime, tokenIndexToStartNextTime;
	size_t indexOfThisInterpreterInstruction;
	perLineTokenVector  thisInterpreterInstruction;
	perLineCategoryVector  itsTokenCategoryVect;

	functionCodeRecord thisFunctionCodeRecord;
	vector<size_t> stackOfBlockBeginIndices;
	vector<size_t> stackOfIfHeaderIndices;

	cout << endl
		 << "****  Start buildSyntaxSemanticsInformation  ****" 
		 << endl
		 << "        ... ... ..." 
		 << endl;
	while	(	deriveNextInterpreterInstruction
				(	fromLine, 
					fromTokenIndex,
					thisInterpreterInstruction,
					itsTokenCategoryVect,
					lineToStartNextTime, 
					tokenIndexToStartNextTime
				)
			)
	//When a new interpreter instruction is derived successfully
	{
		if ( debugModeStatus == true )
		{
			cout << endl
				 << "***********************************************" << endl;
			displayOneInterpreterInstruction(thisInterpreterInstruction);
			cout<< "\tInterpreter Instruction # " 
				<< indexOfThisInterpreterInstruction << endl
				<< '\t' << "From line#" << fromLine 
				<< " token#" << fromTokenIndex 
				<< " ending before line#" << lineToStartNextTime 
				<< " token#" << tokenIndexToStartNextTime
				<< endl;
		}

		indexOfThisInterpreterInstruction = vectInterpreterInstructions.size();

		//Roughly determine the category of the interpreter instruction
		interpreterInstructionCategory thisInterpreterInstructionCategory;
		thisInterpreterInstructionCategory
			=	getCategoryOfInterpreterInstruction
					(	thisInterpreterInstruction,
						itsTokenCategoryVect
					);

		//In the following check the syntax closely based on the category of 
		//	the interpreter instruction
		if (thisInterpreterInstructionCategory == UNKNOWN_STATEMENT)
		{
			cout << "Error. Unknown interpreter instruction!" << endl;
			return false;
		}

		if	(	thisFunctionCodeRecord.isUndefined() &&
				(	thisInterpreterInstructionCategory != 
					FUNCTION_HEADER_FUNCTION_STATEMENT
				)
			)
		{
			cout << "Error! missing function header in the beginning of function definition." << endl;
			return false;
		}

		switch (thisInterpreterInstructionCategory)
		{	
			//**********************************************************************
			case FUNCTION_HEADER_FUNCTION_STATEMENT:	//e.g. function square(x)
				//************************
				if	(	parseFunctionHeader
							(	thisInterpreterInstruction,
								itsTokenCategoryVect,
								thisFunctionCodeRecord.functionName, 
								thisFunctionCodeRecord.parametersList
							)
						== false
					)
						return false; //The function header is not is a good shape

				//Add parameters into the sybmbol table
				addAllVariablesIntoSymbolTable
					(	thisInterpreterInstruction,
						itsTokenCategoryVect,
						3,	//Satring from the 4th token
						thisInterpreterInstruction.size(),
						thisFunctionCodeRecord.localVariablesTable
					);
				thisFunctionCodeRecord.indexOfFirstInterpreterInstruction
					= indexOfThisInterpreterInstruction;
				break;
	
			//******* Simple Statements *******************************************
			case DISPLAY_STATEMENT:					 //e.g. display "x+y equals ", x+y;
			case ASSIGNMENT_STATEMENT:				 //e.g. x=1+y;
			case READ_STATEMENT:					 //e.g. read x;
			case RETURN_STATEMENT:					 //e.g. return x-1;
			case FUNCTION_CALL_ASSIGNMENT_STATEMENT: //e.g. x = functionCall square(2);
				//******************
				if  (	categoryVectOfAllInterpreterInstructions
						[indexOfThisInterpreterInstruction-1]	
							== WHILE_HEADER_WHILE_STATEMENT
					)
					updateMapForNextInterpreterInstruction
						(	indexOfThisInterpreterInstruction, 
							indexOfThisInterpreterInstruction-1
						);
				// If this is a simple statement following a while loop,
				// jump back to the while header as the next instruction.

				if (	checkAndProcessVariablesAndExpressions
							(	thisInterpreterInstruction,
								itsTokenCategoryVect,
								thisInterpreterInstructionCategory,
								thisFunctionCodeRecord.localVariablesTable
							)
						== false
					)
						return false; //invalid expressions or variables used
				break;

			//**********************************************************************
			case IF_HEADER_IF_STATEMENT:		 	 //e.g. if (x>1) 
			case WHILE_HEADER_WHILE_STATEMENT:	 	 //e.g. while (x>1) 

				//************************
				if (	checkAndProcessVariablesAndExpressions
							(	thisInterpreterInstruction,
								itsTokenCategoryVect,
								thisInterpreterInstructionCategory,
								thisFunctionCodeRecord.localVariablesTable
							)
						== false
					)
						return false; //invalid expressions or variables used

				updateMapForNextInterpreterInstruction
					(	indexOfThisInterpreterInstruction, 
						indexOfThisInterpreterInstruction+2
					);
				//Suppose only a single simple statement following 
				//	the "if" or "while" header
				//	then the next instruction should be 2 instructions down when
				//	the if or the while condition is not true.
				//If it turns out there is a block of statements 
				//	following the "if" header, the next instruction information
				//	added here is not right and will be updated when we processes
				//	the END_IF_BLOCK or END_WHILE_BLOCK of that block.

				if (thisInterpreterInstructionCategory == IF_HEADER_IF_STATEMENT)
					stackOfIfHeaderIndices.push_back(indexOfThisInterpreterInstruction);
				//Keep the index of an IF_HEADER_IF_STATEMENT instruction
				//	in the stackOfIfHeaderIndices for later use when processing
				//	the corresponding ELSE_HEADER_IF_STATEMENT

				break;

			//**********************************************************************
			case ELSE_HEADER_IF_STATEMENT:			 //else 
				size_t indexOfTheMatchingIfHeader;
				if  (	categoryVectOfAllInterpreterInstructions
						[indexOfThisInterpreterInstruction-1]	!= END_IF_BLOCK 
						&&	
						(	indexOfThisInterpreterInstruction < 2 
								||
							categoryVectOfAllInterpreterInstructions
								[indexOfThisInterpreterInstruction-2]	
							!= IF_HEADER_IF_STATEMENT
						)
					)//Check to make sure there is a matching if part before the else part
					{
						cout << "Dangling else header without a matching if header." << endl;
						return false;
					}
				else
				{	indexOfTheMatchingIfHeader
						= stackOfIfHeaderIndices.back();
					stackOfIfHeaderIndices.pop_back();
					//Get the index of the matching "if header" from the stack
					//Pop it off from the stack.

					updateMapForNextInterpreterInstruction
						(	indexOfTheMatchingIfHeader, 
							indexOfThisInterpreterInstruction+1
						);
					//If the condition of the "if header" is not true,
					//	the next instruction to execute is the one
					//	following the "else" header here.
				}
				
				updateMapForNextInterpreterInstruction
					(	indexOfThisInterpreterInstruction, 
						indexOfThisInterpreterInstruction+2
					);
				//Suppose only a single simple statement following 
				//	the "else" header. Then the next instruction should be 
				//	2 instructions down when we reach the ELSE header after
				//	the end of if part .
				//If it turns out there is a block of statements 
				//	following the "else" header, the next instruction information
				//	added here is not right and will be updated when we processes
				//	the END_OF_ELSE of that block.
				break;

			//**********************************************************************
			case BEGIN_ONE_BLOCK:	//i.e.  a left curly brace
				stackOfBlockBeginIndices.push_back(indexOfThisInterpreterInstruction);
				//Remember the index oh this {

				interpreterInstructionCategory lastInterpreterInstructionCategory;
				lastInterpreterInstructionCategory = 
					categoryVectOfAllInterpreterInstructions
					[indexOfThisInterpreterInstruction-1];
				//In the following, determine more specifically what this block is

				switch( lastInterpreterInstructionCategory )
				{
					case FUNCTION_HEADER_FUNCTION_STATEMENT:
						thisInterpreterInstructionCategory = 
							BEGIN_FUNCTION_DEFINTION_BLOCK;
						break;

					case IF_HEADER_IF_STATEMENT:
						thisInterpreterInstructionCategory = 
							BEGIN_IF_BLOCK;
						break;

					case ELSE_HEADER_IF_STATEMENT:
						thisInterpreterInstructionCategory = 
							BEGIN_ELSE_BLOCK;
						break;

					case WHILE_HEADER_WHILE_STATEMENT:
						thisInterpreterInstructionCategory = 
							BEGIN_WHILE_BLOCK;
						break;
					default:
						cout << "Error. Not a valid block following a function header"
							 << "or while header or if header or else header!" << endl;
						return false;
				}
				break;
			//**********************************************************************

			case END_ONE_BLOCK:		//i.e.  a right curly brace

				//Retrieve information of the matching {
				int indexOfBlockBegin;
				if ( stackOfBlockBeginIndices.empty())
				{
					cout << "Error. Dangling }. No matching {" << endl;
					return false;
				}
				indexOfBlockBegin = stackOfBlockBeginIndices.back();
				stackOfBlockBeginIndices.pop_back();

				interpreterInstructionCategory blockBeginCategory;
				blockBeginCategory = 
					categoryVectOfAllInterpreterInstructions
					[indexOfBlockBegin];

				//In the following, determine what actually is this block
				switch( blockBeginCategory )
				{
					case BEGIN_FUNCTION_DEFINTION_BLOCK:
						thisInterpreterInstructionCategory 
							= END_FUNCTION_DEFINTION_BLOCK;
						//This is the end of a function definition

						if ( !stackOfBlockBeginIndices.empty())
							{
								cout << "Error. Dangling {. No matching }" 
									 << " by the end of function definition." << endl;
								return false;
							}
						thisFunctionCodeRecord.indexOfLastInterpreterInstruction
							= indexOfThisInterpreterInstruction;
						addToTableOfFunctionNamesAndCodeRecords(thisFunctionCodeRecord);
						thisFunctionCodeRecord.clear();
						break;

					case BEGIN_IF_BLOCK:
						thisInterpreterInstructionCategory =
							END_IF_BLOCK;
						updateMapForNextInterpreterInstruction
							(	indexOfBlockBegin-1, 
								indexOfThisInterpreterInstruction+1
							);
						//when the condition of "if" fails, jump to pass the "if block"
						break;

					case BEGIN_ELSE_BLOCK:
						thisInterpreterInstructionCategory =
							END_ELSE_BLOCK;
						updateMapForNextInterpreterInstruction
							(	indexOfBlockBegin-1, 
								indexOfThisInterpreterInstruction+1
							);
						// When meeting the "else" header after the end of "if" block, 
						//	jump to pass over "else block"
						break;

					case BEGIN_WHILE_BLOCK:
						thisInterpreterInstructionCategory =
							END_WHILE_BLOCK;
						updateMapForNextInterpreterInstruction
							(	indexOfBlockBegin-1, 
								indexOfThisInterpreterInstruction+1
							);
						//When the condition in the "while" header is false, 
						//	jump to pass over the entire "while block"

						updateMapForNextInterpreterInstruction
							(	indexOfThisInterpreterInstruction, 
								indexOfBlockBegin-1
							);
						//At the end of "while" block, jump back to the "while" header
						break;

					default:
						cout << "Error. Not a valid place to close a block!" << endl;
						return false;
				}
			//**********************************************************************
		}//End of outer switch to process a single interpreter instruction

		//Store the current interpreter instruction and its category
		vectInterpreterInstructions.push_back(thisInterpreterInstruction);
		categoryVectOfAllInterpreterInstructions.push_back
			(thisInterpreterInstructionCategory);

		//prepare to derive the next interpreter instruction
		fromLine = lineToStartNextTime;
		fromTokenIndex = tokenIndexToStartNextTime;

	}//End of while loop

	cout << "**** End of buildSyntaxSemanticsInformation ****" << endl << endl;
	return true;

}//End of syntax-semantic parsing

bool SyntaxAnalyzer::parseFunctionHeader
(	perLineTokenVector & functionHeader,
	perLineCategoryVector & itstokenCategoryVector,
	string & functionName, 
	vector<string>& parametersList
)
{
		//Parse the function header. The header is expected to be of the form 
		//		function functionName(parameter,parameter,...)
		//		For example:		function main()		
		//							function gcd(n,m)
		//So the token vector derived from the command must have at least 4 tokens 
		//	to account for the functio keyword, function name and the two parentheses
		if (	functionHeader.size() < 4		||		
				functionHeader[0] != "function"	||
				itstokenCategoryVector[1]	!= ID_NAME ||
				itstokenCategoryVector[2]	!= LEFT_PARENTHESIS ||
				itstokenCategoryVector.back()	!= RIGHT_PARENTHESIS
			)
		{	cout << "The function header of function :" <<   functionHeader[1]
				 << " not in a right shape!" << endl << endl;
			return false;
		}

		functionName = functionHeader[1];
		//cout << "functionName:" << functionName << endl;
		parametersList.clear();

		bool needToFindExpBegin = true;
		for (	size_t i=3; //Starting from the 4th token
				i< functionHeader.size()-1;  
				i += 2
			)
		{	if	(		(	itstokenCategoryVector[i] == ID_NAME		&&
							itstokenCategoryVector[i+1] == COMMA	
						)		
					||	
						(	itstokenCategoryVector[i] == ID_NAME		&&
							i+1 == functionHeader.size()-1	
						)
				)
				parametersList.push_back(functionHeader[i]);
			else
				{	cout << "The parameters of fuction :" <<   functionHeader[1]
						 << " not in a right shape!" << endl << endl;
					return false;
				}

		}//End of for loop

	return true;	//All parameters well processed
}


//Get the function name and the argument list from
//	a functionCallAssignment Interpreter Instruction.
//For example, from the following interpreter instruction
//		x = gcd(4+6, y-1)
//with variable value 1 for y,
//	this function will derives "gcd" as the function name and 
//	a vector of two values: 10 and 0 as the argument list.
bool SyntaxAnalyzer::parseFunctionNameAndArgumentsListFromFunctionCallAssignmemt
	(	vector<string> & functionCallAssignment,
		symbolTable & localVariablesTable,
		string & functionName,
		vector<float> & argumentsList
	)
{
		vector<tokenCategory> tokenCategoryVector;
		//Call the following funtion from lexScanner.cpp to get the token categories
		LexicalScanner::getCategoryVectorFromTokenVector
			(	functionCallAssignment,
				tokenCategoryVector		
			);

		//Parse the function call assignment. It is expected to be of the form 
		//		ID_NAME = functionCall functionName(argument,argument,...);
		//		For example:		x = gcd(4,8);
		//So the token vector derived from the command must have at least 6 tokens 
		//		even if there is no argument.
		if (	functionCallAssignment.size() < 6					||		
				tokenCategoryVector[0] != ID_NAME					||
				tokenCategoryVector[1] != ASSIGNMENT_OP				||
				tokenCategoryVector[2] != ID_NAME					||
				tokenCategoryVector[3]	!= LEFT_PARENTHESIS			||
				tokenCategoryVector[tokenCategoryVector.size()-2]	
						!= RIGHT_PARENTHESIS						||
				tokenCategoryVector.back()!= SEMICOLON	
			)
		{	cout	<< "The function call assignment of:" 
					<<   functionCallAssignment[3]
					<< " not in a right shape!" 
					<< endl << endl;
			return false;
		}

		functionName = functionCallAssignment[2];
		argumentsList.clear();

		int indexToExpressionBegin,  indexToExpressionEnd;
		bool needToFindExpBegin = true;
		for (	size_t i=4; //Starting from the 5th token
				i< functionCallAssignment.size();  
				++i
			)
		{	if (needToFindExpBegin)		
			//Detect the beginning of an argument (as an expression)
				{	indexToExpressionBegin = i;
					needToFindExpBegin = false;
				}
			else	
			if	(	tokenCategoryVector[i]==COMMA	||		//A seperating comma
					i==functionCallAssignment.size()-2		//The last parenthesis
				)
				//Detect the comma or the last parenthesis ) after 
				//the end of an argument (as an expression)
				{	indexToExpressionEnd = i;
					
					float argumentValue;
					bool isArgumentValid;
					
					//Evaluate the argument (as an expression)
					isArgumentValid	=	
						ExpressionEvaluator::infixEvaluator		
							(	functionCallAssignment.begin()+indexToExpressionBegin, 
								functionCallAssignment.begin()+indexToExpressionEnd, 
								localVariablesTable, 
								argumentValue
							);

					if (isArgumentValid)
					{	argumentsList.push_back(argumentValue); //Store the argument
						needToFindExpBegin = true;	//Prepare to find next argument
					}
					else //Not a valid argument. Output an error message
					{	cout	<< "Cannot evaluate the argument \" "
								<< functionCallAssignment[indexToExpressionBegin]
								<< "..."
								<< functionCallAssignment[indexToExpressionEnd]
								<< " \" to a numerical value!" << endl;
						return false;
					}
				}

		}//End of for loop

	return true;	//All arguments  well processed
}


interpreterInstructionCategory 
SyntaxAnalyzer::getCategoryOfInterpreterInstruction
(	perLineTokenVector & interpreterInstruction,
	perLineCategoryVector & itsTokenCategoryVect
)
{
	if (interpreterInstruction.empty() || itsTokenCategoryVect.empty() )
	{	cout << "Error: Cannot determine the statement's type "
			 << "without complete lexical info of it." << endl;
		return UNKNOWN_STATEMENT;
	}

	if (	itsTokenCategoryVect[0] == KEYWORD )
	{
		if (interpreterInstruction[0] == "function")
			return FUNCTION_HEADER_FUNCTION_STATEMENT;

		if (interpreterInstruction[0] == "display"		&&
			itsTokenCategoryVect.back() == SEMICOLON	
		   )
			return DISPLAY_STATEMENT;

		if (interpreterInstruction[0] == "read"		&&
			itsTokenCategoryVect[1] == ID_NAME		&&
			itsTokenCategoryVect[2] == SEMICOLON	&&
			interpreterInstruction.size() == 3
		   )
			return READ_STATEMENT;

		if (interpreterInstruction[0] == "return"		&&
			itsTokenCategoryVect.back() == SEMICOLON	&&
			interpreterInstruction.size() >= 3	
		   )
			return RETURN_STATEMENT;

		if (interpreterInstruction[0] == "while")
			return WHILE_HEADER_WHILE_STATEMENT;

		if (interpreterInstruction[0] == "if")
			return IF_HEADER_IF_STATEMENT;

		if (interpreterInstruction[0] == "else"	&&
			interpreterInstruction.size() == 1
		   )
			return ELSE_HEADER_IF_STATEMENT;

		if (interpreterInstruction[0] == "//")
			return COMMENTS_STATEMENT;

		return UNKNOWN_STATEMENT;
	}

	else if (	interpreterInstruction.size() >= 6					&&
				itsTokenCategoryVect[0] == ID_NAME					&&
				itsTokenCategoryVect[1] == ASSIGNMENT_OP			&&
				itsTokenCategoryVect[2] == ID_NAME					&&
				itsTokenCategoryVect[3] == LEFT_PARENTHESIS			&&
				itsTokenCategoryVect[itsTokenCategoryVect.size()-2] 
						== RIGHT_PARENTHESIS						&&
				itsTokenCategoryVect.back() == SEMICOLON			
			)
		return FUNCTION_CALL_ASSIGNMENT_STATEMENT;

	else if (	itsTokenCategoryVect[0] == ID_NAME			&&
				itsTokenCategoryVect[1] == ASSIGNMENT_OP	&&
				itsTokenCategoryVect.back() == SEMICOLON	&&
				interpreterInstruction.size() >= 4
			)
		return ASSIGNMENT_STATEMENT;

	else if (	itsTokenCategoryVect[0] == LEFT_CURLYBRACE )
		return BEGIN_ONE_BLOCK;

	else if (	itsTokenCategoryVect[0] == RIGHT_CURLYBRACE )
		return END_ONE_BLOCK;

	return UNKNOWN_STATEMENT;
}


bool SyntaxAnalyzer::deriveNextInterpreterInstruction
	(	size_t fromLineIndex, 
		size_t fromTokenIndex,
		perLineTokenVector & interpreterInstruction,
		perLineCategoryVector & itstokenCategoryVect,
		size_t & lineToStartNextTime, 
		size_t & tokenIndexToStartNextTime
	)
{
	if	(	fromLineIndex < 0 ||fromTokenIndex < 0)
		{	cout << "Negative indicies! NotAllowed.";
			return false;
		}
	//each index must be non-negative

	if (	fromLineIndex > tokenVectsSourcCodeAllLines.size()-1	||
			(	fromLineIndex == tokenVectsSourcCodeAllLines.size()-1	&&
				fromTokenIndex > 
				tokenVectsSourcCodeAllLines[fromLineIndex].size()-1
			)
	   )
			return false; 
	//Reach beyond the last token of the last line. If so, there is no 
	//interpreter instructions to derive from tokenVectsSourcCodeAllLines,
	//simply return false to ndicate it. 

	//Start scanning for a new interpreter instruction
	interpreterInstruction.clear();
	itstokenCategoryVect.clear();
		
	int numLeftParenthesesToMatch=0;
	bool keepSearching=true;
	while (keepSearching)
	{	
		string thisToken; 
		tokenCategory thisTokenCategory;

		//Determine the token we have at hand
		thisToken = tokenVectsSourcCodeAllLines[fromLineIndex][fromTokenIndex]; 
		thisTokenCategory	
			= categoryVectsSourcCodeAllLines[fromLineIndex][fromTokenIndex];

		//Determine the next token we will look at after this one
		string nextToken;

		tokenCategory nextTokenCategory;
		if	(	fromTokenIndex < 
				tokenVectsSourcCodeAllLines[fromLineIndex].size() -1
			)
			{	nextToken
					= tokenVectsSourcCodeAllLines[fromLineIndex][fromTokenIndex+1];
				nextTokenCategory
					= categoryVectsSourcCodeAllLines[fromLineIndex][fromTokenIndex+1];
			}
		else
		if	(	fromLineIndex < 
				tokenVectsSourcCodeAllLines.size() -1
			)
		{
				nextToken
					= tokenVectsSourcCodeAllLines[fromLineIndex+1][0];

				nextTokenCategory
					= categoryVectsSourcCodeAllLines[fromLineIndex+1][0];

			}
		
		if (thisTokenCategory == COMMENT)
			//Simply skip to the next line
			{	++fromLineIndex;		
				fromTokenIndex = 0;	
			}
		else if (thisTokenCategory == SEMICOLON && !interpreterInstruction.empty())
			//Reach the end of an interpreter instruction. Store the token and stop.
			{	interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++; 
				keepSearching = false;	
			}
		else if (thisTokenCategory == LEFT_CURLYBRACE && !interpreterInstruction.empty())
			//Reach the beginning of a block interpreter instructions.
			//Stop searching for and leave this token to be scanned again 
			//	next time as the beginning of next interpreter instruction.
			{	keepSearching = false;	
			}
		else if (thisTokenCategory == LEFT_CURLYBRACE && interpreterInstruction.empty())
			//A BEGIN_ONE_BLOCK instruction 
			//Stop searching. This token alone is an interpreter instruction.
			//Next time search the token after it.
			{	interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++; 
				keepSearching = false;	
			}
		else if (thisTokenCategory == RIGHT_CURLYBRACE && !interpreterInstruction.empty())
			//Reach the end of a block interpreter instructions.
			//Stop searching and leave this token to be scanned again 
			//	next time as the beginning of next interpreter instruction.
			{	keepSearching = false;	
			}
		else if (thisTokenCategory == RIGHT_CURLYBRACE && interpreterInstruction.empty())
			//A END_ONE_BLOCK instruction 
			//Stop searching. This token alone is an interpreter instruction.
			//Next time search the token after it.
			{	interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++; 
				keepSearching = false;	
			}
		else if (thisTokenCategory == LEFT_PARENTHESIS)
			//Count how many left parentheses are still not matched, and 
			//	store this left parenthesis into the interpreter instruction.
			{	++numLeftParenthesesToMatch;
				interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++; 
			}
		else if (thisTokenCategory == RIGHT_PARENTHESIS)
			//Count how many left parentheses are still not matched, and 
			//	store this left parenthesis into the interpreter instruction.
			//If all left parentheses are all matched by now and this is 
			//	an "if" header or a "while" header interpreter instruction,
			//stop searching and this should be the end of this interpreter instruction.
			{	--numLeftParenthesesToMatch;
				interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++; 
				if (	numLeftParenthesesToMatch == 0				&&
						!interpreterInstruction.empty()				&&
						(	interpreterInstruction[0] == "if"
							|| interpreterInstruction[0] == "while"
						)											
					)
				  keepSearching = false;	
			}
		else if (	!interpreterInstruction.empty()		&&
					thisTokenCategory == KEYWORD		&& 
					thisToken != "functionCall"			
				)
			//Reach the beginning of another interpreter instruction since
			//	the keywords of BIOLA language (except for "functionCall" )
			//	signal the beginning of a new interpreter instruction.
			//Stop searching and leave this token to be scanned again 
			//	next time as the beginning of next interpreter instruction.
			{	keepSearching = false;	
			}
		else if (	interpreterInstruction.empty()			&& 
					thisToken == "else"
				)
			//A ELSE_HEADER_IF_STATEMENT instruction as the beginning
			//	this interpreter instruction that we want to construct.
			//Stop searching. This token alone is an interpreter instruction.
			//Next time search the token after it.
			{	interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++; 
				keepSearching = false;	
			}
		else if (	interpreterInstruction.empty()		&&
					thisTokenCategory == ID_NAME		&&
					nextTokenCategory == LEFT_PARENTHESIS
				)
			//Transform a function call instruction of the form
			//		"SomeFunctionName(...);"		into
			//		"SomeFunctionName = SomeFunctionName ...", i.e
			//		SomeFunctionName is artificially used as a dumb variable here.
			//The purpose is to make all functionCall instructions appear in 
			//		the cannonical form of the functionCallAssignment  above.
			{	string someFunctionName= thisToken;

				interpreterInstruction.push_back(someFunctionName);
				itstokenCategoryVect.push_back(ID_NAME);
				interpreterInstruction.push_back("=");
				itstokenCategoryVect.push_back(ASSIGNMENT_OP);
				interpreterInstruction.push_back(someFunctionName);
				itstokenCategoryVect.push_back(ID_NAME);

				fromTokenIndex++;
			}
		else	
			//One more regular token appended into the interpreter instruction
			{	interpreterInstruction.push_back(thisToken);
				itstokenCategoryVect.push_back(thisTokenCategory);
				fromTokenIndex++;
			}

		//Check end of line
		if ( fromTokenIndex > tokenVectsSourcCodeAllLines[fromLineIndex].size()-1 )
			{	++fromLineIndex;		fromTokenIndex = 0;	}
		//Prepare to check next token in next iteration
		lineToStartNextTime = fromLineIndex;
		tokenIndexToStartNextTime = fromTokenIndex;

		if ( fromLineIndex > tokenVectsSourcCodeAllLines.size()-1 )
			keepSearching = false;
		//Reached the end already.
	}
 
	if (interpreterInstruction.empty())
		return false;	//No new valid interpreter instruction found
	else
		return true;	//A new valid interpreter instruction found
}


//Check the validity of the variables and the expressions 
//	appear in the interpreter instruction with repsect to
//	the local symbol table built so far.
//If all are valid, add new variables that are seen  
//	for the first time into the local variable table of 
//	the current functionCode Record.
//Return true if all are valid; otherwise return false.
bool SyntaxAnalyzer::checkAndProcessVariablesAndExpressions
(	perLineTokenVector & thisInterpreterInstruction,
	perLineCategoryVector & tokenCategoryVect,
	interpreterInstructionCategory thisInterpreterInstuctionCategory,
	symbolTable & localVariablesTable
)
{	bool allVariablesWellInitialized;

	switch (thisInterpreterInstuctionCategory)
	{	
		case DISPLAY_STATEMENT:					 //e.g. display "x+y equals ", x+y;
		case READ_STATEMENT:					 //e.g. read x;
		case RETURN_STATEMENT:					 //e.g. return x-1;
		case IF_HEADER_IF_STATEMENT:		 	 //e.g. if (x>1) 
		case WHILE_HEADER_WHILE_STATEMENT:	 	 //e.g. while (x>1) 
			allVariablesWellInitialized
				= areAllVariablesInSymbolTable
					(	thisInterpreterInstruction,
						tokenCategoryVect,
						1,
						thisInterpreterInstruction.size()-1,
						localVariablesTable
					);
			break;

		case ASSIGNMENT_STATEMENT:				 //e.g. x=1+y;
			allVariablesWellInitialized
				= areAllVariablesInSymbolTable
					(	thisInterpreterInstruction,
						tokenCategoryVect,
						2,
						thisInterpreterInstruction.size()-1,
						localVariablesTable
					);
			break;


		case FUNCTION_CALL_ASSIGNMENT_STATEMENT: 
			//e.g. x = functionCall square(2); or simply
			//	   x = square(2);
			allVariablesWellInitialized
				= areAllVariablesInSymbolTable
					(	thisInterpreterInstruction,
						tokenCategoryVect,
						4,
						thisInterpreterInstruction.size()-2,
						localVariablesTable
					);
			break;


		default: //do nothing
			allVariablesWellInitialized = true;
			break;
	}

	if ( !allVariablesWellInitialized)
		cout << "Uninitialized variables initialized to 0. " << endl
			 << "Continue to check the validity of expression." <<endl;

	//If all variables used in exoressions are well initialized before
	//	add variables into the table and then check 
	addAllVariablesIntoSymbolTable
		(	thisInterpreterInstruction,
			tokenCategoryVect,
			0,
			thisInterpreterInstruction.size(),
			localVariablesTable
		);

	bool isWellFormedExpression;
	switch (thisInterpreterInstuctionCategory)
	{	float tempResult;
		case DISPLAY_STATEMENT:			
			//e.g. display "x+y equals ", x+y;
			//Check all the expressions and make sure they are all valid
			isWellFormedExpression
				=	checkExpressionsInDisplayInterpreterInstruction
					(	thisInterpreterInstruction,
						tokenCategoryVect,
						localVariablesTable
					);
			break;

		case RETURN_STATEMENT:			//e.g. return x-1;
			isWellFormedExpression
				=	ExpressionEvaluator::infixEvaluator
					(	thisInterpreterInstruction.begin()+1, 
						thisInterpreterInstruction.end()-1, 
						localVariablesTable, 
						tempResult
					);
			//Check whether the expression can be well evaluated without problem.
			break;

		case ASSIGNMENT_STATEMENT:				 //e.g. x=1+y;
			isWellFormedExpression
				=	ExpressionEvaluator::infixEvaluator
					(	thisInterpreterInstruction.begin()+2, 
						thisInterpreterInstruction.end()-1, 
						localVariablesTable, 
						tempResult
					);
			//Check whether the expression can be well evaluated without problem.
			break;

		case FUNCTION_CALL_ASSIGNMENT_STATEMENT: //e.g. x = functionCall square(2);
			{	string functionName;
				vector<float> argumentsList;

				isWellFormedExpression
					= parseFunctionNameAndArgumentsListFromFunctionCallAssignmemt 
						(	thisInterpreterInstruction,
							localVariablesTable,
							functionName,
							argumentsList
						);
			}
			break;

		case IF_HEADER_IF_STATEMENT:		 	 //e.g. if (x>1) 
		case WHILE_HEADER_WHILE_STATEMENT:	 	 //e.g. while (x>1) 
			isWellFormedExpression
				=	ExpressionEvaluator::infixEvaluator
					(	thisInterpreterInstruction.begin()+1, 
						thisInterpreterInstruction.end(), 
						localVariablesTable, 
						tempResult
					);
			//Check whether the expression can be well evaluated without problem.
			break;

		case READ_STATEMENT:
			//e.g. read x;			
			//A single variable is always a valid expression. No need to check.
		default: //do nothing for the other kinds of interpreter intructions
			isWellFormedExpression = true;
			break;
	}

	if ( !isWellFormedExpression)
	{	cout << "Error. Invalid Expression found in the instruction!" << endl;
		return false;
	}
	else
		return true;
}


//Check to make sure all expressions in a display statement
//	are valid. If so, return true; othersie return false.
bool SyntaxAnalyzer::checkExpressionsInDisplayInterpreterInstruction
(	perLineTokenVector & thisInterpreterInstruction,
	perLineCategoryVector & tokenCategoryVector,
	symbolTable & localVariablesTable
)
{	int indexToExpressionBegin,  indexToExpressionEnd;
	bool needToFindExpBegin = true;
	for (	size_t i=1; //Starting from the 2nd token
			i< thisInterpreterInstruction.size();  
			++i
		)
	{	if	(	needToFindExpBegin	&& 
				tokenCategoryVector[i] == STRING_LITERAL
			)
			//Display the contents of a string literal
			{	//Check to make sure it is followed by a comman or semicolon
				if	(	i != thisInterpreterInstruction.size()-1	&&
						tokenCategoryVector[i+1]!= COMMA			&& 
						tokenCategoryVector[i+1]!= SEMICOLON
					)
					return false;
				else
					++i;
			}
		else
		if	(	needToFindExpBegin	&& 
				tokenCategoryVector[i] != STRING_LITERAL	
			)		
			//Detect the beginning of an expression in display
			{	indexToExpressionBegin = i;
				needToFindExpBegin = false;
			}
		else	
		if	( !needToFindExpBegin	&& 
				(	tokenCategoryVector[i]==COMMA	||	  //A seperating comma
					tokenCategoryVector[i]==SEMICOLON	  //The ending semicolon
				)
			)
			//Detect the end of an expression signaled by
			//	a comma or the ending semicolon
			{	indexToExpressionEnd = i;
				
				float expressionValue;
				bool isExpressionValid;
				
				//Evaluate the expression)
				isExpressionValid	=	
					ExpressionEvaluator::infixEvaluator		
						(	thisInterpreterInstruction.begin()+indexToExpressionBegin, 
							thisInterpreterInstruction.begin()+indexToExpressionEnd, 
							localVariablesTable, 
							expressionValue
						);

				if (isExpressionValid)
				//This expression is fine.
				//Prepare to find next argument
					needToFindExpBegin = true;	
				else 
				//Not a valid expression. Output an error message
				{	cout	<< "invalid expression \" "
								<< thisInterpreterInstruction[indexToExpressionBegin]
								<< "..."
								<< thisInterpreterInstruction[indexToExpressionEnd]
								<< " \" to a numerical value!" << endl;
					return false;
				}
			}
	}//End of for loop


	return true;
	//Everthing is fine.
}




//Check to see whether all variables (tokens with ID_NAME category)
//	in the range specified by [beginIndex, endIndex) are all already present
//	in the localVariablesTable
//	according to the token category information in tokenCategoryVect.
//Return true if so; otherwise return false.
bool SyntaxAnalyzer::areAllVariablesInSymbolTable
(	perLineTokenVector & interpreterInstruction,
	perLineCategoryVector &tokenCategoryVect,
	size_t beginIndex,
	size_t endIndex,
	symbolTable & localVariablesTable
)
{
	if (	beginIndex < 0 )
		beginIndex = 0;
	if (	endIndex > interpreterInstruction.size())
		endIndex = interpreterInstruction.size();

	for (size_t i=beginIndex; i<endIndex; ++i)
		if (	tokenCategoryVect[i] == ID_NAME		&&
				(	localVariablesTable.find(interpreterInstruction[i])
					== localVariablesTable.end()
				)	//A variable (ID_NAME) not in the table
			)
		{	cout << "Uninitialized variable:" << interpreterInstruction[i]
				 << " used in an expression" << endl;
			return false;
		}

	return true;
}

//Add all variables (tokens with ID_NAME category)
//	in the range specified by [beginIndex, endIndex) are all already present
//	into the localVariablesTable
//	according to the token category information in tokenCategoryVect
bool SyntaxAnalyzer::addAllVariablesIntoSymbolTable
(	perLineTokenVector & interpreterInstruction,
	perLineCategoryVector &tokenCategoryVect,
	size_t beginIndex,
	size_t endIndex,
	symbolTable & localVariablesTable
)
{	
	if (	beginIndex < 0 )
		beginIndex = 0;
	if (	endIndex > interpreterInstruction.size())
		endIndex = interpreterInstruction.size();

	for (size_t i=beginIndex; i<endIndex; ++i)
		if (	tokenCategoryVect[i] == ID_NAME		&&
				(	localVariablesTable.find(interpreterInstruction[i])
					== localVariablesTable.end()
				)	//A variable (ID_NAME) not in the table
			)
		  localVariablesTable[interpreterInstruction[i]]=1;
		  //Add and initialize the variable to 1

	return true;
}

void SyntaxAnalyzer::addToTableOfFunctionNamesAndCodeRecords
(functionCodeRecord & codeRecord)
{
	tableOfFunctionNamesAndCodeRecords[codeRecord.functionName] 
		= codeRecord; 
}


//Add the next instruction information of one interpreter instruction
//into mapForNextInterpreterInstruction.
//The is a control-flow map recording the control flow information 
//	when exeuting conditional instructions like: if, else, while.
//
//The key of an entry in this map is the index of 
//	(i) an if header, an else header, or a while header 
//		interpreter instruction, or
//	(ii)END_WHILE_BLOCK interpreter instruction.
//
//The value of an entrie in this map recording the index of 
//	the next interpreter instruction to execute after
//	(i) an if header or a while header interpreter instruction
//		when the logic condition in the header is not true
//	(ii)an ELSE (after the if part is done) or an END_WHILE_BLOCK 
//		interpreter instruction.
void SyntaxAnalyzer::updateMapForNextInterpreterInstruction
(	int indexThisInterpreterInstruction,
	int indexNextInterpreterInstruction
)
{
	mapForNextInterpreterInstruction[indexThisInterpreterInstruction]
		=indexNextInterpreterInstruction;
}

//********************************************************************
//*****		Other public member functions for house keeping		******
//********************************************************************

//Output the parse structure of an instruction to a file
void SyntaxAnalyzer::outputParseStructureOfOneInterpreterInstruction
(	const vector<string> & thisInstruction, 				//An interpreter instruction
	interpreterInstructionCategory   thisCategory,			//The category of the interpreter instruction
	int scopeCount,			//The depth of its scope
	int index,				//The index of the instruction in the source program
	ofstream & fout			//The file to write to
)
{	string message;

	switch (thisCategory)
	{
		//Regarding Section 1 of interpreter instructions in syntax.h
		case ASSIGNMENT_STATEMENT:
			message = "ASSIGNMENT_STATEMENT:<simple-stmt>";
				break;

		case FUNCTION_CALL_ASSIGNMENT_STATEMENT:
			message = "FUNCTION_CALL_ASSIGNMENT_STATEMENT:<simple-stmt>";
				break;

		case DISPLAY_STATEMENT:
			message = "DISPLAY_STATEMENT:<simple-stmt>";
				break;

		case READ_STATEMENT:
			message = "READ_STATEMENT:<simple-stmt>";
				break;

		case RETURN_STATEMENT:
			message = "RETURN_STATEMENT:<simple-stmt>";
				break;

		case COMMENTS_STATEMENT:
			message = "COMMENTS_STATEMENT:<simple-stmt>";
				break;

		//Regarding Section 2 of interpreter instructions in syntax.h
		case IF_HEADER_IF_STATEMENT:
			message = "IF_HEADER:<compound-stmt>";
				break;

		case ELSE_HEADER_IF_STATEMENT:
			message = "ELSE_HEADER:<compound-stmt>";
				break;

		case WHILE_HEADER_WHILE_STATEMENT:
			message = "WHILE_HEADER:<compound-stmt>";
				break;

		case FUNCTION_HEADER_FUNCTION_STATEMENT:
			message = "FUNCTION_DEFINITION_HEADER:<compound-stmt>";
				break;

		//Regarding Section 4 of interpreter instructions in syntax.h
		case BEGIN_FUNCTION_DEFINTION_BLOCK:
			message = "BEGINNING of FUNCTION DEFINITION:<compound-stmt>";
				break;

		case END_FUNCTION_DEFINTION_BLOCK:
			message = "END of FUNCTION DEFINITION:<compound-stmt>";
				break;

		case BEGIN_IF_BLOCK:
			message = "BEGINNING of IF_BLOCK:<compound-stmt>";
				break;

		case END_IF_BLOCK:
			message = "END of IF_BLOCK:<compound-stmt>";
				break;

		case BEGIN_ELSE_BLOCK:
			message = "BEGINNING of ELSE_BLOCK:<compound-stmt>";
				break;

		case END_ELSE_BLOCK:
			message = "END of ELSE_BLOCK:<compound-stmt>";
				break;

		case BEGIN_WHILE_BLOCK:
			message = "BEGINNING of WHILE_BLOCK:<compound-stmt>";
				break;

		case END_WHILE_BLOCK:
			message = "END of WHILE_BLOCK:<compound-stmt>";
				break;

		case UNKNOWN_STATEMENT:
			message = "??? UNKNOWN ???:";
				break;

		default:
			message = "??? ERROR ???:";
				break;
	}



	//Output one line of the markers of scope levels
	for (int i=0; i<= scopeCount; ++i)
	{	//output a maker followed by two spaces for each scope level including level 0
		fout << "|  ";	
	}
	fout << endl;

	//Output the 2nd line of the markers of scope levels
	for (int i=0; i<= scopeCount; ++i)
	{	//output a maker followed by two spaces for each scope level including level 0
		fout << "|  ";	
	}
	//Output the information of the syntax category
	fout << message << endl;


	//Output the 3rd line of the markers of scope levels
	for (int i=0; i<= scopeCount; ++i)
	{	//output a maker followed by two spaces for each scope level including level 0
		fout << "|  ";	
	}
	//Output the interpreter instruction
	fout << "[" << index << "] ";
	for (	vector<string>::const_iterator 
				itr= thisInstruction.begin();

			itr < thisInstruction.end();

			++itr
		)
		fout << *itr << ' ';
	fout << endl;



	//Output the 4th line of the markers of scope levels
	for (int i=0; i<= scopeCount; ++i)
	{	//output a maker followed by two spaces for each scope level including level 0
		fout << "|  ";	
	}
	fout << endl;

}


//Output a parse tree based on 
//	vectInterpreterInstructions					and 
//	categoryVectOfAllInterpreterInstructions
//Save it into the file whose name is stored in outputFileName
void SyntaxAnalyzer::outputParseTree(const char * outputFileName)
{
	ofstream fout;
	fout.open( outputFileName );
	if ( fout.fail() )
	{	cout << endl 
			 << "Error!!  SyntaxAnalyzer::outputParseTree fail to open the file:" 
			 <<outputFileName<< endl << endl;
		return ;
	}

	//cout << endl
	//	 << "*************************************************************" << endl
	//	 << "** Parse Tree: Upto the the levels of simple statements   ***" << endl
	//	 << "*************************************************************" << endl
	//	 << "...   ...  ..." <<endl;

	fout << endl
		 << "*************************************************************" << endl
		 << "** Parse Tree: Upto the the levels of simple statements   ***" << endl
		 << "*************************************************************" << endl
		 << endl
		 << "Program" << endl;



	for 
	(	//Initialization
		int index = 0,
		scopeCount = 0;

		//Logic conditions of the loop
		index != vectInterpreterInstructions.size() &&
		index != categoryVectOfAllInterpreterInstructions.size();

		//Update after each iteration
		++index
	)
	{
		vector<string> instruction, previousInstruction;
		interpreterInstructionCategory  instructionCategory;

		//Determine the instruction to examine and its category
		instruction = vectInterpreterInstructions[index];
		if ( index > 0)
			previousInstruction = vectInterpreterInstructions[index -1];
		else
			previousInstruction.clear();

		instructionCategory = categoryVectOfAllInterpreterInstructions[index];

		//Rule 1: Before processing End of block },  moving one level up
		if	(	instruction[0] == "}"	)
			--scopeCount;


		//**************************************************************************
		//Output the parse structure of the interpreter instruction with the indx
		//**************************************************************************
		outputParseStructureOfOneInterpreterInstruction
			(instruction, instructionCategory, scopeCount, index, fout);

		//Rule 2: After processing End of block },  moving one level up also
		if	(	instruction[0] == "}"	)
			--scopeCount;

		//Rule 3: Move one level down after a compound statement. 
		//If the next instruction is {, Rule#1 will compensate it and move it back
		if	(	instruction[0] == "{"		|| 
				instruction[0] == "if"		||
				instruction[0] == "else"	||
				instruction[0] == "while"	||
				instruction[0] == "function"		
			)
			++scopeCount;


		//Rule 4: Move one level up by after a simple statement that immediately follows a compound statement. 
		if	(	(	instruction[0] != "if"			&&
					instruction[0] != "else"		&&
					instruction[0] != "while"		&&
					instruction[0] != "function"	&&		
					instruction[0] != "{"			&&		
					instruction[0] != "}"				
				)	//i.e. it is a simple BIOLA statement
			 && 
				!previousInstruction.empty()
			 &&
				(	previousInstruction[0] == "if"		||
					previousInstruction[0] == "else"	||
					previousInstruction[0] == "while"	
				)	//i.e the previous instruction is an if, an else, or a while header
			)
			--scopeCount;
	}


	//cout << endl << "...   ...  ...  Done" << endl
	//	 << "*************************************************************" << endl
	//	 << "***                   End of Parse Tree                   ***" << endl
	//	 << "*************************************************************" << endl;

	fout << endl << endl << endl
		 << "*************************************************************" << endl
		 << "***                   End of Parse Tree                   ***" << endl
		 << "*************************************************************" << endl;

	fout.close();


}



//Display the interpreter instructions derived from the source code
//	together with the category information and 
//	the next instruction information.
void SyntaxAnalyzer::displayAllInterpreterInstructions()
{
	cout << endl
		 << "List of all interpreter instructions "<< endl
		 << "***************************************************" << endl;

	int index = 0;
	int scopeCount = 0;
	for (	vectOfTokenVects::iterator itr1 = vectInterpreterInstructions.begin();
			itr1 != vectInterpreterInstructions.end();
			++itr1
		)
	{	cout << "[" << index++ << "]:";
		if	(	(*itr1)[0] == "}"	)
			--scopeCount;
		
		//Output one tab for for the beginning of each interpreter instruction
		cout << '\t';
		for (int i=0; i< scopeCount; ++i)
			cout << "  ";		//output two spaces for each scope

		displayOneInterpreterInstruction(*itr1);

		if	(	(*itr1)[0] == "{"		|| 
				(*itr1)[0] == "if"		||
				(*itr1)[0] == "else"	||
				(*itr1)[0] == "while"	||
				(*itr1)[0] == "function"		
			)
			++scopeCount;

		if	(	(*itr1)[0] == "}"	)
			--scopeCount;

		if	(	(	(*itr1)[0] != "if"			&&
					(*itr1)[0] != "else"		&&
					(*itr1)[0] != "while"		&&
					(*itr1)[0] != "function"	&&		
					(*itr1)[0] != "{"			&&		
					(*itr1)[0] != "}"				
				)	//i.e. it is a simple BIOLA statement
			 && 
				(	(*(itr1-1))[0] == "if"		||
					(*(itr1-1))[0] == "else"	||
					(*(itr1-1))[0] == "while"	
				)	//i.e the last instruction is an if, an else, or a while header
			)
			--scopeCount;
	}
	cout << "***************************************************" << endl;
	cout << "End of list of all interpreter instructions" 
		 << endl << endl << endl;

}


//Display the functionCodeRecords fo all functions 
//	defined in the source code.
void SyntaxAnalyzer::displayFunctionCodeRecords()
{	cout << endl
		 << "List all functions and their codeRecords "<< endl
		 << "***************************************************" << endl;

	for (	map<string, functionCodeRecord>::iterator 
				itr1 =tableOfFunctionNamesAndCodeRecords.begin();
			itr1 != tableOfFunctionNamesAndCodeRecords.end();
			++itr1
		)
			{	cout << endl << endl
					 << "*******************************************" << endl
					 << "functionCodeRecord for "
					 << itr1->second.functionName <<'(';
				if (! itr1->second.parametersList.empty())
				{
					for (size_t i=0; i<itr1->second.parametersList.size()-1;++i)
						cout << itr1->second.parametersList[i] << ',';

					cout << itr1->second.parametersList[i]; //The last parameter
					cout << ')' << endl;
				}
				cout << '\t' << "Index range of the corresponding instructions: "
					 << '[' << itr1->second.indexOfFirstInterpreterInstruction
					 << ',' << itr1->second.indexOfLastInterpreterInstruction
					 << ']'
					 << endl;
				displaySymbolTable(itr1->second.localVariablesTable);
			}

	cout << endl << endl << "***************************************************" << endl;
	cout << "End of list of all functions and their codeRecords"<< endl;
	cout << endl << endl;
}


//Like displayFunctionCodeRecords(),
//  but only sisplay the prototypes of the functions 
//	defined in the source code.
void SyntaxAnalyzer::displayFunctionPrototypes()
{	cout << endl << endl << endl
		 << "**********  List of Function Prototypes  **********" << endl << endl;

	for (	map<string, functionCodeRecord>::iterator 
				itr1 =tableOfFunctionNamesAndCodeRecords.begin();
			itr1 != tableOfFunctionNamesAndCodeRecords.end();
			++itr1
		)
			{	cout << '\t' << itr1->second.functionName <<'(';
				if (! itr1->second.parametersList.empty())
				{
					for (size_t i=0; i<itr1->second.parametersList.size()-1;++i)
						cout << itr1->second.parametersList[i] << ',';

					cout << itr1->second.parametersList[i]; //The last parameter
				}

				cout << ')' << endl << endl;	//The enclosing parenthesis

			}

	cout << "***************************************************" << endl;

}



//Display the variables in a symbol table and their current values  
void SyntaxAnalyzer::displaySymbolTable(symbolTable & localVariablesTable)
{	cout << endl
		 << '\t' << "Local variables/ arameters and their values in the localVariablesTable " << endl
		 << '\t' << "**********************************************" << endl;

	for (	map<string, float>::iterator itr = localVariablesTable.begin();
			itr != localVariablesTable.end();
			++itr
		)
		{
			cout << '\t' << "[Name of variable, value]=[" 
					<< (*itr).first << ',' << (*itr).second 
					<< "]" << endl;
		}
	cout << '\t' << "*******************************************" <<endl;

}


//Display the mapForNextInterpreterInstruction 
//	defined in the source code.
void SyntaxAnalyzer::displayMapForNextInterpreterInstruction()
{
	cout << endl << endl
		 << "List of  mapForNextInterpreterInstruction information"<< endl
		 << "***************************************************" 
		 << endl;

	for (	map<int, int>::iterator itr = mapForNextInterpreterInstruction.begin();
			itr != mapForNextInterpreterInstruction.end();
			++itr
		)
		cout << '\t' <<"(this, next)=" << itr->first << ',' << itr->second <<endl;

	cout << "***************************************************" << endl;
	cout <<"End of list of mapForNextInterpreterInstruction information."<< endl;
	getchar();
	cout << endl << endl;
}



void SyntaxAnalyzer::displayOneInterpreterInstruction
(perLineTokenVector thisInterpreterInstruction)
{
	for (	vector<string>::iterator itr
				= thisInterpreterInstruction.begin();
			itr < thisInterpreterInstruction.end();
			++itr
		)
		cout << *itr << ' ';

	cout << endl;
}




//	**********************************************************
//	********	The functionCodeRecord class		**********
//	**********************************************************
		
void functionCodeRecord::clear()
//clear the contents of the functionCodeRecord
{
		functionName = "_UNDEFINED";

		parametersList.clear();

		indexOfFirstInterpreterInstruction=0;

		indexOfLastInterpreterInstruction=0;

		localVariablesTable.clear();
};

bool functionCodeRecord::isUndefined()
//clear the contents of the functionCodeRecord
{	//cout << "In isUndefined:" << functionName << endl;
	if (functionName.empty() || functionName == "_UNDEFINED")
		return true;
	else
		return false;
}