作业5 词法分析程序的设计与实现
词法分析程序(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 //引入头文件 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 //声明变量 6 char prog[800],dc[8]; //程序段 单词 7 char ch; //单词中的字符 8 int syn,p,m=0; //单词符号种别码 指针p 9 int n,sum=0; //整数sum 10 char *word[6]={"begin","if","then","while","do","end"}; //保留字 11 //主函数 12 int main(void){ 13 //指针从0开始 14 p=0; 15 printf("请输入源程序段:"); 16 //逐个字符读入,放入字符数组prog中,直到'#'停止 17 do{ 18 ch=getchar(); 19 prog[p++]=ch; 20 }while(ch!='#'); 21 //指针从0开始 22 p=0; 23 //逐个字符判断其单词符号种别码 24 do{ 25 //初始化数组dc 26 for(n=0;n<8;n++){ 27 dc[n]=NULL; 28 } 29 ch=prog[p++]; 30 //遇到空格指针加1 31 while(ch==' '){ 32 ch=prog[p]; 33 p++; 34 } 35 //标识符 36 if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ 37 m=0; 38 while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ 39 dc[m++]=ch; 40 ch=prog[p++]; 41 } 42 p--; 43 syn=10; 44 //保留字 45 for(n=0;n<6;n++){ 46 if(strcmp(dc,word[n])==0){ 47 syn=n+1; 48 break; 49 } 50 } 51 } 52 //数字 53 else if((ch>='0'&&ch<='9')){ 54 sum=0; 55 while((ch>='0'&&ch<='9')){ 56 sum=sum*10+ch-'0'; 57 ch=prog[p++]; 58 } 59 p--; 60 syn=11; 61 } 62 else{ 63 switch(ch){ 64 case '<':m=0; 65 dc[m++]=ch; 66 ch=prog[p++]; 67 if(ch=='>'){ 68 syn=22; 69 dc[m++]=ch; 70 } 71 else if(ch=='='){ 72 syn=21; 73 dc[m++]=ch; 74 } 75 else{ 76 syn=20; 77 p--; 78 } 79 break; 80 case '>':m=0; 81 dc[m++]=ch; 82 ch=prog[p++]; 83 if(ch=='='){ 84 syn=24; 85 dc[m++]=ch; 86 } 87 else{ 88 syn=23; 89 p--; 90 } 91 break; 92 case ':':m=0; 93 dc[m++]=ch; 94 ch=prog[p++]; 95 if(ch=='='){ 96 syn=18; 97 dc[m++]=ch; 98 } 99 else{ 100 syn=17; 101 p--; 102 } 103 break; 104 case '*':syn=15;dc[0]=ch;break; 105 case '/':syn=16;dc[0]=ch;break; 106 case '+':syn=13;dc[0]=ch;break; 107 case '-':syn=14;dc[0]=ch;break; 108 case '=':syn=25;dc[0]=ch;break; 109 case ';':syn=26;dc[0]=ch;break; 110 case '(':syn=27;dc[0]=ch;break; 111 case ')':syn=28;dc[0]=ch;break; 112 case '#':syn=0;dc[0]=ch;break; 113 case '\n':syn=-2;dc[0]=ch;break; 114 } 115 } 116 switch(syn){ 117 case 11:printf("(%d,%d)\n",syn,sum);break; 118 default:printf("(%d,%s)\n",syn,dc);break; 119 } 120 }while(syn!=0); 121 }
测试截图如下: