关于词法分析器的一个小结

思路

我是一个一个字符读入判断,所以要关注前后字符加以判断。比如%,如果它在引号里面,后面有d、s等,说明应该是格式字符。/这个字符后面还是/说明是注释,就要另外判断。

代码

#include<stdio.h>


char sign[100];
char num[100];
char* key[]={"int","main","void","char","include","return","printf","float","double","if","else"};
char block[]={',','<','>','/','=','*','-','%','(',')','&','{','}','[',']',';'};

FILE *fp;


int p=0,q=0,l=0;
int flag=-1;
int flag1=0;
int flag2=0;

int cmp(char sign[])
{
	int i;
	for(i=0;i<11;i++)
	{
		if(strcmp(sign,key[i])==0){
			return 1;
		}
			
	}
	return 0;
}

void cmp2(char ch)
{
	switch(ch)
	{
		case ',':
		case '(':
		case ')':
		case ';':printf("\n分隔符:%c\n",ch);break;
		case '>':printf("%c\n",ch);break;
		case '<':
		case '.':printf("%c",ch);break;
		case '{':printf("分隔符:%c\n",ch);break;
		case '"': 
		case '}': printf("\n分隔符:%c",ch);break;
		case '%': if(deliver(ch=fgetc(fp)))
					{
						fseek(fp,-2,1);
						ch=fgetc(fp);
						flag1=1;
						printf("\n格式字符:%c",ch);
					}
					else
					{
						fseek(fp,-2,1);
						ch=fgetc(fp);
						printf("运算符:%c\n",ch);
					} 
					break;
		case '/':
				ch=fgetc(fp);
				if(ch=='/')
					flag1=-1;
				else if(ch==1)
					flag1=-1;
				else if(ch==0)
					flag1=-1;
				else if(ch=='*')
					flag1=-1;
				else
				{
					fseek(fp,-2,1);
					ch=fgetc(fp);
					if(ch!=10)
						printf("运算符:%c\n",ch);
					flag1=0;
				}
				break;
		case '*':
				ch=fgetc(fp);
				if(ch!=47)
				{
					fseek(fp,-2,1);
					ch=fgetc(fp);
					printf("运算符:%c\n",ch);
				}	
				else
				{
					flag1=0;
					fseek(fp,-2,1);
					ch=fgetc(fp);
					if(ch!=42)
					printf("运算符:%d\n",ch);
				}
					
				break;	
		case '=':
			ch=fgetc(fp);
			if(ch=='=')
			{
				//fseek(fp,-2,1);
				//ch=fgetc(fp); 
				printf("判断符:%c%c\n",ch,ch);
			}
			else
			{
				fseek(fp,-2,1);
				ch=fgetc(fp);
				printf("运算符:%c\n",ch);
			}
			break;
		case '+':
		case '-':printf("运算符:%c\n",ch);break; 
	}
}

int deliver(ch)
{
	if(ch=='d'||ch=='s'||ch=='c'||ch=='f')
		return 1;
	return 0;
}

int letter(ch)
{
	if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
		return 1;
	return 0;
}

int digit(ch)
{
	if(ch>='0'&&ch<='9')
		return 1;
	return 0;
}

int scanner(char ch)
{
	int i=0;
	char c='c';
	if(letter(ch))
	{
		sign[p++]=ch;
		sign[p]='\0';
		flag=0;
	}
	else if(digit(ch))
	{
		num[q++]=ch;
		num[q]='\0';
		flag=1;
	}
	else
	{
		if(flag==0){
			if(cmp(sign)&&flag1==0)
			{
				printf("关键字:");
				printf("%s\n",sign);
			}
			else if(flag1==0)
			{
				printf("标识符:");
				printf("%s\n",sign);
			}
			else if(flag1!=-1)
				printf("%s",sign);
			flag=-1;
		}	
		else if(flag==1&&flag1!=-1){
			printf("常数:%s\n",num);flag=-1;
		}
		if(ch!=' '&&ch!='\n')
		{
			if(ch=='#')
			{
				if(ch=fgetc(fp)=='i')
					printf("预处理命令:");
				else
					printf("宏定义:");
				fseek(fp,-2,1);
				ch=fgetc(fp);
				flag1=1;
				printf("%c",ch);
			}
			else
			{
				if(ch!='<'&&ch!='.')
					flag1=0;	
				else
					flag1=1;
				cmp2(ch);
			}	
		}
		if(ch=='\n'||ch==' ')
		{
			flag1=0;
		} 
		p=q=0;
		sign[p]=num[q]='\0';
	}
	
}

main()
{
	char ch;
	
	fp=fopen("text.dat","r");
	ch=fgetc(fp);
	while(ch!=EOF){
		scanner(ch);
		ch=fgetc(fp);
	}
	
	fclose(fp);
 } 

补充

其实这个东西还不完善,设计时考虑不周全,只具有基本功能。编译原理这门课学习确实有难度,但是每次学习都是突破。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值