编译原理 在字符串中识别不同进制数字

 

 

input.txt 内容

#include <stdio.h>

int main() {
    int a = 123;
    char b = 077;
    unsigned long c = 0x1a;
    int d = 0b1111011;
    return 0;
}



#include <stdio.h>
#include <string.h>
#include <malloc.h>

FILE* fp, *fa2;
int lenth = 10000;
char* str = new char[200];				// 循环读取文件,分200字节读取
char** cmd = new char*[lenth];			// 词元存储
char** order = new char*[100];			// 保留字
char** find = new char*[lenth];			// 筛选到的保留字
int cnt = 0;							// 分割词元个数
int have = 0;									// 筛选到的总数

char num[1000][100];				// 数字存储区
int cntv2 = 0;							// 当前合规数字个数


int getoption(char* id) {
	int i, j, k;
	int norw = 12; // 9 不行 // 8个		// 总个数+1,j 对应是最后一个词组序号
//	char* id=new char[20];
	int sym;							// 翻译的指令
//	k=0;
	i = 0;
	j = norw - 1;
	do {
		k = (i + j) / 2;
		if (strcmp(id, order[k]) <= 0) {
			j = k - 1;
//			printf("字符小于列表\n");
//			printf("%s\n",id);
		}
		if (strcmp(id, order[k]) >= 0) {
			i = k + 1;
		}
//		if (strcmp(id, word[k]) == 0) {
//			break;
//		}
//		printf("%s\n",order[k]);
//		printf("%d\n",k);
	} while (i <= j);
	
//	printf("匹配字位置 %d\n", k);
	
	if (i - 1 > j) {
		sym = k; //保留字
		//printf("识别出保留字\n");
		return sym;
	} else {
//		sym=ident; //标识符
		//printf("识别出标识符\n");
//		sym = error;
		sym = -1;
		return sym;
	}
}

void init() {
	fp = fopen("input.txt", "r");
	fa2 = fopen("output.txt", "w");		// 发现命令中有文件输出,所以之前需要开启文件
	
	for ( int i = 0; i < 100; i++) {
		order[i] = new char[30];
	}
	
	strcpy(order[0], "begin");
	strcpy(order[1], "call");
	strcpy(order[2], "const");
	strcpy(order[3], "do");
	strcpy(order[4], "else");
	strcpy(order[5], "end");
	strcpy(order[5 + 1], "if");
	strcpy(order[6 + 1 ], "procedure");
	strcpy(order[7 + 1], "read");
	strcpy(order[8 + 1], "then");
	strcpy(order[9 + 1], "var");
	strcpy(order[10 + 1], "while");
	
	
	
	
	for (int i = 0; i < 100; i++) {
		cmd[i] = new char[200];
		find[i] = new char[200];
	}
}


void split() {
	
	char *p;
	int num = 0;
	
	
//	分割词语
	while (fgets(str, 200, fp) != NULL) {
		
		p = str;
		
		// 处理回车,有些回车读取会影响代码结果
		if (str[0] == '\n') {
			printf("发现回车\n");
			continue;
		} else if (str[strlen(str) - 1 ] == '\n') {
			str[strlen(str) - 1 ] = '\0';
		}
		
//		按空格分割字符
		while (*p != '\0') {
//			printf("%c\n",*p);
			if (*p == ' ' || *p == '\n') {
				cnt++;
				num = 0;
			} else {
				if (*p == '0') {
//					printf("发现0\n");
				}
				cmd[cnt][num] = *p;
//				cnt++;
				num++;
			}
			p++;
		}
		if (num != 0)
			cnt++;
		
	}
}

// 输出
void test() {
	for (int i = 0; i < cnt; i++) {
		printf("%s\n", cmd[i]);
	}
}

//void select() {
//	for (int i = 0; i<cnt; i++) {
//		if(getoption(cmd[i])!=-1){
//			strcpy(find[have],cmd[i]);
			fprintf(fa2,"true");
//			have++;
//		}else{
			fprintf(fa2,"false");
//		}
//	}
//}

void testv2() {
	for (int i = 0; i < have; i++) {
		printf("%s ", find[i]);
		fprintf(fa2, "%s", find[i]);
	}
	
}



