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

📄 lexer.h

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

#ifndef LEXER_H
#define LEXER_H

#include <list>
#include <string>
#include <map>
#include <sstream>
#include "C0Types.h"
#include "File.h"
#include "Error.h"

namespace C0
{
	namespace Lexer
	{
		using namespace std;
		using FileAdapter::File;
		using Interpreter::ErrorLog;

		/// <summary>
		/// 单词与语义编码的映射
		/// </summary>
		class SemanMapper
		{
			static map<string, SemanCode> semans;
			/// <summary>
			/// 初始化单词与语义编码的映射,当且仅当第一次查询时调用
			/// <summary>
			static void Initialize()
			{	
				semans.insert(make_pair("{", LBRACE));
				semans.insert(make_pair("+", PLUS));
				semans.insert(make_pair("*", MULT));
				semans.insert(make_pair("=", ASS));
				semans.insert(make_pair("read", READ));
				semans.insert(make_pair("write", WRITE));
				semans.insert(make_pair("}", RBRACE));
				semans.insert(make_pair(";", SEMI));
				semans.insert(make_pair("(", OPEN));
				semans.insert(make_pair(")", CLOSE));
				semans.insert(make_pair("EOF", END));
			}
		public:
			static SemanCode GetSeman(const string& word)
			{
				if (semans.empty()) Initialize();
				return semans[word];
			}
		};

		/// <summary>
		/// 单词与记号类型的映射
		/// </summary>
		class TypeMapper
		{
			static map<string, TokenType> types;
			/// <summary>
			/// 初始化单词与记号类型的映射,当且仅当第一次查询时调用
			/// <summary>
			static void Initialize()
			{
				types.insert(make_pair("{", FORMAT));
				types.insert(make_pair("+", OPERATOR));
				types.insert(make_pair("*", OPERATOR));
				types.insert(make_pair("=", OPERATOR));
				types.insert(make_pair("read", KEYWORD));
				types.insert(make_pair("write", KEYWORD));
				types.insert(make_pair("}", FORMAT));
				types.insert(make_pair(";", FORMAT));
				types.insert(make_pair("(", FORMAT));
				types.insert(make_pair(")", FORMAT));
				types.insert(make_pair("EOF", FORMAT));
			}
		public:
			static TokenType GetType(const string &word)
			{
				if (types.empty()) Initialize();
				return types[word];
			}
		};

		/// <summary>
		/// 标识符与语义编码映射
		/// </summary>
		class IDTable
		{
			static map<string, SemanCode> idSeman;
		public:
			static SemanCode GetSeman(const string &id)
			{
				SemanCode sc = idSeman[id];
				if (!sc) sc = idSeman[id] = SemanCode(idSeman.size());
				return sc;
			}
		};

		/// <summary>
		/// 语义记号抽象类
		/// </summary>
		class Token
		{
		protected:	
			int lineNum;
			int charNum;
			string word;
			SemanCode seman;

			Token(const string& word, int lineNum, int charNum)
			{
				this->word = word;
				this->lineNum = lineNum;
				this->charNum = charNum;
			}

		public:
			int GetLineNum()
			{
				return lineNum;
			}

			int GetCharNum()
			{
				return charNum;
			}
			
			string& GetWord()
			{
				return word;
			}

			SemanCode GetSeman()
			{
				return seman;
			}

			virtual TokenType GetType() = 0;
		};

		//各实现类型
		//保留字
		class Keyword : public Token
		{
		public:
			Keyword(const string& word, int lineNum, int charNum)
				:Token(word, lineNum, charNum)
			{
				seman = SemanMapper::GetSeman(word);
			}
			TokenType GetType()
			{
				return KEYWORD;
			}
		};

		//标识符
		class Identifier : public Token
		{
		public:
			Identifier(const string& word, int lineNum, int charNum)
				:Token(word, lineNum, charNum)
			{
				seman = IDTable::GetSeman(word);
			}
			TokenType GetType()
			{
				return IDENTIFIER;
			}
		};

		//常数
		class Constant : public Token
		{
		public:
			Constant(const string& word, int lineNum, int charNum)
				:Token(word, lineNum, charNum)
			{
				int tempSeman;
				std::stringstream sstr;
				sstr << word;
				sstr >> tempSeman;
				seman = SemanCode(tempSeman);
			}
			TokenType GetType()
			{
				return CONSTANT;
			}
		};

		//运算符
		class Operator : public Token
		{
		public:
			Operator(const string& word, int lineNum, int charNum)
				:Token(word, lineNum, charNum)
			{
				seman = SemanMapper::GetSeman(word);
			}
			TokenType GetType()
			{
				return OPERATOR;
			}
		};

		//格式符
		class Format : public Token
		{
		public:
			Format(const string& word, int lineNum, int charNum)
				:Token(word, lineNum, charNum)
			{
				seman = SemanMapper::GetSeman(word);
			}
			TokenType GetType()
			{
				return FORMAT;
			}
		};

		/// <summary> 
		/// 语义记号链表
		/// </summary>
		class TokenList
		{
			typedef list<Token *> LIST;
			LIST ptokens;
			/// <summary>
			/// 指向在堆中开辟的计数变量,记录指向相同Token对象集的TokenList
			/// </summary>
			int* pcount;
			string fileName;

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

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

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

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

			TokenList(const TokenList& t):ptokens(t.ptokens), pcount(t.pcount),fileName(t.fileName)
			{
				++(*pcount);
			}

			string GetFileName()
			{
				return fileName;
			}

			TokenList& operator =(const TokenList &t)
			{
				if (pcount == t.pcount) return *this;
				if (--(*pcount) == 0) destroy();
				ptokens = t.ptokens;
				pcount = t.pcount;
				fileName = t.fileName;
				++(*pcount);
				return *this;
			}

			~TokenList()
			{
				if (--(*pcount) == 0) destroy();
			}

			/// <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;
				}
				Token* operator ->()
				{
					return *it;
				}
			private:
				LIST::iterator it;
			};

			void PushBack(const string &word, int lineNum, int charNum)
			{
				//追加记号为常数
				if ('0' <= word[0] && word[0] <= '9')
				{
					ptokens.push_back(new Constant(word, lineNum, charNum));
					return;
				} 
				//追加记号不是常数
				Token *token;
				switch(TypeMapper::GetType(word))
				{
				case IDENTIFIER:
					token = new Identifier(word, lineNum, charNum);
					break;
				case KEYWORD:
					token = new Keyword(word, lineNum, charNum);
					break;
				case OPERATOR:
					token = new Operator(word, lineNum, charNum);
					break;
				case FORMAT:
					token = new Format(word, lineNum, charNum);
					break;
				case CONSTANT:
					token = new Constant(word, lineNum, charNum);
				}
				ptokens.push_back(token);
			}

			Iterator Begin()
			{
				return Iterator( ptokens.begin() );
			}

			Iterator End()
			{
				return Iterator( --ptokens.end() );
			}
			
		};

		/// <summary>
		/// 词法分析器
		/// </summary>
		class Lexer
		{
			File inFile;
			TokenList tokens;
			ErrorLog* errors;
		public:
			Lexer(){}

			void Open(const string& file)
			{
				inFile.Open(file);
				tokens.SetFileName(file);
			}
				
			Lexer(const string& fileName)
			{
				Open(fileName);
			}

			void SetErrorLog(ErrorLog* el)
			{
				errors = el;
			}

			void PrintSourceFile();

			/// <summary>
			/// 对源程序文件执行解析
			/// </summary>
			/// <returns>返回对记号链表的常引用</returns>
			const TokenList& Execute();
			
			~Lexer()
			{
				inFile.Close();
			}

		private:
			/// <summary>
			/// 获得字母的小写形式
			/// </summary>
			/// <returns>返回转化是否成功;如果参数不是字母,返回false</returns>
			bool Lexer::ToLowercase(char &letter);

			string Lexer::GetNum(File& inFile);

			string Lexer::GetIdentifier(File& inFile);
		};
	}
}
#endif

⌨️ 快捷键说明

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