📄 1020310725.cpp
字号:
#include<iostream.h>
#include<stdio.h>
#include <fstream>
#define BMaxlen 10000 //定义缓冲区的最大长度
#define WMaxlen 10 //用来定义取出的标识符的最大长度
#define KEY_No 32 //定义要比较的关键字的个数
#define Maxtype '5' //单词的总类型共有5种
char *KEY[KEY_No]={{"include"},{"main"},{"if"},{"else"},{"int"},
{"char"},{"for"},{"while"},{"do"},{"return"},{"break"},{"printf"},
{"scanf"},{","},{";"},{"{"},{"}"},{"("},{")"},{"+"},{"-"},{"*"},
{"/"},{"#"},{"%"},{"="},{"<"},{">"},{">="},{"<="},{"!="},{"=="}
};
char Symbolk[100][10];//作为一个缓冲区,用来存放将要写入symbolk文件中的字符编号
int Inr=0;
int flag1;
char Str[BMaxlen];//建立缓冲区
char Word[WMaxlen];//用来标识标识取出的单词,且其长度不超过单词的最大长度
int pStr=-1; //用来表示从缓冲区取字母时的指针
char ch; //用来表示从缓冲区中取出的一个字母
int Flag=1;//标志缓冲区中是否还有字母,如果没有则为-1;如果还有则其为1
char CType;//用来标识得到的单词的类型
int CNum;//用来标识得到的字符的编号
char Lasttype;//用来标识是其前面的单词的类型
void insource()//用来把文件中的内容放到缓冲区中,以'@'作为标识符
{
FILE *fp;
char c;
int i=0;
if((fp=fopen("t.txt","r"))==NULL)
printf("Not found!");
else
{
while((c=fgetc(fp))!=EOF)
Str[i++]=c;
}
Str[i]='@'; //以'@'作为标识符
fclose(fp);
}
void scanner()//用来从缓冲区中取一个字符,如果成功,则返回1,否则为-1
{
ch=Str[++pStr];
if (ch=='@')
Flag=-1;//当取出的字符是'@',则表明缓冲区中已无字符,返回值为-1
else Flag=1;
}
void Insymbolk()//来把字符写入文件a.txt中
{
FILE *fp1;
int q=-1;
flag1=0;
for (int p=-1;p<Inr;p++)//判断取出的当前单词是不是已经写入文件中了
if (strcmp(Word,Symbolk[p])==0)
{
flag1=1;break;
}
if(flag1==0)
{
cout<<"写入"<<endl;
fp1=fopen("a.txt","a+");
fprintf(fp1,"%s",Word);
for(int j=0;j<5;j++)
fputc('-',fp1);
fprintf(fp1,"%d",CNum);
fputc('\n',fp1);
fclose(fp1);
strcat(Symbolk[Inr++],Word);//把该字符加入到数组中,以供以后的操作进行判断是否应该写入文件中
}
else cout<<"已写入"<<endl;
}
void Work()//从缓冲区中取一个单词进行词法分析
{
bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为false
int k=-1; //表示取出的字符放在单词数组的指针
CType='0'; //预先定义的取出的单词的类型
Lasttype='0'; //初始化先前的类型,此变量为判断正负数用
scanner();//首先取出一个字符
if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')//取出标识符或者是关键词
{
while(true)//取出的单词长度不超过WMaxlen,如果超过,则其后的字符无效
{
if((++k)<WMaxlen)//(++k)为了使取出的单词最长为WMaxlen
{
Word[k]=ch;
scanner();//处理完一个后,紧接着再取出一个字符供一次判断
if (!(ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'||ch=='.'))
break; //如果后继取出的字符不是字母或是数字,则此次取单词结束
}
}
Word[++k]='\0';//以'\0'标识取出单词的结束,这样便把单词各自分离开来
for (int i=0;i<13;i++)//判断取出的当前单词是不是关键词
if (strcmp(Word,KEY[i])==0)
{
flag=true;
break;
}
if (flag){
CType='1';//如果是关键词,则把此单词的类型定义为k型
}
else CType='2';
{ //否则是标识符,其类型为2
pStr--;//原理和把pStr初始化为-1一样。
CNum=33;//因为符号表的数目为33个,所以标识符的编号34
}
}
else if (ch>='0' && ch<='9')//判断是不是为整数
{
Word[++k]=ch;
scanner();
while(true)//如果是数字,则一直接受,且定义它的类型为3
{
if(ch>='0' && ch<='9')
{
Word[++k]=ch;
scanner();//完成操作后立即取出下一个字符
}
else
CType='3';
Word[++k]='\0';
CNum=34;
break;
//不是数字则跳出循环
}
}
else if (ch=='+'||ch=='-'||ch=='*'||ch=='/')//取出是运算符号的单词
{
Word[++k]=ch;
if (ch=='+' || ch=='-')//如果是+号或者是-号,则还要判断是不是正负数
{
if (Lasttype=='6')//判断其取出的当前字母的前一个单词是6号类型的,
//即是<、>、<=、>=、==、=时则可判断现在取出的是整数
{
while(ch>='0' && ch<='9')//如果是整数 ,则说明是正负号
{
scanner();
Word[++k]=ch;
}
CType='3';//如果正负整数,则直接返回类型为3,则表示此单词为整数
}
}
else
Word[++k]='\0';
CType='4';//如果不是整数,则定义当前取出的单词是运算符,定义此类型为4
}
else if (ch=='>'||ch=='<'||ch=='='||ch=='!')//取出运算符的另几类,即<、<=、>、>=、==、=、!=
{
Word[++k]=ch;
scanner();
if( ch=='=')//判断是不是<=、>=、==、!=
Word[++k]=ch;
else pStr--;//如果不是=则后退一位 ,以便下次取用
Word[++k]='\0';
CType='4';
Lasttype='6';//当下一个字符的开头为“+”或“-”时,可以据些来判断是不是正负数
}
else if (ch==','||ch==';'||ch=='{'||ch=='}'||ch=='('||ch==')'||ch=='#')
//判断当前取出的单词是不是界符,如果是界符,则定义其类型为5
{
CType='5';
Word[++k]=ch;
Word[++k]='\0';
}
for (int j=0;j<KEY_No;j++)//判断取出的当前单词是不是关键词
if (strcmp(Word,KEY[j])==0)
{
CNum=j;
break;
}//查出其编号
if(CType==0){}//用来处理空格,即如果是空格,则不执行任何操作。
else if(CType=='1')
{
cout<<Word<<"-------"<<CNum;
cout<<"---------关健字"<<endl;
Insymbolk();//把字符写进符号表symbolk.txt中。
}
else if(CType=='2')
{
cout<<Word<<"-------"<<CNum;
cout<<"----------标识符"<<endl;
Insymbolk();//把字符写进符号表symbolk.txt中。
}
else if(CType=='3')
{
cout<<Word<<"-------"<<CNum;
cout<<"----------整数"<<endl;
Insymbolk();//把字符写进符号表symbolk.txt中。
}
else if(CType=='4')
{
cout<<Word<<"-------"<<CNum;
cout<<"---------运算符"<<endl;
Insymbolk();//把字符写进符号表symbolk.txt中。
}
else if(CType=='5')
{
cout<<Word<<"-------"<<CNum;
cout<<"--------分割符"<<endl;
Insymbolk();//把字符写进符号表symbolk.txt中。
}
}
int main()
{
int j=0;
insource();//把文件中的内容放入缓冲区
Flag=1;//初始化定义,认为缓冲区中还有字母
cout<<"word-----cnum------TYPE"<<endl<<endl;
while(Flag!=-1)
Work();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -