词法分析程序(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<string.h>
#include<stdlib.h>
char compare[10];//分开进行比较
char ch;
/*char rwtab[6]={"begin","if","then","while","do","end"};*/
char r1[]={"begin"};
char r2[]={"if"};
char r3[]={"then"};
char r4[]={"while"};
char r5[]={"do"};
char r6[]={"end"};
char All[10000];//输入的所有值
int syn,row;//syn是种别码
int n,m,p,num,j;
static int i = 0;
void scaner();
int main()
{
row = 0 ;
p = 0 ;
printf("请输入需要识别的字段:(以$结尾)\n");
do
{
scanf("%c",&ch);
All[p]=ch;
p++;
}//输入值到数组A【】中,以$结束
while(ch!='$');
do
{
scaner();//进入函数进行判定
switch(syn)
{
case 7: printf("(%d,%d)\n",syn,num); break;//如果是7,那么就是数字
case 0: printf("(%d,%c)\n",syn,compare[0]);break;//如果是0,那么是$ 结束
case -2: row=row++;break;
default: printf("(%d,%s)\n",syn,compare);break;//否则,就是变量名、关键词
}
}
while (syn!=29);
}
void scaner()
{
/*共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else*/
for(n=0;n<7;n++)
compare[n]=0;//每次循环完就清零
ch=All[i];
while(ch==' '||ch=='\n')//如果字符是空格或者回车,跳过
{
i++;
ch=All[i];
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是标示符或者变量名
{
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
//找到一个变量名或者关键字,直到遇到空格为止
{
compare[m]=ch;m++;
i++;ch=All[i];
}
compare[m]='\0';
//将识别出来的字符和已定义的标示符作比较, //因为定义的begin为1,if为2......
if(strcmp(compare,r1)==0){syn=1;}
else if(strcmp(compare,r2)==0){syn=2; }
else if(strcmp(compare,r3)==0){syn=3;}
else if(strcmp(compare,r4)==0){syn=4;}
else if(strcmp(compare,r5)==0){syn=5;}
else if(strcmp(compare,r6)==0){syn=6;}
else{syn=100;} //变量名
}
else if((ch>='0'&&ch<='9')) //数字
{
num=0;
while((ch>='0'&&ch<='9'))
{
num=num*10+ch-'0';//显示其数字sum
i++;
ch=All[i];
}
syn=7;//数字是7
}
else switch(ch) //其他字符
{
case'<':m=0;compare[m]=ch;m++;
i++;ch=All[i];
if(ch=='=')//<=为21
{
syn=21;
compare[m]=ch;m++;i++;
}
else
{
syn=20;//<为20
}
break;
case'>':m=0;compare[m]=ch;m++;
i++;ch=All[i];
if(ch=='=')
{
syn=24;//>=为24
compare[m]=ch;m++;i++;
}
else
{
syn=23;//>为23
}
break;
case':':m=0;compare[m]=ch;m++;
i++;ch=All[i];
if(ch=='=')
{
syn=18;//:=为 18
compare[m]=ch;m++;i++;
}
else
{
syn=17;//:为17
}
break;
case'"':syn=10;compare[0]=ch;i++;break;
case',':syn=11;compare[0]=ch;i++;break;
case'.':syn=12;compare[0]=ch;i++;break;
case'+':syn=13;compare[0]=ch;i++;break;
case'-':syn=14;compare[0]=ch;i++;break;
case'*':syn=15;compare[0]=ch;i++;break;
case'/':syn=16;compare[0]=ch;i++;break;
case'=':syn=25;compare[0]=ch;i++;break;
case';':syn=26;compare[0]=ch;i++;break;
case'(':syn=27;compare[0]=ch;i++;break;
case')':syn=28;compare[0]=ch;i++;break;
case'#':syn=0;compare[0]=ch;i++;break;
case'$':syn=29;compare[0]=ch;i++;break;
case'{':syn=30;compare[0]=ch;i++;break;
case'}':syn=31;compare[0]=ch;i++;break;
case'\n':syn=-2;break;
default: syn=-1;break;
}
}
程序结果截图: