📄 scanner.cpp
字号:
#include<iostream.h>
#include<fstream.h>
#include<string.h>
int m = 0;
int n = 0;
int x[50], y[50];
char * reservechar[] = {"PROGRAM", "CONST", "VAR", "INTEGER", "LONG", "PROCEDURE",
"IF", "THEN", "WHILE", "DO", "READ", "WRITE", "BEGIN", "END", "ODD"};
//关键字表
char id[50][10]; //符号表
char cst[50][10]; //常数表
class Scanner
{
private:
int i, j; //指针
int length;
char ch, buffer[100], strtoken[20];
public:
Scanner(char str[], int n);
int isdigit();
int isletter();
int reserve();
int insertid();
int insertconst();
void getchar();
void getbc();
void concat();
void retract();
void scan();
};
Scanner::Scanner(char str[], int n) //构造函数
{
strcpy(buffer, str);
length = n;
i = j = 0;
}
int Scanner::isdigit()
{
if(ch>='0' && ch<='9')
return 1;
else
return 0;
}
int Scanner::isletter()
{
if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z'))
return 1;
else
return 0;
}
void Scanner::getchar() //将下一输入字符读到ch中,指针后移一字符位置
{
ch = buffer[i];
i++;
}
void Scanner::getbc() //保证ch是一个非空白字符
{
while(ch == ' ')
getchar();
}
void Scanner::concat() //将ch连接到字符串stroken的末尾
{
strtoken[j] = ch;
j++;
}
void Scanner::retract() //置ch为空白字符,指针前移一字符位置
{
ch = ' ';
i--;
}
int Scanner::reserve() //对stroken进行关键字表的查找,返回其编码值
{
int i, flag = 0;
for(i=0; i<15; i++)
{
if( strncmp(reservechar[i],strupr(strtoken), j) == 0 )
{
flag = 1;
break;
}
}
if(flag == 1) return i+1;
else return 0;
}
int Scanner::insertid() //将stroken中的标识符插入符号表,返回在符号表中的位置
{
for(int a = 0; a < m; a++)
for(int b = 0; b < x[a]; b++)
if( strncmp(&id[a][0], strtoken, j) == 0 )
{
return m+1;
break;
}
for(a = 0; a < j; a++)
id[m][a] = strtoken[a];
x[m] = j;
m++;
return m;
}
int Scanner::insertconst() //将stroken中的常数插入常数表,返回在常数表中的位置
{
for(int i = 0; i < j; i++)
cst[n][i] = strtoken[i];
y[n] = j;
n++;
return n;
}
void Scanner::scan()
{
while(i < length)
{
j = 0;
int code, value;
strcpy(strtoken, " "); //置strtoken为空串
getchar();
getbc();
if(isletter()) //如果打头的是字母
{
while(isletter() || isdigit())
{
concat();
getchar();
}
retract();
code = reserve();
if(code == 0) //如果扫描到的是标识符
{
value = insertid();
cout<<"<34,"<<value<<">"<<'\n';
}
else cout<<"<"<<code<<",->"<<'\n'; //如果扫描到的是关键字
}
else if(isdigit()) //如果打头的是数字
{
while(isdigit())
{
concat();
getchar();
}
retract();
value = insertconst();
cout<<"<33,"<<value<<">"<<'\n';
}
else if(ch == '+')
cout<<"<16,->"<<'\n';
else if(ch == '-')
cout<<"<17,->"<<'\n';
else if(ch == '*')
cout<<"<18,->"<<'\n';
else if(ch == '/')
cout<<"<19,->"<<'\n';
else if(ch == '=')
cout<<"<20,->"<<'\n';
else if(ch == '<')
{
getchar();
if(ch == '>')
cout<<"<21,->"<<'\n';
else if(ch == '=')
cout<<"<23,->"<<'\n';
else
{
retract();
cout<<"<22,->"<<'\n';
}
}
else if(ch == '>')
{
getchar();
if(ch == '=')
cout<<"<25,->"<<'\n';
else
{
retract();
cout<<"<24,->"<<'\n';
}
}
else if(ch == '.')
cout<<"<26,->"<<'\n';
else if(ch == ',')
cout<<"<27,->"<<'\n';
else if(ch == ';')
cout<<"<28,->"<<'\n';
else if(ch == ':')
{
getchar();
if(ch == '=')
cout<<"<30,->"<<'\n';
else
{
retract();
cout<<"<29,->"<<'\n';
}
}
else if(ch == '(')
cout<<"<31,->"<<'\n';
else if(ch == ')')
cout<<"<32,->"<<'\n';
else if(ch == '{')
{
while(ch != '}')
getchar();
}
else cout<<"出错!"<<'\n';
}
}
void main(void)
{
fstream file;
file.open("G:\My Work\编译原理\词法分析器\source_code.txt", ios::in||ios::nocreate); //以只读方式打开
file.unsetf(ios::skipws); //不跳过文本中的空格
char buffer[100];
while(file.getline(buffer, 100))
{
Scanner SS(buffer, strlen(buffer));
SS.scan();
}
cout<<"标识符表如下:\n"<<"编号\t"<<"值\n";
for(int i=0; i<m; i++)
{
cout<<i+1<<'\t';
for(int j=0; j<x[i]; j++)
cout<<id[i][j];
cout<<'\n';
}
cout<<"常数表如下:\n"<<"编号\t"<<"值\n";
for(i=0; i<n; i++)
{
cout<<i+1<<'\t';
for(int j=0; j<y[i]; j++)
cout<<cst[i][j];
cout<<'\n';
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -