📄 词法分析.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();//对stroken进行关键字表的查找,返回其编码值
int insertid();//将stroken中的标识符插入符号表,返回在符号表中的位置
int insertconst();//将stroken中的常数插入常数表,返回在常数表中的位置
void getchar();//将下一输入字符读 到ch中,指针后移一字符位置
void getbc();//保证ch是一个非空白字符
void concat();//将ch连接到字符串stroken的末尾
void retract();//置ch为空白字符,指针前移一字符位置
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("F:/20032320/20032320.txt", ios::in||ios::nocreate); //以只读方式打开
file.unsetf(ios::skipws); //不跳过文本中的空格
char buffer[100]; //缓冲区定义
cout<<"扫描结果如下所示"<<'\n';
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 + -