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

📄 parser.h

📁 一个可视化的编译器
💻 H
字号:
/// <author> 任晶磊 </author>
/// <update> 2008-3-1 </update>
///	<E-mail> renjinglei@163.com </E-mail>

#ifndef PARSER_H
#define PARSER_H

#include <list>
#include <string>
#include <map>
#include <iostream>
#include <exception>
#include "Lexer.h"
#include "Stack.h"
#include "Error.h"

namespace C0
{
	namespace Interpreter
	{
		using namespace std;
		/// <summary>
		/// 解释环境,包含保存变量值的符号表
		/// </summary>
		class Context
		{
			map<SemanCode, int> table;
		public:
			void Add(SemanCode id, int value)
			{
				table.insert(make_pair(id, value));
			}
			int GetValue(SemanCode id) const
			{
				map<SemanCode, int>::const_iterator it = table.find(id);
				if (it != table.end()) return it->second;
				else return 0;
			}
		};
	}

	namespace Parser
	{
		using namespace std;
		using Lexer::TokenList;
		using Interpreter::Context;
		using Interpreter::ErrorLog;

		class OperatorPriority
		{
			static map<SemanCode, int> op;
			static void Initialize()
			{
				op.insert(make_pair(PLUS, 1));
				op.insert(make_pair(MULT, 2));
			}
		public:
			static int GetPriority(SemanCode sc)
			{
				if (op.empty()) Initialize();
				return op[sc];
			}
		};
		
		/// <summary>
		/// 语句的接口
		/// </summary>
		class Statement
		{
		public:
			virtual void Interprete(Context& context) = 0;
			virtual ~Statement(){}
		};
		
		/// <summary>
		/// 输入语句
		/// </summary>
		class ReadStatement : public Statement
		{
			SemanCode id;
			ReadStatement(SemanCode id):id(id){}
		public: 
			static ReadStatement* Create(SemanCode id)
			{
				return new ReadStatement(id);
			}

			void Interprete(Context& context)
			{
				int num;
				cin >> num;
				context.Add(id, num);
			}
		};

		/// <summary>
		/// 输出语句
		/// </summary>
		class WriteStatement : public Statement
		{
			SemanCode id;
			WriteStatement(SemanCode id):id(id){}
		public: 
			static WriteStatement* Create(SemanCode id)
			{
				return new WriteStatement(id);
			}

			void Interprete(Context& context)
			{
				cout << context.GetValue(id) << endl;
			}
		};

		/// <summary>
		/// 表达式接口
		/// </summary>
		class Expression
		{
		public:
			virtual int Interprete(Context &context) = 0; 
			virtual ~Expression(){}
		};

		/// <summary>
		/// 操作表达式抽象类
		/// </summary>
		class Operation : public Expression
		{
		public:
			static Expression* Create(Expression* left, Expression* right, SemanCode oprator);
			~Operation()
			{
				delete left;
				delete right;
			}
		protected:
			Expression* left;
			Expression* right;
			Operation(Expression* left, Expression* right):left(left), right(right){}
		};

		class Addition : public Operation
		{
			Addition(Expression* left, Expression* right):Operation(left, right){}
		public:
			static Addition* Create(Expression* left, Expression* right)
			{
				return new Addition(left, right);
			}

			virtual int Interprete(Context &context)
			{
				return left->Interprete(context) + right->Interprete(context);
			}
		};

		class Multiplication : public Operation
		{
			Multiplication(Expression* left, Expression* right):Operation(left, right){}
		public:
			static Multiplication* Create(Expression* left, Expression* right)
			{
				return new Multiplication(left, right);
			}

			virtual int Interprete(Context &context)
			{
				return left->Interprete(context) * right->Interprete(context);
			}
		};

		class Identifier : public Expression
		{
			SemanCode id;
			Identifier(SemanCode id):id(id){}
		public:
			static Identifier* Create(SemanCode id)
			{
				return new Identifier(id);
			}

			int Interprete(Context& context)
			{
				return context.GetValue(id);
			}
		};

		class Constant : public Expression
		{
			int value;
			Constant(int value):value(value){}
		public:
			static Constant* Create(int value)
			{
				return new Constant(value);
			}

			virtual int Interprete(Context &context)
			{
				return value;
			}
		};

		/// <summary>
		/// 赋值语句
		/// </summary>
		class AssignStatement : public Statement
		{
			SemanCode id;
			Expression* exp;
			AssignStatement(SemanCode id, Expression* exp):id(id), exp(exp){}
		public: 
			static AssignStatement* Create(SemanCode id, Expression* exp)
			{
				return new AssignStatement(id, exp);
			}

			~AssignStatement()
			{
				delete exp;
			}

			void Interprete(Context &context)
			{
				context.Add(id, exp->Interprete(context));
			}
		};
		
