#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<windows.h>
void Scaner();//词法分析扫描函数
int IsRetainLetters(char *ch);//判断是否为保留字
char * DecimalToBinary(char *buf);//十进制转二进制函数
char GetCh(FILE *fp);//读取文件中的字符,每次只读取一个字符
int main()
{
printf(" 编译正在进行....../n");
Scaner();
printf("执行已经完成!!请参看工程目录下的out.txt文件/n");
return 0;
}
void Scaner()//词法分析扫描函数
{
FILE *fpin;//用于操作输入文件
FILE *fpout;//用于操作输出文件
char ch = ' ';//用于存放字符
int i,k;
int digit;//数字变量
char temp[10];//用做中间变量存放字符
fpin=fopen("in.txt","rb");//以只读的形式打开该文件
fpout=fopen("out.txt","w+");//若文件不存在则系统创建该文件,否则重写打开的文件
if(fpin==NULL || fpout==NULL)
{
printf("文件不能打开或新建,请重新调试!/n");
exit (0);
}
while(1)
{
i=0;
int flag;
while(i++<6) temp[i]='/0'; //初始化temp数组
i=0;
if (ch ==' ' ) ch=GetCh(fpin);
if(ch==EOF)//文件结束
{
fclose(fpin);
fclose(fpout);
return ;
}
//while(ch==' ') ch=GetCh(fpin);
while(ch == ' ' || ch == 9 || ch == 10 || ch == 13 ) ch=GetCh(fpin);
// 如果 ch为空格,回车,制表符table时略去!
if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
{
k=0;
while(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >='0' && ch <= '9')
{//读取的是字母
temp[k++]=ch;
ch=GetCh(fpin);
}
flag=IsRetainLetters(temp);
if(flag>0||flag<6)//判断是否是保留字
{
fprintf(fpout,"(%s,%d)/n",temp,flag);
}
else //是标识符,用7表示
fprintf(fpout,"(%s,%i)/n",temp,7);//写入文件
while(i++<10) temp[i]='/0'; i=0;
}
else if(ch >= '0' && ch <= '9')
{//是数字
k=0;
while(ch >= '0' && ch <= '9'){
temp[k++]=ch;
ch=GetCh(fpin);
}
char *binary;
digit=atoi(temp);//将字符串转换为数字
binary=DecimalToBinary(temp);//将数字转换为二进制
fprintf(fpout,"(%d,%s)/n",digit,binary);
i=0;
while(i++<10) temp[i]='/0';
i=0;
if(ch==EOF)
{
fclose(fpin);
fclose(fpout);
return;
}
}
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch==':'||ch==':='||ch=='<'||ch=='<>'
||ch=='<='||ch=='>'||ch=='>='||ch=='='||ch==';'||ch=='('||ch==')'||ch=='#')
{//为其他字符
int result=0;
switch(ch)
{
case '+': result=13;break;
case '-': result=14;break;
case '*': result=15;break;
case '/': result=16;break;
case ':': result=17;break;
case ':=': result=18;break;
case '<': result=19;break;
case '<>': result=20;break;
case '<=': result=21;break;
case '>': result=22;break;
case '>=': result=23;break;
case '=': result=24;break;
case ';': result=25;break;
case '(': result=26;break;
case ')': result=27;break;
case '#': result=28;break;
default:
break;//不是定义的界符是为reuslt=0;
}
fprintf(fpout,"(%c,%i)/n",ch,result);
ch=GetCh(fpin);
continue;
}
else if(ch==EOF)
{
while(!feof(fpout))
putchar(fgetc(fpout));//将输出的信息打印到屏幕上
fclose(fpin);
fclose(fpout);
return ;
}//else continue;
else
{
MessageBox(NULL,"输入的整数或字母界符不在定义范围之内","Message",MB_RETRYCANCEL);
//The message box contains two push buttons: Retry and Cancel.
//If 第一个参数 is NULL, the message box has no owner window.
ch=GetCh(fpin);//读取下一字符;
continue;
}
}//while(1)
fclose(fpin);
fclose(fpout);
}
//判断是否为保留字
int IsRetainLetters(char *ch)
{
int flag=1;
int i=0;
char *keyword[6]={"begin","if","then","while","do","end"};
while(i<6)
{
if(strcmp(ch,keyword[i])==0)
{
break;
}
flag++;
i++;
}
return flag;
}
//读取文件中的字符
char GetCh(FILE *fp)
{
char ch;
if(!feof(fp))
ch=fgetc(fp);//从fp所指向的文件的当前位置每次读取一个字符
return ch;
}
//十进制转二进制函数
char * DecimalToBinary(char *buf)
{
int temp[20];
char *binary;
int value=0,i=0,j;
for(i=0;buf[i]!='/0';i++)
value=value*10+(buf[i]-48); /*先将字符转化为十进制数*/
if(value==0)
{
binary=(char *)malloc(2*sizeof(char));
binary[0]='0';
binary[1]='/0';
return(binary);
}
i=0;
while(value!=0)
{
temp[i++]=value%2;
value/=2;
}
temp[i]='/0';
binary=(char *)malloc((i+1)*sizeof(char));
for(j=0;j<=i-1;j++)
binary[j]=(char)(temp[i-j-1]+48);
binary[i]='/0';
return(binary);
}