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

📄 main.c

📁 参照清华大学《编译原理》写的cmm语言词法分析程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*编译和运行环境 * gcc4.3.2 * Archlinux-2.6.26 * 使用方法 * 命令行输入 gcc main.c && ./a.out Test.cmm */#include "cmm.h"int main (int argc, char * argv[]) {      bool nxtlev[symnum];      fname = argv[1];      fin = fopen(fname,"r");		/* 只读打开文件 */      if (fin) {            init();            getsymdo;            program(0);      }      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)) {		/* 文件结束 */                        return -1;                  }                  line[ll] = ch;                  ll++;            }            linenum++;            //          printline();      }      ch = line[cc];      cc++;      return 0;}/* 词法分析,获取下一个Token */int getsym() {      int i, j, k;      while ( ch == 0 || 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;	}/**  * @brief  打印当前Token的值 *  * @param offset 偏移量  *  * @returns void */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");}int program(int lev) {       bool nxtlev[symnum];       printspace(lev);      printf("Program-->\n");      while(sym == constsym) {            constdeclaration(lev+iden);      }      while (sym == intsym || sym == realsym) {            vardeclaration(lev+iden);      }      while (sym == ident || sym == ifsym || sym == whilesym || sym == readsym) {            statement(lev+iden);      }}int statement(int lev) {      printspace(lev);      switch (sym) {            case ident:                  printf("AssignStatement-->\n");                  printspace(lev+iden);                  printf("identifier:%s\n",id);                  getsymdo;                  while (sym == lbrace) {                        printspace(lev+iden);                        printf("lbracket:[\n");                        getsymdo;                        expression(lev+iden);                        if (sym == rbrace) {                              printspace(lev+iden);                              printf("rbracket:]\n");                              getsymdo;                        }                  }                  if (sym == assign) {                        printspace(lev+iden);                        printspace(lev+iden);                        printf("assign operator:=\n");                        getsymdo;                        expression(lev+iden);                        if (sym == semicolon) {                              printspace(lev+iden);                              printf("semicolon:;\n");                              getsymdo;                        }                  }                  break;

⌨️ 快捷键说明

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