		class StatementList
		{
			typedef list<Statement*> LIST;
			LIST statements;
			/// <summary>
			/// 指向在堆中开辟的计数变量,记录指向相同Statement对象集的StatementList
			/// </summary>
			int* pcount;
			string fileName;

			void destroy()
			{
				for (LIST::iterator it = statements.begin(); it != statements.end(); ++it)
					delete *it;
			}

		public:
			StatementList():pcount(new int(1)){}

			void SetFileName(const string& fileName)
			{
				this->fileName = fileName;
			}

			StatementList(const string& fileName):pcount(new int(1)), fileName(fileName){}

			StatementList(const StatementList& sl)
				:statements(sl.statements), pcount(sl.pcount), fileName(sl.fileName)
			{
				++pcount;
			}
			
			~StatementList()
			{
				if (--(*pcount) == 0) destroy();
			}

			StatementList& operator =(const StatementList& sl)
			{
				if (pcount == sl.pcount) return *this;
				if (--(*pcount) == 0) destroy();
				statements = sl.statements;
				pcount = sl.pcount;
				fileName = sl.fileName;
				++(*pcount);
				return *this;
			}

			string GetFileName()
			{
				return fileName;
			}

			/// <summary>
			/// 在StatementList中添加新指针指向Statement对象
			/// </summary>
			/// <param name = "pStatement">指向Statement对象的指针,
			/// 该对象必须在堆中,由new创建</param>
			void PushBack(Statement* pStatement)
			{
				statements.push_back(pStatement);
			}
			
			/// <summary>
			/// 用于元素遍历的迭代器
			/// </summary>
			class Iterator
			{
			public:
				Iterator(){}
				Iterator(LIST::iterator i):it(i){}

				Iterator& operator ++()
				{
					++it;
					return *this;
				}

				Iterator& operator --()
				{
					--it;
					return *this;
				}
				
				bool operator ==(Iterator right)
				{
					return this->it == right.it;
				}
				
				bool operator !=(Iterator right)
				{
					return this->it != right.it;
				}
				Statement* operator ->()
				{
					return *it;
				}
			private:
				LIST::iterator it;
			};
			
			Iterator Begin()
			{
				return Iterator(statements.begin());
			}

			Iterator End()
			{
				return Iterator( statements.end() );
			}

		};
		
		class Parser;
		/// <summary>
		/// 自动操作符栈,可按解析表达式自主操纵操作数栈,以完成操作
		/// </summary>
		class AutoOperatorStack
		{
			Stack<SemanCode> base;
			Parser* parser;
			Stack<Expression*>* operants;
		public:
			AutoOperatorStack(){}
			void SetParser(Parser* parser)
			{
				this->parser = parser;
			}
			void SetOperants(Stack<Expression*>* opts)
			{
				operants = opts;
			}

			AutoOperatorStack(Parser& parser, Stack<Expression*>& operants)
				:parser(&parser), operants(&operants){}
			void Push(SemanCode nextOperator);
			SemanCode Pop()
			{
				SemanCode opr = base.Top();
				base.Pop();
				return opr;
			}

			int Size()
			{
				return base.Size();
			}

			bool Empty()
			{
				return base.Empty();
			}
		};

		/// <summary>
		/// 语法分析器
		/// </summary>
		class Parser
		{
			TokenList tokens;
			TokenList::Iterator it;
			StatementList statements;
			Stack<Expression*> operants;
			AutoOperatorStack operators;
			ErrorLog* errors;
			friend void AutoOperatorStack::Push(SemanCode);
		public:
			Parser():it(tokens.Begin())
			{
				operators.SetParser(this);
				operators.SetOperants(&operants);
			}
			
			void Open(const TokenList& t)
			{
				tokens = t;
				it = tokens.Begin();
				statements.SetFileName(tokens.GetFileName());
			}

			Parser(const TokenList& t) : tokens(t)
			{
				it = tokens.Begin();
				statements.SetFileName(tokens.GetFileName());
				operators.SetParser(this);
				operators.SetOperants(&operants);
			};
			
			void SetErrorLog(ErrorLog* el)
			{
				errors = el;
			}

			StatementList& Execute(); 
		private:
			/// <summary>
			/// 当出现错误后略过该C0语句,直至分号
			/// </summary>
			void SkipOver();
			Statement* ParseRead();
			Statement* ParseWrite();
			Expression* ParseNum();
			Expression* ParseExpression();
			
			class ParserFailure : public exception
			{
				string errorMessage;
			public:
				ParserFailure(const string em):errorMessage(em){};

				virtual const char* what() const throw()
				{
					return errorMessage.c_str();
				}
			};
		};
	}
}

#endif

⌨️ 快捷键说明

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