词法分析程序的设计与实现

词法分析程序(Lexical Analyzer)要求:

- 从左至右扫描构成源程序的字符流

-  识别出有词法意义的单词(Lexemes

-  返回单词记录(单词类别,单词本身)

-  滤掉空格

-  跳过注释

-  发现词法错误

 

程序结构:

输入:字符流(什么输入方式,什么数据结构保存)

处理:

–遍历(什么遍历方式)

–词法规则

输出:单词流(什么输出形式)

–二元组

 

单词类别:

1.标识符(10)

2.无符号数(11)

3.保留字(一词一码)

4.运算符(一词一码)

5.界符(一词一码)

 

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<=

21

do

5

<>

22

end

6

>

23

l(l|d)*

10

>=

24

dd*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

  1 #include<stdio.h>
  2 #include<conio.h>
  3 #include<math.h>
  4 #include<string.h>
  5 #include<stdlib.h>
  6 
  7 int i, row = 0, line = 0;
  8 char test[1000];  //test文件中的字符 
  9 int number[100];    //常数表 
 10 char mark[100][5];   //标识符表
 11 
 12 //词法分析
 13 int wordanalysis()
 14 {
 15     //标识符和保留字
 16     if ((test[i] >= 'A'&&test[i] <= 'Z')||(test[i]>='a'&&test[i]<='z'))  
 17     {
 18         char word[10];
 19         //保留字表
 20         char pro[100][100] = { "PROGRAM", "BEGIN", "END", "VAR", "INTEGER", "WHILE",
 21                                  "IF", "THEN", "ELSE", "DO", "PROCEDURE" ,"char",
 22                                 "int","if","else","var" ,"return","break",
 23                                 "do","while","for","double","float","short"}; 
 24 
 25         int n = 0;
 26         word[n++] = test[i++];
 27         while ((test[i] >= 'A'&&test[i] <= 'Z') || (test[i] >= '0' && test[i] <= '9')||(test[i]>='a'&&test[i]<='z'))
 28         {
 29             word[n++] = test[i++];
 30         }
 31         word[n] = '\0';
 32         i--;
 33 
 34         //判断该标识符是否为保留字
 35         for (n = 0; n < 100; n++)
 36         {
 37             if (strcmp(word, pro[n]) == 0)
 38             {
 39                 printf(" %s\t 保留字\n", pro[n], n + 1);
 40                 return 3;
 41             }
 42         }
 43 
 44         //判断该标识符是否在标识符表中
 45         int m = 0;
 46         if (line != 0)
 47         {
 48             int q = 0;
 49             while (q<line)
 50             {
 51                 if (strcmp(word, mark[q++]) == 0)
 52                 {
 53                     printf(" %s\t 标识符\n", word, q);
 54                     return 3;
 55                 }
 56             }
 57 
 58         }
 59 
 60         //将该标识符保存到标识符表中
 61         strcpy(mark[line], word);
 62         
 63         printf(" %s\t 标识符\n", word, line + 1);
 64         line++;
 65         return 3;
 66 
 67     }
 68     //数字 
 69     else if (test[i] >= '0' && test[i] <= '9')  
 70     {
 71         char x[100];
 72         int n = 0;
 73         x[n++] = test[i++];
 74         
 75         while (test[i] >= '0' && test[i] <= '9')
 76         {
 77             x[n++] = test[i++];
 78         }
 79         x[n] = '\0';
 80         i--;
 81         int num = atoi(x); //将字符串转换成int型
 82         
 83         //判断该常数是否存在于常数表中
 84         if (row != 0)
 85         {   
 86             
 87             for(int y=0;y<row;y++)
 88             {
 89                 if(number[y]==num)
 90                 {
 91                     printf(" %d\t\n", num, y + 1);
 92                     return 3;
 93                 }
 94             }
 95         }
 96         
 97         //将该常数保存到标识符表中
 98         number[row]=num;
 99         
100 
101         int line = row;
102         printf(" %d\t\n", num, line + 1);
103         row++;
104 
105         return 3;
106     }
107     
108     //各种符号
109     else                      
110         switch (test[i])
111     {
112         case ' ':
113         case '\n':
114             return -1;
115         case '#': return 0;
116         case '=':printf(" =\t\n"); return 3;
117         case '<':
118             i++;
119             if (test[i] == '=')
120             {
121                 printf(" <= \t\n");
122                 return 3;
123             }
124             else if (test[i] == '>')
125             {
126                 printf(" <>\t\n");
127                 return 3;
128             }
129             else
130             {
131                 i--;
132                 printf(" <\t\n");
133                 return 3;
134             }
135         case '>':
136             i++;
137             if (test[i] == '=')
138             {
139                 printf(" >=\t\n");
140                 return 3;
141             }
142             else
143             {
144                 i--;
145                 printf(" >\t\n");
146                 return 3;
147             }
148         case '+': printf(" +\t\n"); return 3;
149         case '-': printf(" -\t\n"); return 3;
150         case '*': printf(" *\t\n"); return 3;
151         case '/': 
152             i++;
153             if(test[i]!='/'){
154                 i--;
155                 printf(" /\t\n"); return 3;
156             }
157 
158             else{
159 
160                 while(1){
161                     if(test[i++]=='\n')
162                         return -1;
163                 }
164                 printf(" //\t\n");return 3;
165 
166             }
167 
168         case ':': printf(" :\t\n"); return 3;
169         case ';': printf(" ;\t\n"); return 3;
170         case '(': printf(" (\t\n"); return 3;
171         case ')': printf(" )\t\n"); return 3;
172         case '{': printf(" {\t\n"); return 3;
173         case '}': printf(" }\t\n"); return 3;
174         case '[': printf(" [\t\n"); return 3;
175         case ']': printf(" ]\t\n"); return 3;
176         case '|': printf(" |\t\n"); return 3;
177         case '"': printf(" \"\t\n"); return 3;
178         case ',': printf(" ,\t\n"); return 3;
179         case '\'': printf(" '\t\n"); return 3;//单引号
180         case '&': 
181             i++;
182             if(test[i]!='&'){
183                 i--;
184                 printf(" &\t\n"); return 3;
185             }   
186             else{   
187                 printf(" &&\t\n");return 3;
188 
189             }
190         case '\\': printf(" \\\t\n"); return 3;
191     }
192 
193 }
194 
195 int main()
196 {
197 
198     int c = 0;
199     int m;
200     i = 0;
201     FILE *fp;
202     fp=fopen("D:\\test.txt","r");
203     if (fp == NULL)
204     {
205         printf("can't open file!\n");
206         exit(0);
207     }
208 
209     while (!feof(fp))
210     {
211         test[c++] = fgetc(fp);
212     }
213     test[c] = '#';
214     do
215     {
216         m = wordanalysis();
217 
218         switch (m)
219         {
220         case -1:i++; break;
221         case 0: i++; break;
222         case 3: i++; break;
223         }
224     } while (m != 0);
225 
226 
227     return 0;
228 }

运行结果图:

 

 

此代码是参考CSDN博客的。

posted @ 2019-10-11 20:06  小罗伯特唐尼  阅读(507)  评论(0)    收藏  举报