⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syntaxanalyzer.cpp

📁 a basic interpreter free basic
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	getline(KeyStream, Keyword);

	// Make sure we're looking at an if statement
	if(Keyword != "IF")
	{
		throw ILLEGAL_INSTRUCTION;
	}

	// Get the first expression
	LeftExp = this->sExpression();

	// Get the relational operator
	Relationship = this->sRelationalOperator();

	// Get the second expression
	RightExp = this->sExpression();

	// Get 'THEN'
	Token = *this->m_tokenIterator;
	KeyStream.clear();

	for(int i = 0; i < 4; i++)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	if(Keyword != "THEN")
	{
		throw INCORRECT_FORMAT;
	}

	// Get the line number
	LineNumber = this->sLineNumber();
	
	// Run the comparison, and branch if necessary
	bool branch = false;
	switch(Relationship)
	{
	case LESSER_THAN:
		if(LeftExp < RightExp)
			branch = true;
		break;
	case LESSER_THAN_OR_EQUAL:
		if(LeftExp <= RightExp)
			branch = true;
		break;
	case GREATER_THAN:
		if(LeftExp > RightExp)
			branch = true;
		break;
	case GREATER_THAN_OR_EQUAL:
		if(LeftExp >= RightExp)
			branch = true;
		break;
	case NOT_EQUAL:
		if(LeftExp != RightExp)
			branch = true;
		break;
	case EQUAL:
		if(LeftExp == RightExp)
			branch = true;
		break;
	default:
		throw ILLEGAL_RELATION;
	}

	// Branch
	if(branch)
	{
		if(this->GetContext()->GetCode()->Find(LineNumber) == NULL)
		{
			throw ILLEGAL_LINE_NUMBER;
		}
		else
		{
			this->GetContext()->SetBranching(true);
		}
	}

	return true;
}

