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

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

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

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

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

- 滤掉空格

- 跳过注释

- 发现词法错误

程序结构:

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

处理:

–遍历(什么遍历方式)

–词法规则

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

–二元组

单词类别:

1.标识符(13)

2.无符号数(10)

3.保留字(一词一码)

4.运算符(11)

5.界符(5)

单词符号 种别码 单词符号 种别码
begin 0 * 15
call 1 / 16
const 2 = 17
do 3 # 18
end 4 < 19
if 5 <= 20
odd 6 > 21
procedure 7 >= 22
read 8 := 23
then 9 ( 24
var 10 ) 25
while 11 , 26
write 12 ; 27
+ 13 , 28
- 14 l(l|d)* 29
    dd* 30

测试代码:

1 int a=1;
2 int b=2;
3 if(a<b){
4         printf("1");
5     }
6     else{
7         printf("2");
8     }

运行代码如下:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #define reserve 13
  4 #define operator 11
  5 
  6 FILE* fiar;
  7 char ch;                //getch读取的字符
  8 char id[operator+1];
  9 int num;
 10 int sum, length;
 11 char line[81];
 12 char a[operator+1];           //读取的符号存在这里
 13 char word[reserve][operator];    //保留字13个
 14 FILE* fin;
 15 FILE* fout;
 16 char fname[operator];         //输入的文件名
 17 int err;
 18 
 19 #define getchdo         if(-1==getch()) return -1;
 20 
 21 void init() {
 22     strcpy(&(word[0][0]), "begin");
 23     strcpy(&(word[1][0]), "call");
 24     strcpy(&(word[2][0]), "const");
 25     strcpy(&(word[3][0]), "do");
 26     strcpy(&(word[4][0]), "end");
 27     strcpy(&(word[5][0]), "if");
 28     strcpy(&(word[6][0]), "odd");
 29     strcpy(&(word[7][0]), "procedure");
 30     strcpy(&(word[8][0]), "read");
 31     strcpy(&(word[9][0]), "then");
 32     strcpy(&(word[10][0]), "var");
 33     strcpy(&(word[11][0]), "while");
 34     strcpy(&(word[12][0]), "write");
 35 }
 36 
 37 int getch() {
 38     if(sum == length) {
 39         if(feof(fin)) {
 40             return -1;
 41         }
 42         length = 0;
 43         sum = 0;
 44         ch = ' ';
 45         while(ch != 10) {
 46             if(fscanf(fin, "%c", &ch) == EOF) {
 47                 line[length] = 0;
 48                 break;
 49             }
 50             line[length] = ch;
 51             length++;
 52         }
 53     }
 54     ch = line[sum];
 55     sum++;
 56     return 0;
 57 }
 58 
 59 int getsym() {
 60     int i, j, k;
 61     while(ch == ' ' || ch == 10 || ch == 9||ch== 13) {
 62         getchdo;
 63     }
 64     if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
 65         k = 0;
 66         do {
 67             if(k < operator) {
 68                 a[k] = ch;
 69                 k++;
 70             }
 71             getchdo;
 72         } while(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9');
 73         a[k] = '';
 74         strcpy(id, a);
 75         i = 0;
 76         j = reserve-1;
 77         do {
 78             k = (i+j)/2;
 79             if(strcmp(id, word[k]) <= 0)
 80                 j = k-1;
 81             if(strcmp(id, word[k]) >= 0)
 82                 i = k+1;
 83         } while(i <= j);
 84 
 85         if(i-1 > j) {
 86             printf("3.保 留 字 -- %s
", id);
 87         } else {
 88             printf("1.标 识 符 -- %s
", id);
 89         }
 90     } else {
 91         if(ch >= '0' && ch <= '9') {
 92             k = 0;
 93             num = 0;
 94             do {
 95                 num = num * 10 + ch - '0';
 96                 k++;
 97                 getchdo;
 98             } while(ch >= '0' && ch <= '9');
 99             k--;
100             printf("2.无符号数 -- %d
",num);
101         } else {
102             if(ch == '=') {
103                 printf("4.运 算 符 -- =
");
104                 getchdo;
105             } else if(ch == ':') {
106                 getchdo;
107                 if(ch == '=') {
108                     printf("4.运 算 符 -- :=
");
109                     getchdo;
110                 } else {
111                 }
112 
113             } else {
114                 if(ch == '<') {
115                     getchdo;
116                     if(ch == '=') {
117                         printf("4.运 算 符 -- <=
");
118                         getchdo;
119                     } else {
120                         printf("4.运 算 符 -- <
");
121                     }
122                 } else {
123                     if(ch == '>') {
124                         getchdo;
125                         if(ch == '=') {
126                             printf("4.运 算 符 -- >=
");
127                             getchdo;
128                         } else {
129                             printf("4.运 算 符 -- >
");
130                         }
131                     } else {
132                         if(ch=='+') {
133                             printf("4.运 算 符 -- +
");
134                             getchdo;
135                         } else if(ch=='-') {
136                             printf("4.运 算 符 -- -
");
137                             getchdo;
138                         } else if(ch=='*') {
139                             printf("4.运 算 符 -- *
");
140                             getchdo;
141                         } else if(ch=='/') {
142                             printf("4.运 算 符 -- /
");
143                             getchdo;
144                         } else if(ch=='#') {
145                             printf("4.运 算 符 -- #
");
146                             getchdo;
147                         } else if(ch=='(') {
148                             printf("5.界    符 -- (
");
149                             getchdo;
150                         } else if(ch==')') {
151                             printf("5.界    符 -- )
");
152                             getchdo;
153                         } else if(ch==',') {
154                             printf("5.界    符 -- ,
");
155                             getchdo;
156                         } else if(ch==';') {
157                             printf("5.界    符 -- ;
");
158                             getchdo;
159                         } else if(ch=='.') {
160                             printf("5.界    符 -- .
");
161                             getchdo;
162                         } else {
163                             getchdo;
164 
165                         }
166                     }
167                 }
168             }
169         }
170     }
171     return 0;
172 }
173 
174 int main() {
175     printf("文件名: ");
176     scanf("%s", fname);
177     fin = fopen(fname, "r");
178     if(fin) {
179         init();
180         printf("
结果如下:

");
181         err = 0;
182         sum = length = 0;
183         ch = ' ';
184         while(getsym() != -1) {
185         }
186     } else {
187         printf("文件不存在
");
188     }
189     printf("
");
190     return 0;
191 }
View Code

运行结果:

 

还未完全实现作业的全部要求。

 参考代码来自:https://blog.csdn.net/sinat_37341950/article/details/79565485

原文地址:https://www.cnblogs.com/linyanli/p/11656223.html