?? main.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 + -