📄 parser.cpp
字号:
/// <author> 任晶磊 </author>
/// <update> 2008-3-1 </update>
/// <E-mail> renjinglei@163.com </E-mail>
#include "Parser.h"
using C0::SemanCode;
using namespace C0::Parser;
using namespace C0::Interpreter;
using namespace std;
/// <summary>
/// 操作符优先级类的静态成员
/// </summary>
map<SemanCode, int> OperatorPriority::op;
Expression* Operation::Create(Expression* left, Expression* right, SemanCode opr)
{
switch(opr)
{
case PLUS:
return Addition::Create(left, right);
case MULT:
return Multiplication::Create(left, right);
}
return 0;
}
void AutoOperatorStack::Push(SemanCode nextOperator)
{
Expression* nextOperant = parser->ParseNum();
if (base.Empty())
{
base.Push(nextOperator);
operants->Push(nextOperant);
}
else if (OperatorPriority::GetPriority(nextOperator) > OperatorPriority::GetPriority(base.Top()))
{
Expression* operation = Operation::Create(operants->Pop(), nextOperant, nextOperator);
operants->Push(operation);
}
else
{
Expression* operation = Operation::Create(operants->Pop(), operants->Pop(), base.Pop());
operants->Push(operation);
base.Push(nextOperator);
operants->Push(nextOperant);
}
}
void Parser::SkipOver()
{
SemanCode sc;
while (sc = it->GetSeman(), sc != SEMI && sc != END) ++it;
if (it == tokens.End()) throw ParserFailure("意外的文件尾!");
}
Statement* Parser::ParseWrite()
{
if ((++it)->GetSeman() != OPEN)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少“(”(在“" + it->GetWord() + "”前)");
SkipOver();
return 0;
}
if ((++it)->GetType() != IDENTIFIER)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少标识符(write语句中)");
SkipOver();
return 0;
}
Statement* stm = WriteStatement::Create(it->GetSeman());
if ((++it)->GetSeman() != CLOSE)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少“)”(在“" + it->GetWord() + "”前)");
SkipOver();
return 0;
}
if ((++it)->GetSeman() != SEMI)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少“;”(在“" + it->GetWord() + "”前)");
--it;
return 0;
}
return stm;
}
Statement* Parser::ParseRead()
{
if ((++it)->GetSeman() != OPEN)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少“(”(在“" + it->GetWord() + "”前)");
SkipOver();
return 0;
}
if ((++it)->GetType() != IDENTIFIER)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少标识符(read语句中)");
SkipOver();
return 0;
}
Statement* stm = ReadStatement::Create(it->GetSeman());
if ((++it)->GetSeman() != CLOSE)
{
errors->Record(statements.GetFileName(), it->GetLineNum(), it->GetCharNum(),
"缺少“)”(在“" + it->GetWord() + "”前)");
SkipOver();
return 0;
}
if ((++it)->GetSeman() != SEMI)
{
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "缺少“;”(在“" + it->GetWord() + "”前)");
--it;
return 0;
}
return stm;
}
/// <summary>
/// 解析标识符或常数
/// </summary>
Expression* Parser::ParseNum()
{
switch((++it)->GetType())
{
case CONSTANT:
return Constant::Create(it->GetSeman());
case IDENTIFIER:
return Identifier::Create(it->GetSeman());
default:
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "缺少操作数(在“" + it->GetWord() + "”前)");
return 0;
}
}
Expression* Parser::ParseExpression()
{
// 第一个操作数入栈,进入初始状态
operants.Push(ParseNum());
// 不断调用带有扩展功能的自动运算符栈,直至所有运算符均入栈
while ((++it)->GetType() == OPERATOR)
operators.Push(it->GetSeman());
// 检查自动运算符栈的最后状态
if (operants.Size() == 1 && operators.Empty())
return operants.Pop();
else if (operants.Size() == 2 && operators.Size() == 1)
return Operation::Create(operants.Pop(), operants.Pop(), operators.Pop());
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "非法表达式");
SkipOver();
return 0;
}
StatementList& Parser::Execute()
{
if (it == tokens.End()) return statements;
if (it->GetSeman() != LBRACE)
{
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "程序头缺少“{”");
}
SemanCode sc;
while(++it, it != tokens.End())
{
sc = it->GetSeman();
if (sc == RBRACE) break;
switch(sc)
{
case READ:
statements.PushBack(ParseRead());
break;
case WRITE:
statements.PushBack(ParseWrite());
break;
default:
if (it->GetType() == IDENTIFIER && (++it)->GetSeman() == ASS)
{
statements.PushBack(AssignStatement::Create(sc, ParseExpression()));
//表达式解析成功
if (it->GetSeman() != SEMI)
{
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "缺少“;”(在“" + it->GetWord() + "”前)");
}
}
else
{
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "意外符号(在“" + it->GetWord() + "”后)");
SkipOver();
}
}
}//while
if (it == tokens.End())
{
errors->Record(statements.GetFileName(), it->GetLineNum(),
it->GetCharNum(), "程序尾缺少“}”");
}
return statements;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -