思路
我是一个一个字符读入判断,所以要关注前后字符加以判断。比如%,如果它在引号里面,后面有d、s等,说明应该是格式字符。/这个字符后面还是/说明是注释,就要另外判断。
代码
#include<stdio.h>
char sign[100];
char num[100];
char* key[]={"int","main","void","char","include","return","printf","float","double","if","else"};
char block[]={',','<','>','/','=','*','-','%','(',')','&','{','}','[',']',';'};
FILE *fp;
int p=0,q=0,l=0;
int flag=-1;
int flag1=0;
int flag2=0;
int cmp(char sign[])
{
int i;
for(i=0;i<11;i++)
{
if(strcmp(sign,key[i])==0){
return 1;
}
}
return 0;
}
void cmp2(char ch)
{
switch(ch)
{
case ',':
case '(':
case ')':
case ';':printf("\n分隔符:%c\n",ch);break;
case '>':printf("%c\n",ch);break;
case '<':
case '.':printf("%c",ch);break;
case '{':printf("分隔符:%c\n",ch);break;
case '"':
case '}': printf("\n分隔符:%c",ch);break;
case '%': if(deliver(ch=fgetc(fp)))
{
fseek(fp,-2,1);
ch=fgetc(fp);
flag1=1;
printf("\n格式字符:%c",ch);
}
else
{
fseek(fp,-2,1);
ch=fgetc(fp);
printf("运算符:%c\n",ch);
}
break;
case '/':
ch=fgetc(fp);
if(ch=='/')
flag1=-1;
else if(ch==1)
flag1=-1;
else if(ch==0)
flag1=-1;
else if(ch=='*')
flag1=-1;
else
{
fseek(fp,-2,1);
ch=fgetc(fp);
if(ch!=10)
printf("运算符:%c\n",ch);
flag1=0;
}
break;
case '*':
ch=fgetc(fp);
if(ch!=47)
{
fseek(fp,-2,1);
ch=fgetc(fp);
printf("运算符:%c\n",ch);
}
else
{
flag1=0;
fseek(fp,-2,1);
ch=fgetc(fp);
if(ch!=42)
printf("运算符:%d\n",ch);
}
break;
case '=':
ch=fgetc(fp);
if(ch=='=')
{
//fseek(fp,-2,1);
//ch=fgetc(fp);
printf("判断符:%c%c\n",ch,ch);
}
else
{
fseek(fp,-2,1);
ch=fgetc(fp);
printf("运算符:%c\n",ch);
}
break;
case '+':
case '-':printf("运算符:%c\n",ch);break;
}
}
int deliver(ch)
{
if(ch=='d'||ch=='s'||ch=='c'||ch=='f')
return 1;
return 0;
}
int letter(ch)
{
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
return 1;
return 0;
}
int digit(ch)
{
if(ch>='0'&&ch<='9')
return 1;
return 0;
}
int scanner(char ch)
{
int i=0;
char c='c';
if(letter(ch))
{
sign[p++]=ch;
sign[p]='\0';
flag=0;
}
else if(digit(ch))
{
num[q++]=ch;
num[q]='\0';
flag=1;
}
else
{
if(flag==0){
if(cmp(sign)&&flag1==0)
{
printf("关键字:");
printf("%s\n",sign);
}
else if(flag1==0)
{
printf("标识符:");
printf("%s\n",sign);
}
else if(flag1!=-1)
printf("%s",sign);
flag=-1;
}
else if(flag==1&&flag1!=-1){
printf("常数:%s\n",num);flag=-1;
}
if(ch!=' '&&ch!='\n')
{
if(ch=='#')
{
if(ch=fgetc(fp)=='i')
printf("预处理命令:");
else
printf("宏定义:");
fseek(fp,-2,1);
ch=fgetc(fp);
flag1=1;
printf("%c",ch);
}
else
{
if(ch!='<'&&ch!='.')
flag1=0;
else
flag1=1;
cmp2(ch);
}
}
if(ch=='\n'||ch==' ')
{
flag1=0;
}
p=q=0;
sign[p]=num[q]='\0';
}
}
main()
{
char ch;
fp=fopen("text.dat","r");
ch=fgetc(fp);
while(ch!=EOF){
scanner(ch);
ch=fgetc(fp);
}
fclose(fp);
}
补充
其实这个东西还不完善,设计时考虑不周全,只具有基本功能。编译原理这门课学习确实有难度,但是每次学习都是突破。