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

📄 lexer.h

📁 编译原理实验:设计并实现一个Simple语言的编译器
💻 H
字号:
/************************************************************************/
/* 文件名:lexer.h														*/
/* 功  能:词法分析器					                               */
/* 创建时间:2007-7-1													*/
/* 最后修改时间:2007-7-3				                                */
/************************************************************************/

#ifndef LEXER_H_LEXER_H
#define LEXER_H_LEXER_H
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "global.h"
using namespace std;

struct SignTable signtable[TXMAX+1];
int tab=0;
char arrow[] = ",";
char enter[] = "\n";
//---------------保留字数组定义--------------------//
char* ReserveWords[34] = 
{
    "flout","and", "array", "begin","boll", "call","case","char", "constant", "do", "else", 
	"end", "false","for", "if", "input", "integer",  "not", "of", "or", "output","procedure",
	"program", "read","real", "repeat", "set", "then", "to", "true", "until", "var","while", 
	"write"
};

//----------------填写符号表----------------------//
void entertable(char name1[],int kind1,int val1)
{
	if (tab<TXMAX)
	{
		strcpy(signtable[tab].name,name1);
		signtable[tab].kind=kind1;
		signtable[tab].val=val1;
		tab++;
	} 
}

//-----------------读取源程序中的字符-------------//
char GetChar(ifstream& sourefile)
{
	char cRet;
	sourefile.get(cRet);
	return cRet;
}

//------------------过滤空白符--------------------//
char GetBC(ifstream& sourefile)
{
	char cRet;
	sourefile.get(cRet);
	while (cRet == ' ')
		sourefile.get(cRet);
	return cRet;
}

//------------------识别并连接单词---------------//
void Concat(char *str, char c)
{
	size_t n = strlen(str);
	str[n++] = c;
	str[n] = '\0';
}

//------------------判断是否为保留字-------------//
bool Reserve( char* str)
{
	bool bRet = false;
	for (int i = 0; i < 34; i++)
	{
		if (_stricmp(ReserveWords[i], str) == 0)
		{
			bRet = true;
			break;  
		}
	}
	return bRet;
}

//------------------回调字符---------------------//
char Retract(ifstream& sourefile)
{
	sourefile.seekg(-1, ios::cur);
	return '\0';
}

//----------------词法分析-----------------------//
void lexer(ifstream& sourefile, ofstream& fout)
{
	char ch;
	char strToken[1024] = "";
	ch = GetBC(sourefile);
	//判断标识符的情况
	if (isalpha(ch))
	{
		while (isalpha(ch) || isdigit(ch) || ch == '_')
		{
		  Concat(strToken, ch);
		  ch = GetChar(sourefile);
		}
		ch = Retract(sourefile);
		if (Reserve(strToken))
		{
			for (int i = 0; i < 34; i++)
			{
				if (_stricmp(ReserveWords[i], strToken) == 0)
				{
					fout << i << arrow << -1 << enter;
				}
			}
		}
		else
		{ 
			entertable(strToken,34,0);
			fout << 34 << arrow <<tab-1<< enter;
		}
	}
	// 判断数值的情况
	else if (isdigit(ch))
	{
		float num=0.0;
		float i=0;
		while (isdigit(ch))
		{
			num=num*10+ch-'0';
			Concat(strToken, ch);
			ch = GetChar(sourefile);
		}
		if(ch=='.')
		{ 
			Concat(strToken, ch);
			ch = GetChar(sourefile);
			while (isdigit(ch))
			{
				++i;
				num=num+(ch-'0')/(i*10);
				Concat(strToken, ch);
				ch = GetChar(sourefile);
			}
		}
		Retract(sourefile);
		if(i==0)
		{
			entertable(strToken,35,num);
			fout << 35 << arrow  <<(tab-1)<< enter;
		}
		else
		{
			entertable(strToken,36,num);
			fout << 36<< arrow <<tab-1<< enter;
		}
	}
    //判断字符串的情况
	else if (ch == '\'')
	{
	    Concat(strToken, ch);
		ch = GetChar(sourefile);
		while (ch != '\'')
		{
			Concat(strToken, ch);
			ch = GetChar(sourefile);
		}
		 if (ch != '\'')
		     cerr << "字符串太长超过了1024个字节!" << endl;
		 else
		 { 
			 Concat(strToken, ch);
			 entertable(strToken,37,0);
			 fout << 37<< arrow << (tab-1) << enter;
		 }
	  }
	  //过滤注释
      else if (ch == '{')
	  {
		  while (GetChar(sourefile) != '}')
		     ;
	  }
	  // 判断所有没有歧义的单目运算符
	  else if (ch == '+')
		  fout << 43 << arrow << -1 << enter;
	  else if (ch == '-')
		  fout << 45<< arrow << -1 << enter;
	  else if (ch == '*')
	   	  fout << 41<< arrow << -1 << enter;
	  else if (ch == '/')
		  fout << 48 << arrow << -1 << enter;
	  else if (ch == '=')
		  fout << 56<< arrow << -1 << enter;
	  else if (ch == '[')
		  fout << 59 << arrow << -1 << enter;
	  else if (ch == ']')
		  fout << 60<< arrow << -1 << enter;
	  else if (ch == ',')
		  fout << 44<< arrow << -1 << enter;
	  else if (ch == '^')
		  fout << 42 << arrow << -1 << enter;
	  else if (ch == ';')
		  fout << 52<< arrow << -1 << enter;
	  else if (ch == '(')
	      fout << 39<< arrow << -1 << enter;
	  else if (ch == ')')
		  fout << 40<< arrow << -1 << enter;
	  // 判断<、<>和<=
	  else if (ch == '<')
	  {
		  ch = GetChar(sourefile);
	      if (ch == '>')
			  fout << 55 << arrow << -1 << enter;
		  else if (ch == '=')
		      fout << 54<< arrow << -1<< enter;
		  else
		  {
		      fout << 53 << arrow << -1 << enter;
		      Retract(sourefile);
		  }
	  }
	  //判断>和>=
	  else if (ch == '>')
	  {
		  ch = GetChar(sourefile);
		  if (ch == '=')
		      fout << 58 << arrow << -1 << enter;
		  else
		  {
		      fout << 57 << arrow << -1 << enter;
		      Retract(sourefile);
		  }
	  }
	  //判断.和..
	  else if (ch == '.')
	  {
		 ch = GetChar(sourefile);
		 if (ch == '.')
		    fout << 47 << arrow << -1 << enter;
		 else
		 {
		    fout << 46<< arrow << -1 << enter;
		    Retract(sourefile);
		 }
	  }
	 //判断:和:=
	 else if (ch == ':')
	 {
		  ch = GetChar(sourefile);
		  if (ch == '=')
		      fout << 51 << arrow << -1 << enter;
		  else
		  {
		      fout << 50<< arrow << -1 << enter;
		      Retract(sourefile);
		  }
	 }
}

//----------------------词法分析器总控制----------------------//
int lexmain()
{
	string filename;
	//读入文件名
	cout << "请输入源代码的文件名(格式:文件名+后缀): ";
	getline(cin, filename); 
	//打开文件
	ifstream sourefile(filename.c_str());
	if (sourefile.fail())
	{
		cerr << "\a打开文件\"" << filename << "\"失败!" << endl;
		return 1;
	}
	ofstream fout("lexer.txt");
	//开始词法分析
	while (!sourefile.eof())
		lexer(sourefile, fout);
	fout.close();
	sourefile.close();
	cout << "词法分析成功,结果保存在lexer.txt中!" << endl;
	return 0;
}
#endif

⌨️ 快捷键说明

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