虽然只是个词法分析器,但是重拾C语言好难!好久没用过C了。放在这儿勉励自己做事一定要有始有终
/*Trans.c -main,Trans */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//char *name[]={"begin","1","end","2","integer","3","if","4","then","5","else","6","function","7","read","8","write","9"};
//char *sign[]={"=","<>","<=","<",">=",">","-","*",":=","(",")",";"};
int match_code=0;
char buffer1[256];
char buffer2[256];
char *infile;
char* outfile;
char* errfile;
char token[15];
int token_index=0;
char ch;
int buffer1Empty=1;
int buffer2Empty=1;
int EndofFile=0;
//int reserve_(int* code) //本来自己写了一个比较保留字段的函数,但是不知道什么原因工作不是很良好,鉴于时间很紧就没有用
//{
// int match=-1;
// int i=0;
// while(i!=18)
// {
// match=strcmp(name[i],token);
// i++;
// if(match==0)
// {
// *code=i;
// break;
// }
// }
// return match;
//}
//void write_dyd(int code,FILE* fp) //这个是针对上一个函数的写入文件流的函数,同样也放弃了
//{
// int blank=16-strlen(name[code]);
// while(blank!=0)
// {
// fputc(' ',fp);
// blank=blank-1;
// }
// fputs(name[code],fp);
// fputc(' ',fp);
// fputs(name[code+1],fp);
// fputc('/n',fp);
//}
void ReadIntoBuffer(char buffer[256],FILE* fp)
{
int i;
char c;
char tmp;
for(i=0;i<255;i++)
{
c=fgetc(fp);
switch(c)
{
case ' ':
tmp=c;
while(c==' ')
c=fgetc(fp);
if(c!=EOF)
{
if(c!='/t'&&c!=' ')
fseek(fp,-1L,1);
if(buffer[i-1]!=' ')
buffer[i]=tmp;
else
i=i-1;
}
else
buffer[i]=EOF;
break;
case '/t':
while(c=='/t')
c=fgetc(fp);
if(c!=EOF)
{
if(c!='/t'&&c!=' ') //如果非这些字符,就要把文件当前读取位置往前移
fseek(fp,-1L,1);
if(buffer[i-1]!=' ') //如果缓冲区的前一个字符不为空格,就要输入一个空格来分开token
buffer[i]=' ';
else
i=i-1; //因为这轮for循环缓冲区什么也没有修改,而缓冲区的游标又要被加1,所以这里要把i减1
}
else
buffer[i]=EOF; //其他情况就把文件结束符写到缓冲区里面去
break;
case EOF:
buffer[i]=EOF;
break;
default:
buffer[i]=c;
break;
}
}
}
int read_buffer(FILE* fp,int* index) //这个函数从两个缓冲区中的一个读出一个字符赋给全局变量ch,缓冲区空则调用ReadInotBuffer函数写入缓冲区
{
char* readfrom; //readfrom是我设的缓冲区数组的指针
if(buffer1Empty&&!buffer2Empty) //缓冲区空与否由两个变量buffer1Empty和buffer2Empty来测定
readfrom=buffer2;
else
{
if(buffer2Empty&&!buffer1Empty)
readfrom=buffer1;
else
{
if(buffer1Empty&&buffer2Empty)
{
readfrom=buffer1;
ReadIntoBuffer(readfrom,fp); //第一次读文件时默认填充缓冲区1
}
}
}
if(readfrom==buffer1)
buffer1Empty=0;
else
{
if(readfrom==buffer2)
buffer2Empty=0;
}
if(readfrom[*index]!=EOF&&*index<256)
{
ch=readfrom[*index]; //将ch赋值
*index=*index+1;
}
else
{
if(readfrom[*index]==EOF)
{
return 1; //若读到文件尾,则返回1,1在函数translate中被赋给了全局变量EndofFile,这个全局变量控制了整个translate的while循环
}
else
if(*index>255)
{
*index=0;
readfrom=buffer1Empty?buffer1:buffer2;
ReadIntoBuffer(readfrom,fp);
if(readfrom==buffer1)
{
buffer1Empty=0;
buffer2Empty=1;
}
else
{
if(readfrom==buffer2)
{
buffer1Empty=1;
buffer2Empty=0;
}
}
ch=readfrom[*index];
*index=*index+1;
}
}
return 0;
}
void translate(const char *infile,const char *outfile,const char *errfile) //词法分析器主要功能函数
{
FILE *ifp = fopen(infile,"r");
FILE *ofp = fopen(outfile,"a");
FILE *efp = fopen(errfile,"a");
int index=0; //index为读缓冲区的下标变量
int line_number=1;
while(ifp!=NULL&&!EndofFile)
{
printf("token now is %s|/n",token);
EndofFile=read_buffer(ifp,&index);
if(isdigit((int)ch)&&!EndofFile)
{
while(isdigit((int)ch)&&!EndofFile)
{
token[token_index]=ch;
token_index=token_index+1;
EndofFile=read_buffer(ifp,&index);
}
token[token_index]='/0';
token_index=0;
index=((index-1)==-1)?255:index-1; //每个缓冲区为256个字符,若回退下标的时候处在缓冲区头,则切换到上一次读的缓冲区尾
int blank=16-strlen(token);
while(blank!=0)
{
fputc(' ',ofp);
blank=blank-1;
}
fputs(token,ofp);
fputc(' ',ofp);
fputs("11/n",ofp);
continue;
}
if(isalpha((int)ch)&&!EndofFile)
{
while((isalpha((int)ch)||isdigit((int)ch))&&!EndofFile)
{
token[token_index]=ch;
token_index=token_index+1;
EndofFile=read_buffer(ifp,&index);
}
token[token_index]='/0';
token_index=0;
index=((index-1)==-1)?255:index-1;
if(!strcmp(token,"begin"))
{
fputs(" begin 1/n",ofp);
continue;
}
if(!strcmp(token,"end"))
{
fputs(" end 2/n",ofp);
continue;
}
if(!strcmp(token,"integer"))
{
fputs(" integer 3/n",ofp);
continue;
}
if(!strcmp(token,"if"))
{
fputs(" if 4/n",ofp);
continue;
}
if(!strcmp(token,"then"))
{
fputs(" then 5/n",ofp);
continue;
}
if(!strcmp(token,"else"))
{
fputs(" else 6/n",ofp);
continue;
}
if(!strcmp(token,"function"))
{
fputs(" function 7/n",ofp);
continue;
}
if(!strcmp(token,"read"))
{
fputs(" read 8/n",ofp);
continue;
}
if(!strcmp(token,"write"))
{
fputs(" write 9/n",ofp);
continue;
}
else
{
int blank=16-strlen(token);
while(blank!=0)
{
fputc(' ',ofp);
blank=blank-1;
}
fputs(token,ofp);
fputc(' ',ofp);
fputs("10/n",ofp);
}
continue;
}
if((ch=='=')&&!EndofFile)
{
fputs(" = 12/n",ofp);
continue;
}
if((ch=='<')&&!EndofFile)
{
EndofFile=read_buffer(ifp,&index);
if((ch=='=')&&!EndofFile)
{
fputs(" <= 14/n",ofp);
continue;
}
else
{
if((ch=='>')&&!EndofFile)
{
fputs(" <> 13/n",ofp);
continue;
}
else
{
if(!EndofFile)
{
fputs(" < 15/n",ofp);
index=((index-1)==-1)?255:index-1;
continue;
}
else
{
fputs(" EOF 25/n",ofp);
break;
}
}
}
}
if((ch=='>')&&!EndofFile)
{
EndofFile=read_buffer(ifp,&index);
if((ch=='=')&&!EndofFile)
{
fputs(" >= 16/n",ofp);
continue;
}
else
{
if(!EndofFile)
{
index=((index-1)==-1)?255:index-1;
fputs(" > 17/n",ofp);
continue;
}
else
{
fputs(" EOF 25/n",ofp);
break;
}
}
}
if((ch=='-')&&!EndofFile)
{
fputs(" - 18/n",ofp);
continue;
}
if((ch=='*')&&!EndofFile)
{
fputs(" * 19/n",ofp);
continue;
}
if((ch==':')&&!EndofFile)
{
EndofFile=read_buffer(ifp,&index);
if((ch=='=')&&!EndofFile)
{
fputs(" := 20/n",ofp);
continue;
}
else
{
if(!EndofFile)
{
index=((index-1)==-1)?255:index-1;
fprintf(efp,"%d ':' is not defined",line_number);
continue;
}
else
{
fputs(" EOF 25/n",ofp);
break;
}
}
}
if((ch=='(')&&!EndofFile)
{
fputs(" ( 21/n",ofp);
continue;
}
if((ch==')')&&!EndofFile)
{
fputs(" ) 22/n",ofp);
continue;
}
if((ch==';')&&!EndofFile)
{
fputs(" ; 23/n",ofp);
continue;
}
if((ch=='/n')&&!EndofFile)
{
fputs(" EOLN 24/n",ofp);
line_number=line_number+1;
continue;
}
}
fputs(" EOF 25/n",ofp);
fclose(ifp);
fclose(ofp);
fclose(efp);
}
int main(int argc, char *argv[])
{
switch(argc) //处理命令行参数
{
case 1:
infile="input.txt";
outfile="output.txt";
errfile="error.txt";
break;
case 2:
infile = argv[1];
outfile="output.txt";
errfile="error.txt";
break;
case 3:
infile = argv[1];
outfile = argv[2];
errfile="error.txt";
break;
case 4:
infile = argv[1];
outfile = argv[2];
errfile = argv[3];
break;
default:
fprintf(stderr,"usage:Trans [Infile path] [outfile path] [error log path]/n");
exit(-1);
}
translate(infile,outfile,errfile);
system("PAUSE");
}