| /*****************************C_minus词法分析器 1.0版 **********************************  作者:温铭*  Email: moonbingbing@gmail.com*  版权所有(C) 2005.11***************************************************************************************/#include<stdio.h>#include<ctype.h>#include<stdlib.h>#include<string.h>
//****************************************char * change(char *ps,char *pt);      //处理路径中的反斜杠问题。因为在字符串中要用\\表示\ int  searchkey(char *word,struct key tab[],int n);//二分法查找关键字int  searchsymbol(char c,struct symbol tab[],int n);void getword(int c,FILE * p);//****************************************//用到的结构数组:struct  key{          //关键字表    char*   word;    int     value;}keytab[] = {         "else",  0,         "if",    1,         "int",   2,         "return",3,         "void",  4,         "while", 5,};//****struct   symbol{        //符号表      char  c;      int   value;}symboltab[] = {        '(', 0,        ')', 1,        '*', 2,        '+', 3,        ',', 4,        '-', 5,        '/', 6,        ';', 7,        '<', 8,        '=', 9,        '>', 10,        '[', 11,        ']', 12,        '{', 13,        '}', 14,};//*****************************************
//用到的常量enum{MAX = 50,     NKEYS = sizeof keytab / sizeof keytab[0],     NSYMBOL = sizeof symboltab / sizeof symboltab[0]};//*****************************************
//用到的全局变量int flagnum = 0;  //用来防止出现10t这种情况被当作数字处理。这种情况程序报错int countnum = 0;int countid  = 0;int countfault = 0;int type[] = {0,1,2,3,4};            //词法分析中的类型  依次为 关键字,数字,id,符号char array[MAX];           //存放getword中的字符串
//*****************************************
main(){ int c; int flag;     //判断搜索函数是否成功返回    char s[MAX];       //数组s,t用来存放读取文件的路径 char t[2 * MAX]; char *ps = s; char *pt = t;    FILE * p = NULL;
    printf("input the path of the file\n"); scanf("%s",s);    p = fopen( change(ps,pt),"r" );     //打开文件    if( p == NULL ){                   //如果输入的文件路径不对或文件不存在        printf("open fail!\n");        exit(0);    }   printf("data \t (type,value)\n");    while( ( c = fgetc(p) ) != EOF ){  if ( isspace(c) )       // 如果是空白字符   continue;  else if ( isalpha(c) ){    getword(c,p);             flag = searchkey(array,keytab,NKEYS);    if ( flag >= 0 )                      //如果是关键字     printf("%s\t(%d,%d)\n",array,type[0],flag);    else{                                 //如果以字母开头,但不是关键字     printf("%s\t(%d,%d)\n",array,type[2],countid);                 countid ++;    }  }else if ( isdigit(c) ){         //如果是数字              flagnum = 0;        /*解决getword中的一个bug。如果一个数字之前有超过1个的字符串,如in 2。则后面所有的数字都不能被正确分析*/
     getword(c,p);     if ( flagnum == 0 )      printf("%s\t(%d,%d)\n",array,type[1],countnum);     else      printf("%s\t(%d,%d)\t illegal input \n",array,type[4],countfault);  }else if ( ispunct(c) ){        //如果是符号              flag = searchsymbol(c,symboltab,NSYMBOL);     if ( flag >= 0 )      printf("%c\t(%d,%d)\n",c,type[3],flag);     else{     printf("%c\t(%d,%d)\n",c,type[4],countfault);  //出错处理                 countfault ++;     }  }else{   printf("%c\t(%d,%d)\n",c,type[4],countfault);       //出错处理   countfault ++;  } } return 0;}
//*******************************************char * change(char *ps,char *pt)     /*处理反斜杠的问题*/{ char *p = pt; char c;
 while( (c = *pt++ = *ps++) != '\0' )  if( c == '\\' )   *pt = '\\'; return p;}
//******************************************int  searchkey(char *word,struct key tab[],int n){ int cond; int low,high,mid;
 low = 0; high = n -1; while ( low <= high ){  mid = (low +high) / 2;  if ( ( cond = strcmp(word,tab[mid].word) ) < 0 )   high = mid - 1;  else if ( cond > 0 )   low = mid + 1;  else    return mid; } return -1;}
//**********************************************int  searchsymbol(char c,struct symbol tab[],int n){     int low,high,mid;
    low = 0; high = n -1; while ( low <= high ){  mid = (low +high) / 2;  if ( c < tab[mid].c)   high = mid - 1;  else if(c > tab[mid].c)   low = mid + 1;  else    return mid; } return -1;}//*******************************************void getword(int c,FILE * p){ int i = 0; array[i] = c; while( (c = fgetc(p)) != ' ' && c != '\n'){  if ( isalpha(c) | ispunct(c) )             //如果数字中有字母或字符,则报错   flagnum = 1;                                 /*一个可能引起错误的地方。已经解决(在读入数字后,把flagnum置0,再进入getword)*/  array[++i] = c; } array[++i] = '\0';}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=526675
 
 |