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

📄 parser.cpp

📁 一个可视化的编译器
💻 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 + -