📄 wanshang.cpp
字号:
#include<fstream.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
FILE *keyword;//存放关键字
FILE *sourcefile;//存放源文件
char shuzi[100][20];//存数字
char biaoshifu[100][20];//存标识符
int sz; //数字数组的下标
int bsf;//标识符数组的下标
int count=0;//记录错误个数
int line;//记录行数
void Isnumber(char c);
void Isalpha(char c);
void Isother(char c);
void error(int a);
void noblank( char &ch);
void isanotation(char ch);
void main()
{ cout<<"*************************欢迎使用词法分析器*********************"<<endl<<endl;
char filename[20];
cout<<"请输入要分析的文件路径:";
cin>>filename;
char ch;
sourcefile = fopen(filename,"r");
if(sourcefile==NULL)cout<<"文件不存在!";
ch=fgetc(sourcefile);
if(ch=='\n')
line++;
while(ch!=EOF)
{
noblank( ch ); //跳过回车,空格
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_'){Isalpha(ch);}
else
{if(ch>='0'&&ch<='9'){Isnumber(ch);}
else
{if(ch=='/'){isanotation(ch);}
else{ Isother(ch);}
}
}
ch=fgetc(sourcefile);
if(ch=='\n')line++;
}
cout<<endl;
//输出标识符表
int i=0;
cout<<"文件生成的标识符表"<<endl;
for(;i<bsf;i++)
cout<<i<<'\t'<<biaoshifu[i]<<endl;
//输出常数表
cout<<"文件生成的常数表"<<endl;
for( i=0;i<sz;i++)
cout<<i<<'\t'<<shuzi[i]<<endl;
}
void Isnumber(char c)
{ ofstream outfile("aim.txt",ios::app);
if (!outfile)
{
cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
exit(-1);
}
char arr[20];
int i=0;
arr[i]=c;
c=fgetc(sourcefile);
if(c=='\n')line++;//再读入下一个字符
while(c>='0'&&c<='9')
{
arr[++i]=c;
c=fgetc(sourcefile);
if(c=='\n')line++;
}
if(c!='.')//如果当前读入的符号不为小数点,则常数读完毕,输出此常数
{fseek(sourcefile,-1,SEEK_CUR);
arr[++i]='\0';
if(sz!=0)
{ int j=0;
while(j<sz)
{if(strcmp(arr,shuzi[j])==0)break;
else j++;
}
if(j>=sz)//"数字表未定义"
{
strcpy(shuzi[sz],arr);
cout<<"("<<arr<<","<<sz<<")"<<" ";
outfile<<"("<<arr<<","<<sz<<")"<<" ";
sz++;
}
else //定义输出位置
{cout<<"("<<arr<<","<<j<<")"<<" ";
outfile<<"("<<arr<<","<<j<<")"<<" ";
}
}
else
{ strcpy(shuzi[sz],arr);
cout<<"("<<arr<<","<<sz<<")"<<" ";
outfile<<"("<<arr<<","<<sz<<")"<<" ";
sz++;
}
}
else//当前字符为小数点则继续向下读入
{
arr[++i]=c;
c=fgetc(sourcefile);if(c=='\n')line++;
while(c>='0'&&c<='9')
{
arr[++i]=c;
c=fgetc(sourcefile);
if(c=='\n')line++;
}
fseek(sourcefile,-1,SEEK_CUR);
arr[++i]='\0';
if(sz!=0)
{ int j=0;
while(j<sz)
{if(strcmp(arr,shuzi[j])==0)
break;
else j++;
}
if(j>=sz)
{
strcpy(shuzi[sz],arr);
cout<<"(num,"<<sz<<")"<<" ";
outfile<<"(num,"<<sz<<")"<<" ";
sz++;
}
else
{cout<<"(num,"<<j<<")"<<" ";
outfile<<"(num,"<<j<<")"<<" ";
}
}
else
{ strcpy(shuzi[sz],arr);
cout<<"(num,"<<sz<<")"<<" ";
outfile<<"(num,"<<sz<<")"<<" ";
sz++;
}
}
}
void Isalpha(char c)
{
keyword = fopen("D:keyword.txt","r");
ofstream outfile("aim.txt",ios::app);//追加方式打开
if (!outfile)
{
cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
exit(-1);
}
char arr[20];
char temp[20];
int i=0;
arr[i]=c;
c=fgetc(sourcefile);
if(c=='\n')line++;
while((c>='a'&&c<='z')||(c>='0'&&c<='9')||(c>='A'&&c<='Z'))
{
arr[++i]=c;
c=fgetc(sourcefile);
if(c=='\n')line++;
}
arr[++i]='\0';
fseek(sourcefile,-1,SEEK_CUR);
//把字符数组arr和关键字表比较,判断单词串是关键字还是标识符
c=fgetc(keyword);
i=0;
while(c!=EOF)
{
while(c!='\n')
{
temp[i++]=c;
c=fgetc(keyword);
}
temp[i]='\0';
i=0;
if(strcmp(temp,arr)==0)
{ cout<<"("<<arr<<",-)"<<" ";
outfile<<"("<<arr<<",-)";
return; /*若找到,退出函数*/
}
else
c=fgetc(keyword);
} //结束外层while循环
if(bsf!=0)
{ int j=0;
while(j<bsf)
{if(strcmp(arr,biaoshifu[j])==0)
break;
else j++;
}
if(j>=bsf)//"标识符表未定义"
{
strcpy(biaoshifu[bsf],arr);
cout<<"("<<"id"<<","<<bsf<<")"<<" ";
outfile<<"("<<"id"<<","<<bsf<<")";
bsf++;
}
else
{cout<<"("<<"id"<<","<<j<<")"<<" ";
outfile<<"("<<"id"<<","<<bsf<<")";
}
}
else
{ strcpy(biaoshifu[bsf],arr);
cout<<"("<<arr<<","<<bsf<<")";
outfile<<"("<<"id"<<","<<bsf<<")";
bsf++;
}outfile.close();
}
void Isother(char ch)
{ ofstream outfile("aim.txt",ios::app);
if (!outfile)
{
cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
exit(-1);
}
switch(ch){
case '(':cout<<"((,-)"<<" ";
outfile<<"((,-)"<<" ";
break;
case ')':cout<<"(),-)"<<" ";
outfile<<"(),-)"<<" ";
break;
case '[':cout<<"([,-)"<<" ";
outfile<<"([,-)"<<" ";
break;
case ']':cout<<"(],-)"<<" ";
outfile<<"(],-)"<<" ";
break;
case '*':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{cout<<"(*=,-)"<<" ";
outfile<<"(*=,-)"<<" ";}
else{ cout<<"(*,-)"<<" ";
fseek(sourcefile,-1,SEEK_CUR);
outfile<<"(*,-)"<<" ";}
break;
case '+':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{cout<<"(+=,-)";
outfile<<"(+=,-)"<<" ";
}
else
{cout<<"(+,-)";
fseek(sourcefile,-1,SEEK_CUR);
outfile<<"(+,-)"<<" ";
}
break;
case ',':cout<<"(,,-)";
outfile<<"(,,-)"<<" ";
break;
case '-':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{ cout<<"(-=,-)";
outfile<<"(-=,-)"<<" ";
}
else {cout<<"(-,-)";
fseek(sourcefile,-1,SEEK_CUR);
outfile<<"(-,-)"<<" ";}
break;
case '.':cout<<"(.,-)";
outfile<<"(.,-)"<<" ";
break;
case ':': cout<<"(:,-)";
outfile<<"(:,-)"<<" ";
break;
case ';':cout<<"(;,-)"<<" ";
outfile<<"(;,-)"<<" ";
break;
case '<': ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{cout<<"(rlop,-)";
outfile<<"(rlop,-)"<<" ";
}
else {cout<<"(rlop,-)"<<" ";
fseek(sourcefile,-1,SEEK_CUR);
outfile<<"(rlop,-)"<<" ";
}
break;
case '=':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
cout<<"(==,-)"<<" ";
else {fseek(sourcefile,-1,SEEK_CUR);
cout<<"(=,-)"<<" ";
outfile<<"(=,-)"<<" ";
}
break;
case '>': ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{ cout<<"(rlop,-)";
outfile<<"(rlop,-)"<<" ";
}
else { fseek(sourcefile,-1,SEEK_CUR);
cout<<"(rlop,-)"<<" ";
outfile<<"(rlop,-)"<<" ";
}
break;
case '%':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{ cout<<"(%=,-)";
outfile<<"(%=,-)"<<" ";
}
else { fseek(sourcefile,-1,SEEK_CUR);
cout<<"(%,-)"<<" ";
outfile<<"(%,-)"<<" ";
}
break;
case '!':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='=')
{ cout<<"(!=,-)";
outfile<<"(!=,-)"<<" ";
}
else { fseek(sourcefile,-1,SEEK_CUR);
cout<<"(not,-)"<<" ";
outfile<<"(not,-)"<<" ";
}
break;
case '|':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='|')
{ cout<<"(or,-)";
outfile<<"(or,-)"<<" ";
}
else { fseek(sourcefile,-1,SEEK_CUR);
error(1);
}
break;
case '&':ch=fgetc(sourcefile);
if(ch=='\n')line++;
if(ch=='&')
{ cout<<"(and,-)";
outfile<<"(and,-)"<<" ";
}
else { fseek(sourcefile,-1,SEEK_CUR);
error(1);
}
break;
default:error(1);
break;
}
outfile.close();
}
void isanotation(char ch)
{ ofstream outfile("aim.txt",ios::app);
if (!outfile)
{
cerr<<"无法打开文件 "<<"aim.txt"<<" !!!"<<endl;
exit(-1);
}
ch=fgetc(sourcefile);
if(ch=='\n')line++;
else if(ch=='=')
{cout<<"(/=,-)"<<" ";}
else if(ch=='*')
for(;;)
{
ch=fgetc(sourcefile);
//if(ch=='\n')line++;
if(ch==EOF){error(2);break;}
if(ch=='*')
{
ch=fgetc(sourcefile);
if(ch=='/')
{
return;
}
}
}
else{ fseek(sourcefile,-1,SEEK_CUR); /*不是注释,当作除号处理*/
cout<<"(/,-)"<<" ";
outfile<<"(/,-)"<<" ";
}
}
void error(int a)
{
count++;
switch(a)
{
case 1: cout<<"错误"<<count<<":第"<<line<<"行字符非法!"<<endl;break;
case 2: cout<<"错误"<<count<<":第"<<line<<"行没有匹配的*/"<<endl;break;
default:break;
}
}
void noblank( char &ch) //跳过空格,回车
{
while(ch == ' ' || ch == '\n')
{ch = fgetc(sourcefile);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -