C语言 编译原理实验一 预处理,词法分析器的设计

预处理代码:

#include<stdio.h>
#include<String.h>
int main()
{
 FILE *p;
 int  i=0,j=0;//
 char str[1000],str1[1000],c;
 if((p=fopen("C:\\Users\\Lenovo\\Desktop\\test1.txt","rt"))==NULL){
  printf("无法打开");
  return  0;
 }
 else{
  
  while((c=getc(p))!=EOF){
   str[i] = c; 
   i++;
  }
  fclose(p);
  str[i] = '\0';
  for(i=0;i<strlen(str);i++){
   if(str[i]=='/'&&str[i+1]=='/'){
    while(str[i++]!='\n'){}
    i--;
   }//单行注释
   else if(str[i]=='/'&&str[i+1]=='*'){
    while(!(str[i]=='*'&&str[i+1]=='/'))
	{
	i++;
	}
    i+=1;
   }//多行注释
   else if(str[i]==' '&&str[i+1]==' '){
    while(str[i]==' '){i++;}
    i--;
    if(str1[j-1]!=' ')
       str1[j++]=' ';
   }//多个空格,去除空格
   else if(str[i]=='\n') {
    if(str1[j-1]!=' ')
       str1[j++]=' ';}
   //换行处理,
   else if(str[i]==9){
    while(str[i]==9){
     i++;
    }
    if(str1[j-1]!=' ')
     str1[j++]=' ';
    i--;
   }//\处理
   else str1[j++] = str[i];//其他字符处理
  }
  str1[j] = '\0';
  if((p = fopen("C:\\Users\\Lenovo\\Desktop\\test2.txt","w"))==NULL){
   printf("can not find it!");
   return 0;
  }
  else{
   if(fputs(str1,p)!=0){
    printf("存储失败!");
   }
   else printf("存储成功!");
  }
  fclose(p);
 }
 return 0;
}

词法分析器的设计:

#include<stdio.h>
#include<String.h>
int transfer(int x) {
	int p=1,y=0,yushu;
	while(1)
	{
		yushu=x%2;
		x/=2;
		y+=yushu*p;
		p*=10;
		if(x<2)
		{
			y+=x*p;
			break;
		}
	}
	return y;
}
int main() {
	FILE *p;
	int  falg = 0,len,i=0,j=0;
	char *rwtab[27]= {"","main","if","then","while","do",
	                  "static","int","double","struct","break","else","long",
	                  "switch","case","typedef","char","return","const","float",
	                  "short","continue","for","void","sizeof","default","do"
	                 };
	char str[1000],str1[1000],c;
	int syn,num;
	int k;
	char token[200];

	if((p=fopen("C:\\Users\\Lenovo\\Desktop\\test2.txt","rt"))==NULL) {
		printf("无法打开");
		return  0;
	}
	//fgets(str,1000,p);
	while((c=getc(p))!=EOF) {
		str[i++] = c;
	}
	fclose(p);
	str[i] = '\0';
//printf("%s\n",str);
	for(i=0; str[i]!='\0';) {
		j = 0;
		num = -1;
		if((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')) {
			while((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')||(str[i]>='0'&&str[i]<='9')||str[i]=='_') {
				token[j++] = str[i++];
			}
			token[j] = '\0';
			for( k=1; k<27; k++) {
				if(strcmp(rwtab[k],token)==0)
					break;
			}
			if(k<25)
				syn = k;
			else if(k==25)
				syn = 39;
			else if(k==26)
				syn = 40;
			else syn = 25;
		}//关键字和标示符处理

		else if(str[i]>='0'&&str[i]<='9') {
			num = 0;
			while(str[i]>='0'&&str[i]<='9') { //当读到第一个为0~9的数字时接着读之后的数字
				num = num*10+str[i]-'0';
				token[j++] = str[i++];
			}
			if((str[i]>='a'&&str[i]<='z')||
			        (str[i]>='A'&&str[i]<='Z')){
				num=-1;
				syn=-3;
				while((str[i]>='a'&&str[i]<='z')||
				        (str[i]>='A'&&str[i]<='Z')||(str[i]>='0'&&str[i]<='9')) {
					token[j++] = str[i++];
				}
			} else syn = 26;
		}//数字在此处处理

		else {
			if(str[i]==':'&&str[i+1]=='=') {
				syn = 32;
				token[j++] = str[i];
				token[j++] = str[++i];
				i++;
			} else if(str[i]=='<'&&str[i+1]=='>') {
				syn = 34;
				token[j++] = str[i];
				token[j++] = str[++i];
				i++;
			} else if(str[i]=='<'&&str[i+1]=='=') {
				syn = 35;
				token[j++] = str[i];
				token[j++] = str[++i];
				i++;
			} else if(str[i]=='>'&&str[i+1]=='=') {
				syn = 36;
				token[j++] = str[i];
				token[j++] = str[++i];
				i++;
				} else if(str[i]=='+'&&str[i+1]=='+') {
				syn = 49;
				token[j++] = str[i];
				token[j++] = str[++i];
				i++;
					} else if(str[i]=='-'&&str[i+1]=='-') {
				syn = 50;
				token[j++] = str[i];
				token[j++] = str[++i];
				i++;
			} else if(str[i]==' ') {
				i++;
				syn = -2;
			}//空格处理
			else {
				switch(str[i]) {
					case '+':
						syn = 27;
						break;
					case '-':
						syn = 28;
						break;
					case '*':
						syn = 29;
						break;
					case '/':
						syn = 30;
						break;
					case ':':
						syn = 31;
						break;
					case '<':
						syn = 33;
						break;
					case '>':
						syn = 36;
						break;
					case ';':
						syn = 41;
						break;
					case ')':
						syn = 43;
						break;
					case '(':
						syn = 42;
						break;
					case '#':
						syn = 0;
						break;
					case '=':
						syn = 38;
						break;
					case '.':
					    syn = 44;
						break;
					case '{':
					    syn = 45;
					    break;
					case '}':
					    syn = 46;
					    break;
					case '%':
					    syn = 47;
					    break;
					case '"':
					    syn=48;
						break;
					case ',':
					    syn=51;
						break;				
					default:
						syn = -1;
						break;
				}
				token[j++] = str[i++];
			}
		}
		token[j] = '\0'; 
		if(num!=-1) {
			printf("<%d %d>\n",transfer(num),syn);
		} else if(syn!=-1&&syn !=-2 &&syn!=-3) {
			printf("<%s %d>\n",token,syn);
		} else if(syn==-1) {
			printf("%s error\n",token);
		} else if(syn == -3){
			printf("%s error ID\n",token);
		}
	}
	return 0; 
}

如有疑问,可以评论,私信


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值