词法分析程序(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 |
程序代码在下方贴出:
#include<stdio.h> #include<stdlib.h> #include<string.h> char prog[800],dc[8]; char ch; int syn,p,m=0; int n,sum=0; char *blword[6]={"begin","if","then","while","do","end"}; /*主函数*/ int main(void){ p=0; printf("$$################################$$ "); printf("$ 请输入需要翻译的程序段 $ "); printf("$$################################$$ "); /*逐个字符读入到'#'停止*/ do{ ch=getchar(); prog[p++]=ch; }while(ch!='#'); p=0; /*逐个字符判断其单词符号种别码*/ do{ for(n=0;n<8;n++){ dc[n]=NULL; } ch=prog[p++]; while(ch==' '){ ch=prog[p]; p++; } /*标识符*/ if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ m=0; while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ dc[m++]=ch; ch=prog[p++]; } p--; syn=10; /*保留字*/ for(n=0;n<6;n++){ if(strcmp(dc,blword[n])==0){ syn=n+1; break; } } } /*数字*/ else if((ch>='0'&&ch<='9')){ sum=0; while((ch>='0'&&ch<='9')){ sum=sum*10+ch-'0'; ch=prog[p++]; } p--; syn=11; } /*字符*/ else{ switch(ch){ case '<':m=0; dc[m++]=ch; ch=prog[p++]; if(ch=='>'){ syn=22; dc[m++]=ch; } else if(ch=='='){ syn=21; dc[m++]=ch; } else{ syn=20; p--; } break; case '>':m=0; dc[m++]=ch; ch=prog[p++]; if(ch=='='){ syn=24; dc[m++]=ch; } else{ syn=23; p--; } break; case ':':m=0; dc[m++]=ch; ch=prog[p++]; if(ch=='='){ syn=18; dc[m++]=ch; } else{ syn=17; p--; } break; case '+':syn=13;dc[0]=ch;break; case '-':syn=14;dc[0]=ch;break; case '*':syn=15;dc[0]=ch;break; case '/':syn=16;dc[0]=ch;break; case '=':syn=25;dc[0]=ch;break; case ';':syn=26;dc[0]=ch;break; case '(':syn=27;dc[0]=ch;break; case ')':syn=28;dc[0]=ch;break; case '#':syn=0;dc[0]=ch;break; case ' ':syn=-2;dc[0]=ch;break; } } switch(syn){ case 11:printf("## (%d,%d) ## ",syn,sum);break; default:printf("## (%d,%s) ## ",syn,dc);break; } }while(syn!=0); }
实测效果如图: