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 }

 

posted on 2016-04-20 20:51  (牛_牛).NET  阅读(1079)  评论(0编辑  收藏  举报

导航