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 阅读(1086) 评论(0) 编辑 收藏 举报