📄 lexer.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 + -