// Get a FOR statement from the input stream
bool CSyntaxAnalyzer::sForStatement(void)
{
	// This statement can occur with any string of characters after it
	stringstream KeyStream;
	string Keyword;

	// Expressions
	float StartExp;
	float EndExp;
	float StepExp = 1;

	// Iterate from the first token, lookahead for the keyword
	tokenlist_t::iterator Curtoken = this->m_tokenIterator;

	for(int i = 0; i < 3; i++)
	{
		CToken *Token = *Curtoken;
		string ch = Token->GetLexeme();
		KeyStream << ch;
		Curtoken++;
		if(Curtoken == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at a next statement
	if(Keyword != "FOR")
	{
		return false;
	}
	
	// Go ahead and soak up the line
	CToken *Token = *this->m_tokenIterator;
	KeyStream.clear();

	for(int i = 0; i < 3; i++)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at an rem statement
	if(Keyword != "FOR")
	{
		throw ILLEGAL_INSTRUCTION;
	}

	// Get the next variable
	CSymbol *Symbol = this->sVariable();

	// Get an equals sign
	Token = *this->m_tokenIterator;
	if(Token->GetLexeme() != "=")
	{
		throw INCORRECT_FORMAT;
	}

	this->m_tokenIterator++;

	// Get the starting expression
	StartExp = this->sExpression();

	// Get 'TO'
	Token = *this->m_tokenIterator;
	KeyStream.clear();

	for(int i = 0; i < 2; i++)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Verify it
	if(Keyword != "TO")
	{
		throw INCORRECT_FORMAT;
	}

	// Get the ending expression
	EndExp = this->sExpression();

	// Get an optional 'STEP' expression
	Token = *this->m_tokenIterator;
	KeyStream.clear();

	if(Token->GetTokenType() != EOL)
	{
		for(int i = 0; i < 4; i++)
		{
			KeyStream << Token->GetLexeme();
	
			this->m_tokenIterator++;
			Token = *this->m_tokenIterator;
			if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
		}

		getline(KeyStream, Keyword);

		// Verify it
		if(Keyword != "STEP")
		{
			throw INCORRECT_FORMAT;
		}

		// Set the step expression
		StepExp = this->sExpression();
	}

	forloop_t *ForLoop;

	// See if it already exists in the forloop stack
	if(!this->GetContext()->GetForList()->empty())
		ForLoop = this->GetContext()->GetForList()->top();
	else
	{
		ForLoop = NULL;
	}

	// Otherwise, create a new for loop and stack it
	if(ForLoop == NULL || ForLoop->Symbol->GetName() != Symbol->GetName())
	{
		ForLoop = new forloop_t();
		ForLoop->LineNumber = this->GetContext()->GetCode()->GetCurrentLineNumber();
		ForLoop->Step = StepExp;
		ForLoop->Symbol = Symbol;
		ForLoop->Symbol->Set(StartExp);

		this->GetContext()->GetForList()->push(ForLoop);
	}
	
	if(Symbol->GetName() == ForLoop->Symbol->GetName())
	{
		// Execute the comparison to determine whether to execute
		// the for loop
		if(Symbol->Get() == (EndExp + ForLoop->Step))
		{
			// Branch
			this->GetContext()->GetCode()->Find(ForLoop->EndLineNumber);
			if(this->GetContext()->GetCode()->GetNext() == NULL)
			{
				throw END_IS_NOT_LAST;
			}
			else
			{
				// Pop the for loop off the stack
				this->GetContext()->GetForList()->pop();
			}
		}
	}


	return true;
}

// Get a NEXT statement from the token stream
bool CSyntaxAnalyzer::sNextStatement(void)
{
	// This statement can occur with any string of characters after it
	stringstream KeyStream;
	string Keyword;

	// Iterate from the first token, lookahead for the keyword
	tokenlist_t::iterator Curtoken = this->m_tokenIterator;

	for(int i = 0; i < 4; i++)
	{
		CToken *Token = *Curtoken;
		string ch = Token->GetLexeme();
		KeyStream << ch;
		Curtoken++;
		if(Curtoken == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at a next statement
	if(Keyword != "NEXT")
	{
		return false;
	}
	
	// Go ahead and soak up the line
	CToken *Token = *this->m_tokenIterator;
	KeyStream.clear();

	for(int i = 0; i < 4; i++)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at an rem statement
	if(Keyword != "NEXT")
	{
		throw ILLEGAL_INSTRUCTION;
	}

	// Get the next variable
	CSymbol *Symbol = this->sVariable();

	// Make sure it's the right one
	if(this->GetContext()->GetForList()->empty())
	{
		throw NOT_MATCH_WITH_FOR;
	}

	forloop_t *ForLoop = this->GetContext()->GetForList()->top();

	if(Symbol->GetName() != ForLoop->Symbol->GetName())
	{
		throw NOT_MATCH_WITH_FOR;
	}

	// Otherwise, increment the symbol by step and branch
	float Value = ForLoop->Symbol->Get();
	Value += ForLoop->Step;
	ForLoop->Symbol->Set(Value);

	// Set the ending line number
	ForLoop->EndLineNumber = this->GetContext()->GetCode()->GetCurrentLineNumber();

	this->GetContext()->GetCode()->Find(ForLoop->LineNumber);
	this->GetContext()->SetBranching(true);

	return true;
}

// Get a REM statement from the token stream
bool CSyntaxAnalyzer::sRemStatement(void)
{
	// This statement can occur with any string of characters after it
	stringstream KeyStream;
	string Keyword;

	// Iterate from the first token, lookahead for the keyword
	tokenlist_t::iterator Curtoken = this->m_tokenIterator;

	for(int i = 0; i < 3; i++)
	{
		CToken *Token = *Curtoken;
		string ch = Token->GetLexeme();
		KeyStream << ch;
		Curtoken++;
		if(Curtoken == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at an rem statement
	if(Keyword != "REM")
	{
		return false;
	}
	
	// Go ahead and soak up the line
	CToken *Token = *this->m_tokenIterator;
	KeyStream.clear();

	while(Token->GetTokenType() != EOL)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	return true;
}

// Get a DIM statement from the token stream
bool CSyntaxAnalyzer::sDimStatement(void)
{
	// This statement occurs with a variablelist after it
	stringstream KeyStream;
	string Keyword;

	// Iterate from the first token, lookahead for the keyword
	tokenlist_t::iterator Curtoken = this->m_tokenIterator;

	for(int i = 0; i < 3; i++)
	{
		CToken *Token = *Curtoken;
		string ch = Token->GetLexeme();
		KeyStream << ch;
		Curtoken++;
		if(Curtoken == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at a dim statement
	if(Keyword != "DIM")
	{
		return false;
	}
	
	// Go ahead and soak up the line
	CToken *Token = *this->m_tokenIterator;
	KeyStream.clear();

	for(int i = 0; i < 3; i++)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Verify that the command was constructed correctly
	if(Keyword != "DIM")
	{
		throw ILLEGAL_INSTRUCTION;
	}

	// Assuming that all checks out, grab a variable list.
	// Variable dimensioning is handled through a flag
	this->m_Dim = true;

	this->sVariableList();

	this->m_Dim = false;

	return true;
}

// Get a DEF statement from the token stream
bool CSyntaxAnalyzer::sDefStatement(void)
{
	// This statement occurs with a variablelist after it
	stringstream KeyStream;
	string Keyword;

	// Iterate from the first token, lookahead for the keyword
	tokenlist_t::iterator Curtoken = this->m_tokenIterator;

	for(int i = 0; i < 3; i++)
	{
		CToken *Token = *Curtoken;
		string ch = Token->GetLexeme();
		KeyStream << ch;
		Curtoken++;
		if(Curtoken == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Make sure we're looking at a def statement
	if(Keyword != "DEF")
	{
		return false;
	}
	
	// Go ahead and soak up the line
	CToken *Token = *this->m_tokenIterator;
	KeyStream.clear();

	for(int i = 0; i < 3; i++)
	{
		KeyStream << Token->GetLexeme();

		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
		if(this->m_tokenIterator == this->m_tokenlist->end())
			break;
	}

	getline(KeyStream, Keyword);

	// Verify that the command was constructed correctly
	if(Keyword != "DEF")
	{
		throw ILLEGAL_INSTRUCTION;
	}

	// Assuming that all checks out, grab a function identifier
	CFunction *Function = new CFunction();
	Function->SetName(this->sFunctionIdentifier());

	// Get an open parenthesis
	Token = *this->m_tokenIterator;
	if(Token->GetLexeme() != "(")
	{
		throw INCORRECT_FORMAT;
	}

	this->m_tokenIterator++;

	// Get an unsubscripted variable
	Function->SetSymbol(this->sVariable());

	// Get an CLOSE parenthesis
	Token = *this->m_tokenIterator;
	if(Token->GetLexeme() != ")")
	{
		throw INCORRECT_FORMAT;
	}

	this->m_tokenIterator++;

	// Get an equals sign
	Token = *this->m_tokenIterator;
	if(Token->GetLexeme() != "=")
	{
		throw INCORRECT_FORMAT;
	}

	this->m_tokenIterator++;

	// Soak up the rest of the string and stuff it into the function definition
	Token = *this->m_tokenIterator;
	stringstream ExpStream;
	string Exp;

	while(Token->GetTokenType() != EOL && this->m_tokenIterator != this->m_tokenlist->end())
	{
		ExpStream << Token->GetLexeme();
		this->m_tokenIterator++;
		Token = *this->m_tokenIterator;
	}

	getline(ExpStream, Exp);

	Function->SetExpression(Exp);

	// Add the function to the function table
	this->GetContext()->GetFunctionTable()->Add(Function);

	return true;
}

// Get a GOSUB statement from the token stream
bool CSyntaxAnalyzer::sGoSubStatement(void)
{
	// This statement should occur with one parameter
	stringstream KeyStream;
	string Keyword;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -