📄 syntaxanalyzer.cpp
字号:
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 + -