PL/0 詞法分析器

PL/0 詞法分析器緩存

 

 1 #include<stdio.h>
 2 #include <ctype.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 
 6 typedef enum SymEnum  7 {  8     Identifier=0, //標識符
 9     Const=1,  //常數
 10     Key=2,    //關鍵字
 11     Operator=3,   //運算符
 12     Delimiter=4   //界符
 13 } SymEnum;  14 
 15 char KeyWord[13][15];    //關鍵字
 16 
 17 void Init()  18 {  19     strcpy(&KeyWord[0][0],"begin");  20     strcpy(&KeyWord[1][0],"call");  21     strcpy(&KeyWord[2][0],"const");  22     strcpy(&KeyWord[3][0],"do");  23     strcpy(&KeyWord[4][0],"end");  24     strcpy(&KeyWord[5][0],"if");  25     strcpy(&KeyWord[6][0],"odd");  26     strcpy(&KeyWord[7][0],"procedure");  27     strcpy(&KeyWord[8][0],"read");  28     strcpy(&KeyWord[9][0],"then");  29     strcpy(&KeyWord[10][0],"var");  30     strcpy(&KeyWord[11][0],"while");  31     strcpy(&KeyWord[12][0],"write");  32 }  33 
 34 //判斷一個單詞是否爲關鍵字
 35 int IsKeyWord(char *word)  36 {  37     int i=0,j=12;  38     while(i<=j)  39  {  40         int k=(i+j)/2;  41         if(strcmp(word,KeyWord[k])<=0)  42             j=k-1;  43         if(strcmp(word,KeyWord[k])>=0)  44             i=k+1;  45  }  46     return i-1>j ? 1 : 0;  47 }  48 
 49 //判斷一個單詞是否爲界符
 50 int IsDelimiter(char word)  51 {  52     if(word==','||word==';'||word=='.'||word=='('||word==')')  53         return 1;  54     return 0;  55 }  56 
 57 //判斷一個單詞是否爲操做符
 58 int IsOperator(char *word)  59 {  60     if(word[0]=='+'||word[0]=='-'||word[0]=='*'||word[0]=='/'||word[0]=='<'||word[0]=='>'||strcmp(word,":=")==0||strcmp(word,">=")==0||strcmp(word,"<=")==0||word[0]=='#'||word[0]=='=')  61         return 1;  62     return 0;  63 }  64 
 65 //判斷一個單詞是不是常數
 66 int IsConst(char *word)  67 {  68     if(word[0]>='0'&&word[0]<='9')  69         return 1;  70     return 0;  71 }  72 
 73 //判斷連個字符是否屬於相同類型
 74 int IsSame(char f,char s)  75 {  76     int bf = (f>='0'&&f<='9'||f>='a'&&f<='z'||f>='A'&&f<='Z')?  1 : 0 ;  77     int bs = (s>='0'&&s<='9'||s>='a'&&s<='z'||s>='A'&&s<='Z')?  1 : 0 ;  78     return bf == bs;  79 }  80 
 81 //判斷 word 的類型
 82 SymEnum TypeOfWord(char *word)  83 {  84     if(IsKeyWord(word))  85         return Key;  86     if(IsConst(word))  87         return Const;  88     if(IsOperator(word))  89         return Operator;  90     return Identifier;  91 }  92 
 93 int GetSym()  94 {  95     FILE *fp,*fout;  96     if((fp=fopen("PL0.txt","r"))==NULL || (fout=fopen("source.txt","w+"))==NULL)  97  {  98         printf("Open Error!\n");  99         exit(0); 100  } 101     SymEnum SYM;    //存放每一個單詞的類別,用內部編碼形式表示;
102     char word[50];  //存儲單詞
103     word[0]='\0'; 104     int len=0;      //單詞長度
105     char ch; 106     while(fscanf(fp,"%c",&ch)!=EOF) 107  { 108         // ch 爲空格,回車符,製表符
109         if(ch==' '||ch=='\n'||ch=='\t') 110  { 111             // word 不爲空
112             if(len) 113  { 114                 //判斷單詞類型
115                 SYM=TypeOfWord(word); 116                 fprintf(fout,"%d %s\n",SYM,word); 117                 //清空緩存區
118                 len=0; 119                 word[len]='\0'; 120  } 121             // word 爲空,忽略 ch
122  } 123         else if(IsDelimiter(ch)) 124  { 125             //word 不爲空
126             if(len) 127  { 128                 //判斷單詞的類型
129                 SYM=TypeOfWord(word); 130                 fprintf(fout,"%d %s\n",SYM,word); 131                 // ch == delimiter
132                 SYM=Delimiter; 133                 fprintf(fout,"%d %c\n",SYM,ch); 134                 //清空緩存區
135                 len=0; 136                 word[len]='\0'; 137  } 138             else
139  { 140                 //word 爲空, ch 爲界符
141                 SYM=Delimiter; 142                 fprintf(fout,"%d %c\n",SYM,ch); 143                 //清空緩存區
144                 len=0; 145                 word[len]='\0'; 146  } 147  } 148         else
149  { 150             if(len>0) 151  { 152                 if(IsSame(word[len-1],ch)) 153  { 154                     //判斷 word 與 ch 是否同類型
155                     word[len++]=ch; 156                     word[len]='\0'; //字符串終結符
157  } 158                 else
159  { 160                     //判斷單詞類型
161                     SYM=TypeOfWord(word); 162                     fprintf(fout,"%d %s\n",SYM,word); 163                     //清空緩存區,並把 ch 放入緩存區
164                     len=0; 165                     word[len++]=ch; 166                     word[len]='\0'; //字符串終結符
167  } 168  } 169             else
170  { 171                 word[len++]=ch; 172                 word[len]='\0'; 173  } 174  } 175  } 176  fclose(fp); 177  fclose(fout); 178     return 0; 179 } 180 
181 void PrintToScream() 182 { 183     FILE *fp; 184     if((fp=fopen("source.txt","r+"))==NULL) 185  { 186         printf("Open File Error!\n"); 187         exit(0); 188  } 189     int id; 190     char word[50]; 191     printf("0-標識符 1-常數 2-關鍵字 3-操做符 4-界符\n"); 192     while(fscanf(fp,"%d %s",&id,word)!=EOF) 193  { 194         printf("(%d,%s)\n",id,word); 195  } 196  fclose(fp); 197 } 198 
199 int main() 200 { 201  Init(); 202  GetSym(); 203  PrintToScream(); 204     return 0; 205 }
相關文章
相關標籤/搜索