词法分析程序构造原理与实现技术
实验报告
变更说明
日期
版本
变更位置
变更说明
作者
2014/4/9
1.0
初稿生成
房皓
2014/4/9
1.0
完善 兀善
截稿
房皓
、 实 验目的:
本实验的目的在于在教师的引导下以问题回朔与思维启发的方式, 使学生在 不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术, 启迪学生的 抽象思维、 激发学生的学习兴趣、 培养学生的探究精神和专业素养, 从而提高学 生发现问题、分析问题和解决问题的能力。
、实验内容:
[ 实验项目 ] 完成以下正则文法所描述的 Pascal 语言子集单词符号的词法分析 程序。
<标识符字母丨 < 标识符〉字母丨 < 标识符〉数字
<无符号整数 >—数字丨 < 无符号整数〉数字
<单字符分界符> T + I- I * I; I ( I)
<双字符分界符>f <大于>=I <小于>=I <小于>> I <冒号>=I <斜竖>* <小于>f < <等于>f = <大于>T> <冒号> T: < 斜竖> T/
该语言的保留字: begin end if then else for do while and or not
[设计说明](1)该语言大小写不敏感;(2)字母为a-z A-Z,数字为0-9; (3) 可以对上述文法进行扩充和改造;(4) ‘/*……*/ '为程序的注释部分。
[设计要求] (1)给出各单词符号的类别编码;( 2)词法分析程序应能发现输
入串中的错误;( 3)词法分析作为单独一遍编写,词法分析结果为二元式序列 组成的中间文件;( 4)设计两个测试用例(尽可能完备),并给出测试结果。
三、实验环境:
操作系统: Windows 7
软件: VC++6.0
四、程序功能描述:
给出了各单词符号的类别编码; 词法分析程序能够对给出的文件中的输入串做出正确的词法; 词法分析程序能发现文件输入串中的错误; 词法分析结果为二元式序列组成的中间文件; 词法分析程序能兼容注释并能发现文件注释未关闭的错误
五、数据结构设计:
char T0KEH[20];
FILF *fp_out=fopen("result-txf"w"); char ch;
int i=0,c;
int zhu5hi=0;
ch^fgetcCFp);
六、程序结构描述:
设计方法:
本程序采用从文件读取字符串,根据已有文法、词法的构成及规定对字 符串进行词法分析,其种类主要包括保留字、标识符、无符号数字、字符等, 将分析的结果写入另一个文件。程序规定的单词符号及其种别码见下表:
单词符号及其种别码表
单词符号
种别码
单词符号
种别码
begin
1
r无符号整数
13
end
2
+
14
If
3
-
15
the n
4
*
16
else
5
17
for
6
(
18
do
7
)
19
while
8
=
20
and
9
>
21
or
10
>=
22
not
11
<
23
标识符
12
<=
24
<>
25
:=
26
/
27
/*
28
*/
29
主要函数说明:
-圉 cffx classes
-臼 Globals
lookup (char *str)
mainQ
scanner[FILE xfp)
lookup():每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将 相应关键字的类别码赋给整型变量 c;否则将c置为0;
mai n():主函数;
scanner()扫描函数,完成程序的主要功能,包括读字符串、分析处理、分 析处理等。
函数调用关系说明:
main()函数调用 scanner()函数; scanner()函数调用 lookup()函数。
执行框图:
1)总体结构图:
丁
结束
2)扫描程序结构框图:
七、实验过程结果截图:
测试用例一:
jriput-txt * 记质本 | 回
交1牛(F)需辑旧13式(0)登君〔V)降助凹
asdf 1234T 4 <〉<》(,#+//+dfakldf j+/ >=df^~
结果一:
F - r?ulttxt ■记事本 [=| 回
立弓粗F)端辑IE)瑣式【0)至看(V)帮助[冊
U^asdf) (13, 1234)(1^, & 阪 ^"(23, <)(21,5)(25?<>X1B,(帀讥,亍(非法字符川)fl & *)(27,7F (28, /*)(汪釋鰭束,*/) (22, >=) (12, dfa)
结果二:
""resulttxt-HS^ ? 回
文件{F)彌制E]您式奁看(V)
*
测试用例二:
测试用例二:
八、实验总结:
实验心得:
通过本次实验我锻炼了自己的上机操作能力及编程能力, 并对理论知识有了
进一步的了解。本实验基本思路比较清晰,用较为简单的算法就能实现;解 决实验中遇到的问题也花费了一部分时间, 我增长了处理关于文件错误的能 力;
实验中遇到的问题:
主要问题就是在读取文件时对文件末尾的判断预处理, 有两个问题花费了大
部分时间,一个是在回退时要判断是否为文件末尾,若是则不需要回退;另 外一个就是要先读取一个字符再用 feof(fp)来判断是否为文件尾,且两个应 紧密相连;
程序的自我评价:
此程序实现了要求中的所有功能,并增加了对注释的一些操作,但因编程能 力的欠缺,其中有的地方不免有些繁杂,还有一些潜藏的问题,需要进一步 测试来时程序变得更加具有健壮性。
九、程序清单:
/****************************************************
课题名称:词法分析程序构造原理与实现技术
作者:房皓 进修最后修改时间:2014.4.9 19:47
***************************************************/
单词符号及其分类编码************************************************
单词符号及其分类编码
单词符号
种别码
单词符号
种别码
begin
1
无符号整数
13
end
2
+
14
if
3
-
15
then
4 *
16
else
5 ;
17
for
6
(
18
do
7
)
19
while
8
=
20
and
9
>
21
or
10
>=
22
not
11
<
23
标识符
12
<=
24
<>
25
:=
26
/
27
/*
28
*/
//29
/***************************************************/
#include<iostream>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////
int lookup(char *str)// 每调用一次,就以 TOKEN 中的字符串查保留字表,若查到,就将相应 关键字的类别码赋给整型变量 c;否则将c置为0
{ char*letter[11]={"begin","end","if","then","else","for","do","while","and","or","not"};// 保 留
字
int i; for(i=0;i<11;i++)
{
if(strcmp(str,letter[i])==0) //比较是否相同
return i+1; //若相同,返回相
应的种别码
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////
int scanner(FILE *fp)
{
char TOKEN[20];
FILE *fp_out=fopen("result.txt","w");
}
}
}
}
char ch;
int i=0,c;
int zhushi=0;
前不是注释, zhushi=1 表示当前及以后的都是注释
ch=fgetc(fp);
while(!feof(fp))
{
if(zhushi==0)
{
i=0;
if(ch==' '||ch==' ')
{}
else
if(isalpha(ch))
{ ch=tolower(ch); TOKEN[0]=ch; i++; ch=fgetc(fp); while(isalnum(ch)) {
if(isalpha(ch))
ch=tolower(ch);
TOKEN[i]=ch; i++;
ch=fgetc(fp);
} TOKEN[i]='\0'; if(ch!=EOF) 此判断,遇到文件结尾仍返回的话,则
fseek(fp,-1L,1);
最后一个字符
c=lookup(TOKEN);
if(c==0)
{
fprintf(fp_out,"(%d,%s)",12,TOKEN); printf("(%d,%s)\n",15,TOKEN);
}
else
{
//zhushi 等于 0 表示当
//zhushi 等于 0 表示当
//判断文件结束
//是否为字母
//转换成小写
//数字或字母
//经验证,若没有
//ch 的值永远为文件
//查找保留字
//标识符
//标识符
//保留字
//保留字
e-se
if(isdigif(ch)) 一一^^比濟啪 宀
TOKENollcm
chufgeo(fp)八
+■+
whi-e(isdigifoh))
宀
TOKEN=llcm
+■+
chufgeofp)八
TOKENUII-?
ifoh'ilEOF)
fseek(fp 匕 LL)八
fprinffuplouwdvgJWTOKEN)- 二耳公4謡蒲 prinff(=(%CL%s)云J6HOKEN)- 二耳公4磔蒲 e-se
swifch(ch)
caseA-
if(一 feof(fp))
chufgeofp)八
ifohlu-)
宀
fprinff(fplouf=(%dy%s)=24/u=)八 prinff(=(%CL%s)云=24/u£
e-se
=h(chlv)
宀
fprinff(fplouL=(%dy%s)=25/v== prinff(=(%dy%s?=25/v== e-se 宀
if(ch'ilEOF) fseek(fp「二)八 fprinff(fplouL=(%d-%c)=23A-=
prinff(=(%d-%c?=23\-=
break 八
}
}
case'=':
{
fprintf(fp_out,"(%d,%c)",20,'='); printf("(%d,%c)\n",20,'=');
}
break;
case'>':
if(!feof(fp))
ch=fgetc(fp);
if(ch=='=')
{
fprintf(fp_out,"(%d,%s)",22,">="); printf("(%d,%s)\n",22,">=");
}
else
{
if(ch!=EOF) fseek(fp,-1,1);
fprintf(fp_out,"(%d,%c)",21,'>'); printf("(%d,%c)\n",21,'>');
}
break;
case'+':
{
fprintf(fp_out,"(%d,%c)",14,'+'); printf("(%d,%c)\n",14,'+');
}
break;
case'-':
{
fprintf(fp_out,"(%d,%c)",15,'-'); printf("(%d,%c)\n",15,'-');
}
break;
case'*':
{
fprintf(fp_out,"(%d,%c)",16,'*'); printf("(%d,%c)\n",16,'*');
}
break;
case';':
{
fprintf(fp_out,"(%d,%c)",17,';'); printf("(%d,%c)\n",17,';');
}
break;
case'(':
{
fprintf(fp_out,"(%d,%c)",18,'('); printf("(%d,%c)\n",18,'(');
}
break;
case')':
{
fprintf(fp_out,"(%d,%c)",19,')'); printf("(%d,%c)\n",19,')');
}
break;
case'/':
if(!feof(fp))
ch=fgetc(fp);
if(ch=='*')
{
//zhushi=1;zhushi=1;
//zhushi=1;
fprintf(fp_out,"(%d,%s)",28,"/*"); printf("(%d,%s)\n",28,"/*");
}
else
{
if(ch!=EOF) fseek(fp,-1,1);
fprintf(fp_out,"(%d,%c)",27,'/'); printf("(%d,%c)\n",27,'/');
}
break;
case':':
if(!feof(fp))
ch=fgetc(fp);
if(ch=='=')
{
fprintf(fp_out,"(%d,%s)",26,":="); printf("(%d,%s)\n",26,":=");
}
else
{
if(ch!=EOF) fseek(fp,-1,1);
break;
default:
fprintf(fp_out,"(%s,%c)"," 非法字符 ",ch); printf("(%s,%c)\n"," 非法字符 ",ch); break;
}
}
ch=fgetc(fp);
if(zhushi==1) //该 部分为 检查注 释
是否结束,若结束,则令 shuzhi=0;
if(ch=='*')
{
if(!feof(fp))
ch=fgetc(fp);
if(ch=='/')
{
fprintf(fp_out,"(%s,%s)"," 注释结束 ","*/");
printf("(%s,%s)\n"," 注释结束 ","*/");
zhushi=0;
ch=fgetc(fp);
}
else
{
if(ch!=EOF)
fseek(fp,-1,1);
ch=fgetc(fp);
}
}
}
if(zhushi==1) //没有关闭注释
{
fprintf(fp_out,"(%s)"," 程序有错误,注释没有关闭! ");
printf("(%s)\n"," 程序有错误,注释没有关闭! ");
}
fclose(fp_out);
return 1;
}
///////////////////////////////////////////////////////////////////////////////////////
int main()
{
FILE *fp=fopen("input.txt","r");
scanner(fp);
fclose(fp);
return 1;
推荐访问:实验报告 词法 构造 原理 词法分析程序构造原理与实现技术实验报告文档