实验一、算法分析实验
专业:商业软件工程 姓名:李智濠 学号:201506110117
一、 实验目的
编制一个词法分析程序。
二、 实验内容和要求
输入:源程序字符串
输出:二元组(种别,单词本身)
待分析语言的词法规则。
三、 实验方法、步骤及结果测试
- 1. 源程序名:压缩包文件(rar或zip)中源程序名 kenk.c
可执行程序名:kenk.exe
- 2. 原理分析及流程图
对字符串表示的源程序
从左到右进行扫描和分解
根据词法规则
识别出一个一个具有独立意义的单词符号
以供语法分析之用
发现词法错误,则返回出错信息
- 3. 主要程序段及其解释:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _KEY_WOED_END "waiting for your expanding" //关键字结束标志
typedef struct
{
int typenum;
char * word;
}WORD;
char input[255];
char token[255]="";
int p_input;
int p_token;
char ch; //当前所读的字符
char *rwtab[]={"begin","if","then","while","do","end",_KEY_WOED_END}; //C语言关键字
WORD * scaner(); //词法扫描函数,获得关键字
main()
{
int over=1;
WORD *oneword;
oneword=(WORD *)malloc(sizeof(WORD));
printf("请输入您的单词(以#作为结束标志):");
scanf("%[^#]s",input); //读入源程序字符串到缓冲区,以#结束,允许多行输入
p_input=0;
printf("您输入的单词是:%s\n\n",input);
while(over<1000&&over!=-1)
{
oneword=scaner();
printf("(%d,%s)",oneword->typenum,oneword->word);
over=oneword->typenum;
}
printf("\n按#可推出程序");
scanf("%[^#]s",input);
}
//需要用到的自编函数参考实现
//从输入缓冲区读取一个字符到ch中
char m_getch(){
ch=input[p_input];
p_input=p_input+1;
return (ch);
}
//去掉空白字符
void getbc()
{
while(ch==‘ ‘||ch==10){
ch=input[p_input];
p_input=p_input+1;
}
}
//拼接单词
void concat()
{
token[p_token]=ch;
p_token=p_token+1;
token[p_token]=‘\0‘;
}
//判断是否字母
int letter()
{
if(ch>=‘a‘&&ch<=‘z‘||ch>=‘A‘&&ch<=‘Z‘)return 1;
else return 0;
}
//判断是否数字
int digit()
{
if(ch>=‘0‘&&ch<=‘9‘)
return 1;
else
return 0;
}
//检索关键字表格
int reserve()
{
int i=0;
for(i=0;i<7;i++)
{
if(!strcmp(rwtab[i],token))
{
return i+1;
}
i=i+1;
}
return 10;
}
//回退一个字符
void retract()
{
p_input=p_input-1;
}
/*数字转换成二进制
char *dtb()
{
return NULL;
}
*/
WORD *scaner()
{
WORD *myword;
myword=(WORD *)malloc(sizeof(WORD));
myword->typenum=10;
myword->word="";
p_token=0;
m_getch();
getbc();
if(letter())
{
while(letter()||digit())
{
concat();
m_getch();
}
retract();
myword->typenum=reserve();
myword->word=token;
return(myword);
}
else if(digit())
{
while(digit())
{
concat();
m_getch();
}
retract();
myword->typenum=20;
myword->word=token;
return(myword);
}
else
{
switch(ch)
{
case ‘=‘:m_getch();
if(ch==‘=‘)
{
myword->typenum=39;
myword->word="==";
return(myword);
}
retract();
myword->typenum=21;
myword->word="=";
return(myword);
break;
case ‘+‘:
myword->typenum=22;
myword->word="+";
return(myword);
break;
case ‘-‘:
myword->typenum=23;
myword->word="-";
return(myword);
break;
case ‘*‘:
myword->typenum=24;
myword->word="*";
return(myword);
break;
case ‘/‘:
myword->typenum=25;
myword->word="/";
return(myword);
break;
case ‘(‘:
myword->typenum=26;
myword->word="(";
return(myword);
break;
case ‘)‘:
myword->typenum=27;
myword->word=")";
return(myword);
break;
case ‘[‘:
myword->typenum=28;
myword->word="[";
return(myword);
break;
case ‘]‘:
myword->typenum=29;
myword->word="]";
return(myword);
break;
case ‘{‘:
myword->typenum=30;
myword->word="{";
return(myword);
break;
case ‘}‘:
myword->typenum=31;
myword->word="}";
return(myword);
break;
case ‘,‘:
myword->typenum=32;
myword->word=",";
return(myword);
break;
case ‘:‘:
myword->typenum=33;
myword->word=":";
return(myword);
break;
case ‘;‘:
myword->typenum=34;
myword->word=";";
return(myword);
break;
case ‘>‘:
myword->typenum=35;
myword->word=">";
return(myword);
break;
case ‘<‘:
myword->typenum=36;
myword->word="<";
return(myword);
break;
case ‘!‘:
m_getch();
if(ch==‘=‘)
{
myword->typenum=40;
myword->word="!=";
return(myword);
}
retract();
myword->typenum=-1;
myword->word="ERROR";
return(myword);
break;
case ‘\0‘:
myword->typenum=1000;
myword->word="OVER";
return(myword);
break;
default:
myword->typenum=-1;
myword->word="ERROR";
return(myword);
}
}
}
- 4. 运行结果及分析
一般必须配运行结果截图,结果是否符合预期及其分析。
(截图需根据实际,截取有代表性的测试例子)
四、 实验总结
对要输出的字符串和字符组不是很熟悉,虽然网上有代码参考,但还是不懂。