⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 参照清华大学《编译原理》写的cmm语言词法分析程序
💻 C
字号:
/*编译和运行环境 * gcc4.3.2 * Archlinux-2.6.26 * 使用方法 * 命令行输入 gcc main.c && ./a.out Test.cmm*/#include "cmm.h"int main (int argc, char * argv[]) {	fname = argv[1];	fin = fopen(fname,"r");		/* 只读打开文件 */	if (fin) {		init();		while (getsym() != -1) {			printsym(6);		}	}	else{		printf("Can't open file! \n");	}	return 0;}void init() {	int i;	/* 初始化单字符的Token值 */	for (i = 0; i <= 255; i++) {		ssym[i] = nul;	}	ssym['+'] = plus;	ssym['-'] = minus;	ssym['*'] = times;	ssym['/'] = slash;	ssym['('] = lparen;	ssym[')'] = rparen;	ssym['['] = lbracket;	ssym[']'] = rbracket;	ssym['{'] = lbrace;	ssym['}'] = rbrace;	ssym['='] = assign;	ssym[','] = comma;	ssym['.'] = period;	ssym[';'] = semicolon;		/* 设置保留字的名字,按照字母顺序,便于折半查找 */	strcpy(&(word[0][0]), "const");	strcpy(&(word[1][0]), "else");	strcpy(&(word[2][0]), "if");	strcpy(&(word[3][0]), "int");	strcpy(&(word[4][0]), "read");	strcpy(&(word[5][0]), "real");	strcpy(&(word[6][0]), "while");	strcpy(&(word[7][0]), "write");		/* 设置保留字对应的symbol */	wsym[0] = constsym;	wsym[1] = elsesym;	wsym[2] = ifsym;	wsym[3] = intsym;	wsym[4] = readsym;	wsym[5] =  realsym;	wsym[6] =  whilesym;	wsym[7] =  writesym;}/* * 漏掉空格,读取一个字符 * 每次读一行,存入line缓冲区,line被getsym取空后再读一行 * 被函数getsym调用 */int getch() {	if ( cc == ll ) {		/* cc == ll说明当前行已经分析完成,或者开始分析第一行 */		if ( feof(fin) ) {	/* 文件结束 */			printf("program incomplete");			return -1;		}		ll = 0;		cc = 0;		ch = ' ';		/* 清空上一行余留的字符 */				memset(line,0,sizeof(line));		while (ch != 10) {	/* 碰到换行符停止循环 */			if (EOF == fscanf(fin,"%c",&ch)) {		/* 文件结束 *///				printf("文件结束了!此时ch=%d,ll=%d,cc=%d,linenum=%d\n",ch,ll,cc,linenum);				return -1;			}			line[ll] = ch;			ll++;		}		linenum++;		printline();//		printf("while循环结束后ch=%d,ll=%d,cc=%d,linenum=%d,line=%s\n",ch,ll,cc,linenum,line);	}	ch = line[cc];	cc++;//	printf("最后ch=%d,ll=%d,cc=%d,linenum=%d\n",ch,ll,cc,linenum);	return 0;}/* 词法分析,获取下一个Token */int getsym() {	int i, j, k;	while ( ch == ' ' || ch == 10 || ch == 9) {		/* 忽略空格,换行符和TAB */		getchdo;		/* 忽略后获取下个字符 */	}	if (ch >= 'a' && ch <= 'z') {			/* 检测标识符和关键字 */		k = 0;		do {			if (k < al) {				a[k] = ch;				k++;			}			getchdo;		}while (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9');		a[k] = 0;		strcpy(id,a);		strcpy(value,a);		i = 0;		j = norw - 1;		while (i <= j) {			k = (i+j)/2;			if (strcmp(id,word[k]) < 0) {		/* word[k] 表示 word[k][0]的地址 */				j = k-1;			}			else if (strcmp(id,word[k]) > 0) {				i = k+1;			}			else {				break;			}		}		if (i > j) {			sym = ident;		/* 设置当前符号为ident */		}		else {			sym = wsym[k];		/* 设置当前符号为某保留字的symbol */		}	}	else {		if (ch >= '0' && ch <= '9') {		/* 检测数字 */			k = 0;					/* 当前number的位数 */			num = 0;			sym = number;			do {					/* 继续检查后面的数字 */				if (ch == '.') {	/* 处理小数部分 */					sym = real;					realvalue = num;					e = 0.1;					k++;					getchdo;					while (ch >= '0' && ch <= '9') {						int ich = ch-'0';						realvalue += e*ich;						e*=0.1;						getchdo;					}				}				else {			/* 处理整数部分 */					num=10*num+ch-'0';					k++;					getchdo;				}			} while(ch >= '0' && ch <= '9' || ch == '.');			k--;			if( k > nmax){				printf("number too long!\n");				exit(0);			}		}		else {			if (ch == '=') {		/* 检测赋值符号和等于号 */				getchdo;				if (ch == '=') {					sym = eql;					getchdo;				}				else {					sym = assign;				}			}			else {				if (ch == '<') {	/* 检测小于号和小于等于号*/					getchdo;					if (ch == '=') {						sym = leq;						getchdo;					}					else {						sym = lss;					}				}				else {					if (ch == '>') {	/* 检测大于号和大于等于号*/						getchdo;						if (ch == '=') {							sym = geq;							getchdo;						}						else {							sym = gtr;						}					}					else {						if (ch == '!') {		/* 检测不等号 */							getchdo;							if (ch == '=') {								sym = neq;								getchdo;							}							else {								sym = ssym['!'];							}						}						else {		/* 当前符号不满足上述条件时,全部按照单字符号处理 */							sym = ssym[ch];							getchdo;						}					}				}			}		}	}	return 0;	}/* 打印当前Token的值 */void printsym (int offset) {	int i;	if (sym != 0) {		for (i = 0; i< offset; i++) {			printf(" ");		}		switch (sym) {			case ident : 				printf("identifier : %s\n",value);break;			case number : 				printf("number : %d\n",num);break;			case real : 				printf("real : %f\n",realvalue);break;			case plus : 				printf("plus : +\n");break;			case minus : 				printf("minus : -\n");break;			case times : 				printf("times : *\n");break;			case slash : 				printf("slash : /\n");break;			case eql : 				printf("equal : ==\n");break;			case neq : 				printf("not equal : !=\n");break;			case lss : 				printf("less than : <\n");break;			case leq : 				printf("less equal : <=\n");break;			case gtr : 				printf("greater than : >=\n");break;			case geq : 				printf("greater equal : >=\n");break;			case lparen : 				printf("lparen : (\n");break;			case assign : 				printf("assign : =\n");break;			case rparen : 				printf("rparen : )\n");break;			case lbracket : 				printf("lbracket : [\n");break;			case rbracket : 				printf("rbracket : ]\n");break;			case lbrace : 				printf("lbrace : {\n");break;			case rbrace : 				printf("rbrace : }\n");break;			case comma : 				printf("comma : ,\n");break;			case semicolon : 				printf("semicolon : ;\n");break;			case period : 				printf("period : .\n");break;			case constsym : 				printf("keyword : const\n");break;			case elsesym : 				printf("keyword : else\n");break;			case ifsym : 				printf("keyword : if\n");break;			case intsym : 				printf("keyword : int\n");break;			case readsym : 				printf("keyword : read\n");break;			case realsym : 				printf("keyword : real\n");break;			case whilesym : 				printf("keyword : while\n");break;			case writesym : 				printf("keyword : write\n");break;			}	}}/* 打印当前行 */void printline () {	int i;	printf(" %d: ",linenum);	for (i = 0; i < sizeof(line); i++) {		if (line[i] != 32 && line[i] != 10 && line[i] != 9) {			break;		}	}	for (i;i < sizeof(line) && line[i] != '\n'; i++) {		printf("%c",line[i]);	}	printf("\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -