/*程序全部在TC2.o下跳过的,在其它的编译器下可能调不过。这是因为有些非标准的函数,其它的编译器并没有*/
#include <stdio.h>
#include <string.h>
#include <conio.h> /*屏幕操作函数*/
#include <bios.h>
#define Num 256/*缓冲区大小,当分析Mb大小的文件时候,可以让缓冲区设置到大一些,可以缩短分析的时间,提高整体的效率*/
char q1[Num],temp1[Num],token[Num];
char *pp,*qq;/*两个缓冲区的指针 */
char ch;
int syn,p;
int tabflag=1,spaceflag=1,enterflag=1;/*预处理标识符 */
int count=0,flag2=1;/*count记录分析出的结果总数,flag2结束分析的标志,当为0时即由@出现时候分析结束*/
long ft=0;/*记录读到的文件位置 */
char *rwtab[]={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"};/*33个关键字*/
char *limit[]={"(",")","[","]","}","{","<",">","!","*","/",
"+","-","=","&","->",".","|","#","%","~",",",";","<<","<=",
">>",">=","!=","*=","/=","+=","++","-=","-","==","&&","||","^"};/*运算、限界符38*/
/*功能:清理缓冲区
para:q 缓冲区开始指针,n缓冲区大小 */
void cleanBuf(char *q,int n)
{
int i;
for(i=0;i<n;i++)
q[i]='\0';
}
/*帮助菜单界面1*/
void help1()
{
int i;
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
printf("-------Word symbols-------types of code-------Word symbols------types of code\n");
for(i=0;i<14;i++)
printf("||-------------%-8s|--------%2d|-----------------%2s-----------%2d|---------||\n",rwtab[i],i+1,limit[i],i+36);
/* for(i=0;i<6;i=i+2)
printf("||-------------%-8s|--------%2d|-----------------%2s-----------%2d|---------||\n",limit[i+32],i+68,limit[i+33],i+69);
*/
gotoxy(1,22);
printf("--------------------------------------------------------------------------------");
gotoxy(35,23);
printf("up Next");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(YELLOW);
textbackground(2);
gotoxy(5,5);
cprintf("A");
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
textcolor(RED);
gotoxy(69,5);
cprintf("H");
}
/*帮助菜单界面2*/
void help2()
{
int i;
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
printf("-------Word symbols-------types of code-------Word symbols------types of code\n");
for(i=14;i<28;i++)
printf("||-------------%-8s|--------%2d|-----------------%2s-----------%2d|---------||\n",rwtab[i],i+1,limit[i],i+36);
/* for(i=0;i<6;i=i+2)
printf("||-------------%-8s|--------%2d|-----------------%2s-----------%2d|---------||\n",limit[i+32],i+68,limit[i+33],i+69);
*/
gotoxy(1,22);
printf("--------------------------------------------------------------------------------");
gotoxy(35,23);
printf("up Next");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(YELLOW);
textbackground(2);
gotoxy(5,5);
cprintf("A");
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
textcolor(RED);
gotoxy(69,5);
cprintf("H");
}
/*帮助菜单界面3*/
void help3()
{
int i;
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
printf("-------Word symbols-------types of code-------Word symbols------types of code\n");
for(i=28;i<33;i++)
printf("||-------------%-8s|--------%2d|-----------------%2s-----------%2d|---------||\n",rwtab[i],i+1,limit[i],i+36);
printf("||-------------Identifier|------34|------------Digital-----------35|---------||\n");
for(i=0;i<6;i=i+2)
printf("||-------------%-8s|--------%2d|-----------------%2s-----------%2d|---------||\n",limit[i+32],i+68,limit[i+33],i+69);
gotoxy(1,22);
printf("--------------------------------------------------------------------------------");
gotoxy(35,23);
printf("up Next");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(YELLOW);
textbackground(2);
gotoxy(5,5);
cprintf("A");
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
textcolor(RED);
gotoxy(69,5);
cprintf("H");
}
/*主菜单界面*/
void menu()
{
textcolor(YELLOW);
textbackground(2);
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
gotoxy(5,5);
cprintf("A");
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
gotoxy(69,5);
cprintf("H");
}
/*输入文件地址界面(开始分析程序界面)*/
void Readmenu(char *fileAddress)
{
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
printf("Please input your address to open the file:\n");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(RED);
textbackground(2);
gotoxy(5,5);
cprintf("A");
textcolor(YELLOW);
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
gotoxy(69,5);
cprintf("H");
gotoxy(1,8);
scanf("%s",fileAddress);
}
/*词法分析器开始分析等待界面*/
void resultWait()
{
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
gotoxy(35,14);
textcolor(7);
cprintf("Please wait......\n");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(RED);
textbackground(2);
gotoxy(5,5);
cprintf("A");
textcolor(YELLOW);
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
gotoxy(69,5);
cprintf("H");
}
/*分析完成界面*/
void resultFinish()
{
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
gotoxy(30,14);
textcolor(7);
cprintf("Analysis has been completed\n");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(RED);
textbackground(2);
gotoxy(5,5);
cprintf("A");
textcolor(YELLOW);
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
gotoxy(69,5);
cprintf("H");
}
/*打开文件失败界面*/
void OpenError()
{
printf("--------------------------------------------------------------------------------\n");
printf(" C Lexical analyzer\n");
printf("--------------------------------------------------------------------------------");
printf(" 1.Analysis of the beginning || 2.Results || 3.Set up || 4.Quit || 5.Help\n");
printf("--------------------------------------------------------------------------------");
gotoxy(35,14);
textcolor(7);
cprintf("Failure to open files\n");
gotoxy(1,24);
printf("--------------------------------------------------------------------------------");
gotoxy(1,25);
textcolor(YELLOW);
cprintf(" Version 1.0 All Rights Reserved:KONG Email:bilplink@gmail.com");
textcolor(RED);
textbackground(2);
gotoxy(5,5);
cprintf("A");
textcolor(YELLOW);
gotoxy(34,5);
cprintf("R");
gotoxy(47,5);
cprintf("S");
gotoxy(59,5);
cprintf("Q");
gotoxy(69,5);
cprintf("H");
}
/*功能:分析字符 词法分析器核心 程序最终以@字符结束整个分析
para: q第一缓冲区开始指针的指针,n 缓冲区大小 ,p当前指针所在缓冲区位置,temp第二缓冲区开始指针的指针,fileAddress打开文件的地址*/
void scaner(char **q,int n,int *p,char **temp,char *fileAddress)
{
int i=0,j=0,m=0,h;
char *t;
for(i=0;i<Num;i++)
token[i]='\0';
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
while(ch==' ')
{
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
}
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='_')
{
while((ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='_')
{
token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
}
token[m++]='\0';
(*p)--;
syn=34;/*34为标示符
//1-33为c语言关键字 */
for(j=0;j<32;j++)
if(strcmp(token,rwtab[j])==0)
{
syn=j+1;
break;
}
}
else
if((ch>='0'&&ch<='9'))
{
while((ch>='0'&&ch<='9'))
{
token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
}
(*p)--;
syn=35;/*为数字 */
}
else
switch(ch)
{
case'<':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='<')
{
syn=59;
token[m++]=ch;
}
else
if(ch=='=')
{
syn=60;
token[m++]=ch;
}
else
{
syn=42;(*p)--;
}
break;
case'>':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='>')
{
syn=61;
token[m++]=ch;
}
else if(ch=='=')
{
syn=62;
token[m++]=ch;
}
else
{
syn=43;
(*p)--;
}
break;
case'!':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='=')
{
syn=63;
token[m++]=ch;
}
else
{
syn=44;
(*p)--;
}
break;
case'*':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='=')
{
syn=64;
token[m++]=ch;
}
else
{
syn=45;
(*p)--;
}
break;
case'/':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='=')
{
syn=65;
token[m++]=ch;
}
else
{
syn=46;
(*p)--;
}
break;
case'+':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='=')
{
syn=66;
token[m++]=ch;
}
else if(ch=='+')
{
syn=67;
token[m++]=ch;
}
else
{
syn=47;
(*p)--;
}
break;
case'-':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='=')
{
syn=68;
token[m++]=ch;
}
else if(ch=='-')
{
syn=69;
token[m++]=ch;
}
else if(ch=='>')
{
syn=51;
token[m++]=ch;
}
else
{
syn=48;
(*p)--;
}
break;
case'=':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='=')
{
syn=70;
token[m++]=ch;
}
else
{
syn=49;
(*p)--;
}
break;
case'|':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='|')
{
syn=72;
token[m++]=ch;
}
else
{
syn=53;
(*p)--;
}
break;
case'&':token[m++]=ch;
if(*p>=n)
{
t=*q;
*q=*temp;
*temp=t;
*p=0;
cleanBuf(*temp,Num);
h=readqramm(*temp,Num,fileAddress );
if(h==-1) {system("cls");OpenError();}
}
ch=(*q)[(*p)++];
if(ch=='*')
{
syn=71;
token[m++]=ch;
}
else
{
syn=50;
(*p)--;
}
break;
case'.':syn=52;token[0]=ch;break;
case'\'':syn=54;token[0]=ch;break;
case'%':syn=55;token[0]=ch;break;
case'~':syn=56;token[0]=ch;break;
case'^':syn=73;token[0]=ch;break;
case':':syn=74;token[0]=ch;break;
case',':syn=57;token[0]=ch;break;
case';':syn=58;token[0]=ch;break;
case'{':syn=41;token[0]=ch;break;
case'}':syn=40;token[0]=ch;break;
case'[':syn=39;token[0]=ch;break;
case']':syn=38;token[0]=ch;break;
case'(':syn=36;token[0]=ch;break;
case')':syn=37;token[0]=ch;break;
case'#':syn=59;token[0]=ch;break;
case'@':flag2=0;break;
default:syn=-1;token[0]=ch;break;
}
}
/*功能:从磁盘中读去程序内容
para:q 缓冲区指针,n缓冲区大小,fileAddress 读文件的地址(c:\2.txt)
return: 返回1 文件中还有可读字符 0文件没有可读字符 -1 打开文件失败 */
int readqramm(char *q,int n,char *fileAddress)
{
FILE *fp;
char ch;
int p=0;
if((fp=fopen(fileAddress,"r"))==NULL)
{
return -1;
}
fseek(fp,ft,0);
ch=fgetc(fp);
while(ch!=EOF&&n>p)
{
if(ch==' '&&spaceflag==1)
{
q[p++]=ch;
spaceflag=0;
}
if(ch=='\t'&&tabflag==1)
{
if(q[p-1]!=' ') q[p++]=' ';
tabflag=0;
}
if(ch!=' '&&ch!='\t'&&ch!='\r'&&ch!='\n')
{
q[p++]=ch;
spaceflag=1;
tabflag=1;
}
ch=fgetc(fp);
}
ft=ftell(fp)-1;
fclose(fp);
if(ch==EOF) return 0;
else return 1;
}
int main()
{
char fileAddress[Num];
char ch;
int flag1=1;
FILE *fp;
int jj=0,help_count=0,key;
pp=q1;
qq=temp1;
system("cls");
menu();
while(flag1)
{
key=bioskey(0);
switch(key)
{
case 7777:
case 7745:system("cls");
Readmenu(fileAddress);
flag2=1;
if(fileAddress!=NULL)
{
system("cls");
resultWait();
if(readqramm(qq,Num,fileAddress )==-1||readqramm(pp,Num,fileAddress )==-1) {system("cls");OpenError();}
else
do
{
scaner(&qq,Num,&p,&pp,fileAddress);
if(jj==0)
{
jj++;
if((fp=fopen("result.txt","w"))==NULL)
{
system("cls");OpenError();
}
}
else
{
jj++;
if((fp=fopen("result.txt","a"))==NULL)
{
system("cls");OpenError();
}
}
switch(syn)
{
case -1:fprintf(fp,"%d. (%d,%s) ",++count,syn,token);fclose(fp);continue;/*写入到result.txt文件中,这里最好使用缓冲区可以提高程序的效率,频繁打开文件写,效率低*/
default:fprintf(fp,"%d. (%d,%s) ",++count,syn,token);fclose(fp);continue;/*做法先让这些分析结果写到缓冲区中等缓冲满了,在一次写入到文件中,读取文件就使用了双缓冲效果很好*/
}
}while(flag2);
}
if(flag2==0)
{
system("cls");
resultFinish();
}
break;
case 4978:
case 4946:break;
case 8051:
case 8019:break;
case 4209:
case 4177:flag1=0;break;
case 9064:
case 9032:help_count=0;system("cls");help1();
while((key=bioskey(0))!=283)
{
switch(key)
{
case 20480:if(help_count==0) {system("cls");help2();help_count++;}
else if(help_count==1) {system("cls");help3();help_count++;}
break;
case 18432:if(help_count==2) {system("cls");help2();help_count--;}
else if(help_count==1) {system("cls");help1();help_count--;}
break;
}
}
system("cls");
menu();
break;
}
}
}