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

📄 scanner.h

📁 编译程序的词法分析程序,具体执行词法分析部分
💻 H
字号:
//---------词法分析scanner.h---------------------------

#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#ifndef scanner_comp
#define scanner_comp
#define AL 10
#define TXMAX 1000
using namespace std;
struct table1
{
  char name[AL];
  int kind;
  int val;
};
struct table1 table[TXMAX+1];
int tab=0;

// 保留字数组定义
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"
};
char arrow[] = ",";
char enter[] = "\n";


// 读入空格
char GetBC(ifstream& src)
{
  char cRet;
  src.get(cRet);
  while (cRet == ' ')
    src.get(cRet);
  return cRet;
}
// 读入字符
char GetChar(ifstream& src)
{
  char cRet;
  src.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& src)
{
  src.seekg(-1, ios::cur);
  return '\0';
}
//填写符号表
void entertable(char name1[],int kind1,int val1)
{
  if (tab<TXMAX)
  {
    strcpy(table[tab].name,name1);
    table[tab].kind=kind1;
    table[tab].val=val1;
	tab++;
  }
  
}
// 词法分析函数
void Analyzer(ifstream& src, ofstream& dst)
{
  char ch;
  char sToken[1024] = "";
  ch = GetBC(src);

  if (isalpha(ch))//判断字母
  {
    while (isalpha(ch) || isdigit(ch) || ch == '_')
    {
      Concat(sToken, ch);
      ch = GetChar(src);
    }
    ch = Retract(src);
    if (Reserve(sToken))//关键字 输出二元表
	{
		for (int i = 0; i < 34; i++)
		{
          if (_stricmp(ReserveWords[i], sToken) == 0)
		dst << i << arrow << -1 << enter;
		}
	}
    else//非关键字
	{ 
	  entertable(sToken,34,0);
      dst << 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(sToken, ch);
      ch = GetChar(src);
    }
	if(ch=='.')
	{
	  
	  Concat(sToken, ch);
	  ch = GetChar(src);
	  while (isdigit(ch))
	  {
       ++i;
	   num=num+(ch-'0')/(i*10);
       Concat(sToken, ch);
       ch = GetChar(src);
	  }
	}
    Retract(src);
    if(i==0)
	{
	 entertable(sToken,35,num);
     dst << 35 << arrow  <<(tab-1)<< enter;
	}
	else
	{
	 entertable(sToken,36,num);
     dst << 36<< arrow <<tab-1<< enter;
	}
  }
  // 判断字符串的情况
  else if (ch == '\'')
  {
    Concat(sToken, ch);
    ch = GetChar(src);
    while (ch != '\'')
    {
      Concat(sToken, ch);
      ch = GetChar(src);
    }
    if (ch != '\'')
      cerr << "String is too long - more than 1024 bytes!" << endl;
    else
    { 
      Concat(sToken, ch);
	  entertable(sToken,37,0);
      dst << 37<< arrow << (tab-1) << enter;
    }
  }
  // 过滤注释
  else if (ch == '{')
  {
    while (GetChar(src) != '}')
      ;
  }
  // 判断所有没有歧义的单目运算符
  else if (ch == '+')
    dst << 43 << arrow << -1 << enter;
  else if (ch == '-')
    dst << 45<< arrow << -1 << enter;
  else if (ch == '*')
    dst << 41<< arrow << -1 << enter;
  else if (ch == '/')
    dst << 48 << arrow << -1 << enter;
  else if (ch == '=')
    dst << 56<< arrow << -1 << enter;
  else if (ch == '[')
    dst << 59 << arrow << -1 << enter;
  else if (ch == ']')
    dst << 60<< arrow << -1 << enter;
  else if (ch == ',')
    dst << 44<< arrow << -1 << enter;
  else if (ch == '^')
    dst << 42 << arrow << -1 << enter;
  else if (ch == ';')
    dst << 52<< arrow << -1 << enter;
  else if (ch == '(')
    dst << 39<< arrow << -1 << enter;
  else if (ch == ')')
    dst << 40<< arrow << -1 << enter;
  // 判断<、<>和<=
  else if (ch == '<')
  {
    ch = GetChar(src);
    if (ch == '>')
      dst << 55 << arrow << -1 << enter;
    else if (ch == '=')
      dst << 54<< arrow << -1<< enter;
    else
    {
      dst << 53 << arrow << -1 << enter;
      Retract(src);
    }
  }
  // 判断>和>=
  else if (ch == '>')
  {
    ch = GetChar(src);
    if (ch == '=')
      dst << 58 << arrow << -1 << enter;
    else
    {
      dst << 57 << arrow << -1 << enter;
      Retract(src);
    }
  }
  // 判断.和..
  else if (ch == '.')
  {
    ch = GetChar(src);
    if (ch == '.')
      dst << 47 << arrow << -1 << enter;
    else
    {
      dst << 46<< arrow << -1 << enter;
      Retract(src);
    }
  }
  // 判断:和:=
  else if (ch == ':')
  {
    ch = GetChar(src);
    if (ch == '=')
      dst << 51 << arrow << -1 << enter;
    else
    {
      dst << 50<< arrow << -1 << enter;
      Retract(src);
    }
  }
}

int scanner()
{
  string str;

    cout << "请输入程序路径: ";
    getline(cin, str);
  
  ifstream inf(str.c_str());
  if (inf.fail())
  {
    cerr << "\a文件打开失败 \"" << str << "\"!" << endl;
    return 1;
  }
  ofstream outf("token.txt");

  while (!inf.eof())
    Analyzer(inf, outf);
  outf.close();
  inf.close();
  cout << "二元token表结果已经保存在token.txt文件中." << endl;
  return 0;
}
#endif

⌨️ 快捷键说明

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