小词法分析器

今天编译上完了第三章。所以照着书上第三章词法分析程序的框架,花了两个小时,实现了种个函数的具体代码,加调试。没有写什么注释,相关函数的说明在书上。调试的过程留在程序上在。

在工程目录下的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);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值