实验一、算法分析实验
专业:商业软件工程 姓名:李智濠 学号: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. 运行结果及分析
一般必须配运行结果截图,结果是否符合预期及其分析。
(截图需根据实际,截取有代表性的测试例子)
四、 实验总结
对要输出的字符串和字符组不是很熟悉,虽然网上有代码参考,但还是不懂。