int isnum(char* p) {
	if (*p >= '0' && *p <= '9') {
		return 1;
	}
	return 0;
}

int isnum0b(char* p) {
	if (*p == '0' || *p == '1') {
		return 1;
	}
	return 0;
}

int isnum0x(char* p) {
	if (isnum(p) || (*p >= 'a' && *p <= 'f')) {
		return 1;
	}
	return 0;
}


void checkv3(char* str) {
	
	char numv2[1340];				// 提取的字符,但有可能不是数字 例如'0x' 数字空
	int xflag = 0;				// 是否是十六进制状态
	int bflag = 0;				// 是否是二进制状态
	int tenflag = 0; 				// 是否是十进制状态
	int choose = 0;				// 选择二进制与十六进制
	int i = 0;					// 小存储区下一个字符要存入的位置
	int chopflag = 0;				// if else 语句中分割情况后合并而产生的控制标志
//	int find=0;					// 存储区是合法字符,判断存数据是否是字符
	int end = 0;					// 字符存储结束,判断是否存数据
	
	
	char* p = str;
	while (*p != '\0') {
//		printf("%c", *p);
		if (xflag == 0 && bflag == 0 && tenflag == 0) {
			if (choose == 1) {
				if (*p == 'b') {
					printf("发现二进制数字\n");
					numv2[i] = *p;
					i++;
					bflag = 1;
				} else if (*p == 'x') {
					printf("发现十六进制数字\n");
					numv2[i] = *p;
					i++;
					xflag = 1;
				} else if (isnum(p) && *p != '\0') {
					printf("发现十进制数字\n");
					numv2[i] = *p;
					i++;
					tenflag = 1;							// 01 开始
				} else if (*p == '0') {
//					printf("测试\n");
					choose = 1;
				} else {
					chopflag = 1;
				}
				choose = 0;
				
			} else if (*p == '0' ) {
				choose = 1;
				printf("发现0\n");
				numv2[i] = *p;
				i++;
			} else if (isnum(p)) {
				printf("发现十进制数字\n");
				numv2[i] = *p;
				i++;
				tenflag = 1;
			}else if(*p=='-'){
				printf("发现负数\n");
				numv2[i] = *p;
				i++;
			}
		} else {
			if (bflag == 1) {										// 按进制选择因为有不同数字 a 范围
				if (isnum0b(p)) {
					numv2[i] = *p;
					i++;
				} else {
					bflag = 0;
					chopflag = 1;
				}
			} else if (tenflag == 1) {
//			printf("%c", *p);
				if ( isnum(p)) {
					numv2[i] = *p;
					i++;
				} else {
					tenflag = 0;
					chopflag = 1;
				}
			} else if (xflag == 1) {
				if (isnum0x(p)) {
					numv2[i] = *p;
					i++;
				} else {
					xflag = 0;
					chopflag = 1;
				}
			}
		}
		
		if (chopflag == 1) {			// 退出循环,因为不是数字了
			
			end = 1;
			tenflag = 0;
			bflag = 0;
			xflag = 0;
			chopflag = 0;
		}
		
		if (end) {
			i--;
			
			if (numv2[i] == 'b' || numv2[i] == 'x') {			// 检测是合法字符
				
			} else {
//				printf("%s\n", numv2);
				
				numv2[i + 1] = '\0';
				printf("数字结束%s\n", numv2);
				strcpy(num[cntv2], numv2);
				cntv2++;
				end = 0;
				i = 0;
				numv2[0] = '\0';
			}
		}
		p++;
	}
}


void testv3() {
	for (int i = 0; i < cnt; i++) {
//		printf("%s\n",cmd[i]);
		checkv3(cmd[i]);
	}
}


int main() {
	
	init();
	
	split();
	
//	select();
	
//	test();
	
	testv3();
	
	
	for (int i = 0; i < cntv2; i++) {
		fprintf(fa2, "%s\n", num[i]);
	}
	
//	fprintf(fa2,"0");
	
//	testv2();
	
//	fprintf(fa2,"false");
	
	fclose(fa2);
	fclose(fp);
	return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值