今天编译上完了第三章。所以照着书上第三章词法分析程序的框架,花了两个小时,实现了种个函数的具体代码,加调试。没有写什么注释,相关函数的说明在书上。调试的过程留在程序上在。
在工程目录下的input.txt是词法分析的输入文件,执行完程序后,会在工程目录下生成output.txt文件是词法分析的结果。
程序只能识别一部份的字符。出错处里也写得很简单,全局变量也太多。
下面是源代码,供以后复习之用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define KEY_WORLD_COUNT 7
char ch;
char token[30];
FILE * pRead = fopen("input.txt","r");
FILE * pWrite= fopen("output.txt","w+");
void getch();
void getbc();
void concat();
bool letter(char);
bool digit(char);
int reserve();
void retract();
void return_(int,char *);
char * dtb(char *);
void error_();
char * key_world_table[]={
"int",
"if",
"else",
"while",
"do",
"break",
"continue"
};
void scaner()
{
memset(token,0,sizeof(token));
getch();
getbc();
if (letter(ch))
{
while (letter(ch) || digit(ch))
{
concat();
getch();
}
retract();
int kind=reserve();
return_(kind,token);
}
else if (digit(ch))
{
while (digit(ch))
{
concat();
getch();
}
retract();
return_(11,dtb(token));
}
else
{
switch(ch) {
case '(':
return_(24,"(");
break;
case ')':
return_(25,")");
break;
case '{':
return_(26,"{");
break;
case '}':
return_(27,"}");
break;
case '+' :
return_(13,"+");
break;
case '-':
return_(14,"-");
break;
case '*':
return_(15,"*");
break;
case '/':
return_(16,"/");
break;
case '<':
getch();
if (ch=='=')
return_(17,"<=");
else if (ch == '>')
return_(18,"<>");
else
{
retract();
return_(19,"<");
}
break;
case '=':
return_(28,"=");
break;
case ':':
getch();
if (ch == '=')
return_(22,NULL);
else
{
retract();
return_(23,NULL);
}
break;
case ';':
return_(23,";");
break;
default:
error_();
}
}
}
void main()
{
while(!feof(pRead))
{
scaner();
}
//debug getch(),getbc()
// getch();
// printf("%c\n",ch);
// getch();
// getbc();
// printf("%c\n",ch);
//debug concat()
// strcpy(token,"feng");
// printf("%s\n",token);
// getch();
// concat();
// printf("%s\n",token);
//debug letter(),digit();
// printf("%d\n",letter('A'));
// printf("%d\n",digit('a'));
//debug reserve()
// strcpy(token,"while");
// printf("%d\n",reserve());
// strcpy(token,"whilee");
// printf("%d\n",reserve());
//debug retract()
// getch();
// printf("%c\n",ch);
// retract();
// getch();
// printf("%c\n",ch);
//debug return_
// return_(2,"feng");
// return_(3,"cheng");
//deubg dtb();
//出了一点小问题,当函数的返回值是字符指针时,
//下一个函数利用dtb()返回的指针,但dtb()几经执行完,
//内存被系统回收了,就回出现不是原值的情况
//在binNum[32]前面加上static使其内存分配在堆上就可以了
// printf("%s\n",dtb("127"));
// return_(3,dtb("25"));
//debug error_();
// getch();
// error_();
}
void getch()
{
if (!feof(pRead))
{
ch = fgetc(pRead);
}
}
void getbc()
{
while(ch==' ' || ch == '\t' || ch== '\n')
{
ch = fgetc(pRead);
}
}
void concat()
{
char *p = token;
while (*p!='\0')
{
p++;
}
*p=ch;
p++;
*p='\0';
}
bool letter(char ch)
{
if ((ch>='a' && ch <='z') || (ch >='A' && ch<='Z'))
return true;
else
return false;
}
bool digit(char ch)
{
if (ch>='0' && ch <='9')
return true;
else
return false;
}
int reserve()
{
for (int i=0;i<KEY_WORLD_COUNT;i++)
{
if (strcmp(key_world_table[i],token)==0)
{
return i+1;
}
}
return 10;
}
void retract()
{
fseek(pRead,-1,SEEK_CUR);
}
void return_(int n,char *buf)
{
char buf1[20];
sprintf(buf1,"(%d,%s)",n,buf);
fwrite(buf1,sizeof(char),strlen(buf1),pWrite);
}
char * dtb(char *decNum)
{
int n=atoi(decNum);
static char binNum[32]={0};
itoa(n,binNum,2);
return binNum;
}
void error_()
{
//调试时,总在文件读完后,出现 can't distinguish!
//因为当读到时文件结尾时,会返回一个-1
if(ch !=-1)
{
printf("%c can't distinguish!\n",ch);
exit(0);
}
}