实验一、词法分析实验
专业:商业软件工程2班 姓名:崔格畅 学号:201506110148
一、 实验目的
编制一个词法分析程序
二、 实验内容和要求
- 输入:源程序字符串;
- 输出:二元组(种别,单词本身);
- 待分析语言的词法规则。
三、 实验方法、步骤及结果测试
1. 源程序名:识别字符串.c
2. 原理分析及流程图
词法分析程序,运行后,提示用户输入字符串(遇到’#’退出输入),调用函数scanner(),scanner函数内部用了while嵌套while,while里再嵌套for对用户输入的字符数组元素进行分类,for里进行多分支判断,若为字母,存入辅助数组tempc[],调用函数recignition(),recignition()函数里对字符数组tempc[]判断,若为相应关键字,输出(种别码,本身),否则输出当前字母,退出函数recignition()。若为数字,用输出该字符-48的值。若不为上述字符,进入对符号的判断,若判断是定义的符号,则输出(种别码,本身),结束。
3. 主要程序段及其解释:
#include<stdio.h>
#include<string.h>
char tempc[100];
char tempf[100];
char tempn[100];
char ch[100];
char r1[] = {"begin"};
char r2[] = {"if"};
char r3[] = {"then"};
char r4[] = {"while"};
char r5[] = {"do"};
char r6[] = {"end"};
int c=0;
void scanner();
void Swit(int num);
void recignition();
void main()
{
int i=-1;
printf("请输入字符串(end of '#'):");
do{
i++;
scanf("%c",&ch[i]);
}while(ch[i]!='#');
scanner();
printf("(0,'#')");
}
void scanner()
{ int i=0,j=0,k=0,t,l=0,f=0,n=0,m=0,q=0;
char cf[100]="";
while(ch[i]!='#')
{
while (ch[i]!='#' && ch[i]!=' ' && ch[i]!='\n' && ch[i]!=' ')//在用户输入的字符串中找到分界符,用i记录界符前元素个数
i++;
for(;j<i;j++)//把字符串数组中的元素分类,字母,数字,符号
{
if((ch[j]>='a'&&ch[j]<='z') || (ch[j]>='A'&&ch[j]<='Z'))//判断字母
{
tempc[c]=ch[j];
c++;
if(!((ch[j+1]>='a'&&ch[j+1]<='z') || (ch[j+1]>='A'&&ch[j+1]<='Z')))
recignition();
}
else if(ch[j]>='0'&& ch[j]<='9')//判断数字并输出
{
tempn[n]=ch[j];
n++;
for(;q<n;q++)
printf("(11,'%d')",tempn[q]-48);
if(!(ch[j+1]>='0' && ch[j+1]<='9'))
printf("\n");
}
else//判断符号
{
tempf[f]=ch[j];
f++;
for(;l<f;l++)
{
switch(tempf[l])
{
case '+': m=13;break;
case '-': m=14;break;
case '*': m=15;break;
case '/': m=16;break;
case ':':
if(tempf[l+1]=='=')
{
m=18;
l++;
}
else m=17;
break;
case '<':
if(tempf[l+1]=='=')
{
m=21;
l++;
}
else if (tempf[l+1]=='>')
{
m=22;
l++;
}
else m=20;
break;
case '>':
if(tempf[l+1]=='=')
{
m=24;
l++;
}
else m=23;
break;
case '=': m=25;break;
case ';': m=26;break;
case '(': m=27;break;
case ')': m=28;break;
default :printf("%c\n",tempf[l]);
break;
}
if(m>0)
Swit(m);
m=0;
}
}
}
l++;
if(ch[i]!='#')
i++;
}
}
/*函数名:Swit
形参:num
函数功能:引用形参num,与字符串中对应的种别码进行配对,
输出种别码和字符本身。
返回值:无*/
void Swit(int num)
{
switch(num)
{
case 1:printf("(1,begin)\n");break;
case 2:printf("(2,if)\n");break;
case 3:printf("(3,then)\n");break;
case 4:printf("(4,while)\n");break;
case 5:printf("(5,do)\n");break;
case 6:printf("(6,end)\n");break;
case 13:printf("(13,'+')\n");break;
case 14:printf("(14,'-')\n");break;
case 15:printf("(15,'*')\n");break;
case 16:printf("(16,'/')\n");break;
case 17:printf("(17,':')\n");break;
case 18:printf("(18,':=')\n");break;
case 20:printf("(20,'<')\n");break;
case 21:printf("(21,'<=')\n");break;
case 22:printf("(22,'<>')\n");break;
case 23:printf("(23,'>')\n");break;
case 24:printf("(24,'>=')\n");break;
case 25:printf("(25,'=')\n");break;
case 26:printf("(26,';')\n");break;
case 27:printf("(27,'(')\n");break;
case 28:printf("(28,')')\n");break;
}
}
/*函数名:recignition
形参:无
函数功能:存放字母的数组tempc[]与关键字进行对比,
输出字符数组中的关键字
返回值:无*/
void recignition()
{
int t=0;
int i=0;
char cc[100]="";
if(strcmp(tempc,r1)==0)
t=1;
else if(strcmp(tempc,r2)==0)
t=2;
else if(strcmp(tempc,r3)==0)
t=3;
else if(strcmp(tempc,r4)==0)
t=4;
else if(strcmp(tempc,r5)==0)
t=5;
else if(strcmp(tempc,r6)==0)
t=6;
if(t>0)
Swit(t);
else
printf("(10,'%s')\n",tempc);
for(;c>0;c--)
tempc[c]=cc[0];
t=0;
}
4.运行结果及分析
四、 实验总结
一开始的时候,自己做了一份比较粗糙的、不完善的词法分析程序,在后面经过老师讲解和参考、分析了同学的代码后,自己再原有的程序上进行了改进和完善。