📄 yufa.cpp
字号:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<iostream.h>
#include<windows.h>
/*关键字*/
typedef struct keyword
{
char *name;
int code;
}keyword;
keyword key[11]={{"begin",1},{"end",2},{"if",3},{"then",4},{"else",5},
{"for",6},{"do",7},{"while",8},{"and",9},{"or",10},{"not",11}};
#define ID 12
#define INT 13
#define ADD 14
#define MIN 15
#define MUL 16
#define DIV 17
#define LT 18
#define LE 19
#define EQ 20
#define GE 21
#define GT 22
#define NE 23
#define EVA 24
#define LP 25
#define RP 26
#define SEM 27
/*相关初始化*/
FILE *in,*outfile;//输入输出文件指针
char token[50];//存储一个单词词文中的各个字符
int error_count=0;//错误计数
int b;//记录数值大小
int k;//记录标识符长度
char ch1;//辅助变量
int row=0;//代码行数
int queue=0;//代码列数
/*报错函数*/
void report_error(int a)
{
error_count++;
switch(a)
{
case 1:cout<<"标识符长度超过6,不合法"<<" "<<"行"<<row<<","<<"列"<<queue<<endl;
break;
case 2:cout<<"非法字符"<<" "<<"行"<<row<<","<<"列"<<queue<<endl;
break;
case 3:cout<<"数值超过最大表示范围,溢出"<<" "<<"行"<<row<<","<<"列"<<queue<<endl;
break;
case 4:cout<<"没有匹配的注释符 '*/' "<<" "<<"行"<<row<<","<<"列"<<queue<<endl;
break;
case 5:cout<<"标识符以数字开头,不合法"<<" "<<"行"<<row<<","<<"列"<<queue<<endl;
break;
}
}
/*输出函数*/
void out(char *t,int s)
{
cout<<"("<<t<<" , "<<s<<")"<<" "<<"行"<<row<<","<<"列"<<queue<<endl;
/*输入到文件里*/
outfile =fopen("finish.txt","ar");
fprintf(outfile,"(%s,%d)\n",t,s);
fclose(outfile);
}
/*查找关键字*/
int lookup(char *c)
{
int h=1;//标记是否为关键字,1为不是,0为是
for(int i=0;i<11;i++)//比较关键字
{
if((h=strcmp(c,key[i].name))==0)
break;
}
if(h)
return -1;
else
return i;
}
/*词法分析主函数*/
void scanner()
{
/*函数初始化*/
char ch;
int i=0,c;
while((ch=fgetc(in))!=EOF)//判断代码是否结束
{
if(isalpha(ch))//判断是否为字符开头
{
token[0]=ch;
ch=fgetc(in);
i=1;
while(isalnum(ch))//判断是否为字符或数字
{
token[i]=ch;
i++;
ch=fgetc(in);
}
token[i]='\0';
fseek(in,-1,1);//移动文件指针
c=lookup(token);//判断是否为关键字
if(c==-1)
{
if((k=strlen(token))<7)//判断是否超过标识符号的最大长度
out(token,ID);
else
report_error(1);
}
else
out(key[c].name,key[c].code);
}
else
{
if(isdigit(ch))//判断是否为数字开头
{
token[0]=ch;
ch=fgetc(in);
i=1;
while(isdigit(ch))//判断是否为数字
{
token[i]=ch;
i++;
ch=fgetc(in);
}
if(isalpha(ch))//判断是否为字符
{
token[i]=ch;
i++;
ch=fgetc(in);
while(isalnum(ch))
{
token[i]=ch;
i++;
ch=fgetc(in);
}
token[i]='\0';
fseek(in,-1,1);
report_error(5);
}
else
{
token[i]='\0';
fseek(in,-1,1);
b=atoi(token);
if((b<=65535)&&(b>=0))//判断是否超过数值最大表示范围
out(token,INT);
else
{
if(b>65535)
report_error(3);
}
}
}
else
{
switch(ch)
{
case'<':
ch=fgetc(in);
if(ch=='=')
out("<=",LE);
else
{
if(ch=='>')
out("<>",NE);
else
{
fseek(in,-1,1);
out("<",LT);
}
}
break;
case'=':
out("=",EQ);
break;
case'>':
ch=fgetc(in);
if(ch=='=')
out(">=",GE);
else
{
fseek(in,-1,1);
out(">",GT);
}
break;
case'+':
out("+",ADD);
break;
case'-':
out("-",MIN);
break;
case'*':
out("*",MUL);
break;
case'/': //对注释和除的区分
ch=fgetc(in);
if(ch=='*')
{
while(1)
{
ch=fgetc(in);
if(ch==EOF)
{
report_error(4);
break;
}
if(ch=='*')
{
ch1=ch;
ch=fgetc(in);
if(ch=='/')
{
ch=fgetc(in);
break;
}
}
}
}
else
{
out("/",DIV);
break;
}
case':':
ch=fgetc(in);
if(ch=='=')
out(":=",EVA);
break;
case'(':out("(",LP);
break;
case')':
out(")",RP);
break;
case';':
out(";",SEM);
break;
case' ':
queue++;break;
case'\t':
break;
case'\n':
row++;
break;
default:
report_error(2);
break;
}
}
}
}
}
void main()
{
char filename[30];
cout<<"输入您要编译的文件名:"<<endl;
cin>>filename;
if((in=fopen(filename,"rt"))==NULL)
{
printf("抱歉您要编译的文件 %s 有问题,请检查。\n",filename);
exit(1);
}
fopen("finish.txt","wr");
scanner();
cout<<"**********************************************"<<endl;
cout<<endl;
cout<<"错误个数:"<<error_count<<endl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -