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