编译原理课程设计Pascal语言词法语法分析器设计.docx
- 文档编号:17536070
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:61
- 大小:146.04KB
编译原理课程设计Pascal语言词法语法分析器设计.docx
《编译原理课程设计Pascal语言词法语法分析器设计.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计Pascal语言词法语法分析器设计.docx(61页珍藏版)》请在冰点文库上搜索。
编译原理课程设计Pascal语言词法语法分析器设计
编译原理课程设计
题目:
Pascal语言词法、语法分析器设计
姓名:
学院:
专业:
班级:
学号:
指导教师:
职称:
副教授
2014年06月09日
南京农业大学教务处制
附录
1.程序清单
2.测试报告
Pascal语言词法、语法分析器设计
1实验设计
编译程序是现代运算机系统的大体组成部份之一,而且多数运算机系统都配有不止一个高级语言的编译程序,对有些高级语言乃至配置了几个性能不同的编译程序。
[1]
为了能够更好地把握编译原理的大体理论和编译程序构造的大体方式及技术,通过对Pascal语言词法、语法分析器的设计,关于提高我小组设计的能力,加深对编译理论知识的明白得与应用有很重要的作用。
1.1系统整体框架
主程序
语法分析
程序
词法分析
程序
图1:
系统整体框架
1.2实验目的
1)完成词法分析器并通过测试;
2)完成语法分析器并通过测试。
3)利用九组测试文件对程序进行测试并撰写测试报告,完成实验报告。
1.3系统设计构思
PL/0语言的编译进程采纳一趟扫描方式,以语法语义分析程序为核心,词法分析程序和代码生成程序都作为一个独立的进程,当语法分析需要读单词时就挪用词法分析程序,当语法分析程序需要生成中间代码时就挪用代码生成程序。
另外用表格治理程序成立标量、常量和进程标识符的说明与引用之间的信息联系。
用犯错处置程序对词法和语法分析碰到的错误给出在源程序中犯错的位置和性质[1]。
本小组所设计词法分析与语法分析器,参考了PL/0编译器的设计思路。
与PL/0编译器不同的是,表格治理程序与犯错处置程序被综合在语法分析程序中,且缺少中间代码的说明执行程序。
词法分析器每读到一个单词都会执行入单词表操作enterWordtable()操作,并给出单词的属性,值和id号,以备后面输出词法分析结果。
语法分析器挪用词法分析器获取一个单词以后,分析单词的类别。
若是是标识符那么需要挪用表格治理程序的positon()函数,查看此单词在table表中位置。
若是语法分析器当前分析的语句是变量声明或常量声明或进程声明,且标识符在table中已存在那么转犯错处置eorror(),不然,若是是常量、变量或进程名引用且标识符在table表中不存在那么转犯错处置error()。
若是语法分析概念产生式有一条匹配,那么立刻进行规约,并执行相应的操作,如入表操作,查表操作,犯错处置,中间代码生成和输出当前所匹配产生式等。
其中代码生成处置程序并无作为一个单独的模块进行设计,而是穿插在语法分析程序中,以方便挪用。
同时,将中间代码记录在代码表code中,其中当前所生成的代码在code表中寄存的位置由cx指针决定。
2词法分析程序
词法分析器相对来讲比较简单,作为一个独立子程序词法分析是编译进程中的一个时期,在语法分析前进行。
2.1模块设计
Lex的输入文件分为三个时期,说明部份、识别规那么、辅助进程。
说明部份中line表示行数,nchar表示字符个数,nword表示单词数。
intyywrad(void)是系统里面自带的函数。
voidyyerror(char*)是报错函数。
enumidentkind{constant,variable,procedure}是标识符类型,分为常量,变量和进程三种。
charkeyword[13][20]是用一个数组概念关键字,intid[13]概念标识符,typedefstructnode概念一个单词数组charname[20]是单词名字,charsym[20]是对应的标识符,intid是对应的标识符号,intnum是对应的数值。
wordTypewordTable[200]是一个单词表,寄存输入的单词,voidenterWordtable(char*,int,int)表示单词进表。
digit[0-9]是数字,letter[a-zA-Z]是字母,num[1-9]({digit})*|0是数值,ident[_A-Za-z]([_A-Za-z]|[0-9])*是字母或下划线开头的标识符unlegalident[0-9]{ident}是不合法的标识符。
标识部份中概念了关键字,如[\t]{;}空格,[\n]{line++;nchar++;}换行。
"const"{nchar+=yyleng;enterWordtable("SYM_const",SYM_const,-1);常量,每读到一个关键字的字符,单词的长度就加一,所读到的字符就进入单词表存起来;,-1表示不输出。
运算符,如"="{nchar++;enterWordtable("OPR_become",OPR_become,-1);returnOPR_become;}等号。
边界符"("{nchar++;enterWordtable("BDY_lparen",BDY_lparen,-1);returnBDY_lparen;}左括号。
{ident}是把识别到的标识符独到单词表里去,{num}是返回对应的数值,{unlegalident}如果词法分析上不通过,就会报错。
辅助进程中voidenterWordtable(char*sym,intid,intnum)是单词进表,参数别离表示标识符,id号和数值。
voidlistWordtable()表示输出单词表。
intyywrap(void)是系统自带的,读到文件最后返回1,voidsetInputDirect(FILE*input)是读文件。
intyygetchar(void)是获取字符。
2.2具体功能设计
1)说明部份:
#include"stdio.h"//头文件
#include"string.h"//头文件
#include"malloc.h"//头文件
#include"windows.h"//头文件
#include"myyacc_table.h"//头文件
intline=1;//统计行数
intnchar=0;//统计字符数
intnword=0;//统计单词数
intyywrap(void);//约束,返回1表示扫描后程序终止,不然返回0
voidyyerror(char*);//
typedefstructnode{
charname[20];
charsym[20];
intid;
intnum;
}wordType;
wordTypewordTable[200];//单词表数组
voidenterWordtable(char*,int,int);//入表函数说明
digit[0-9]//无符号整数
letter[a-zA-Z]//标识符
num[1-9]({digit})*|0
ident[_A-Za-z]([_A-Za-z]|[0-9])*
unlegalident[0-9]{ident}//不合法的标识符
2)识别规那么:
"const"{nchar+=yyleng;enterWordtable("SYM_const",SYM_const,-1);returnSYM_const;}//以此为例,若是显现const那么统计字符个数的加上显现单词长度,并进入单词表,由于为保留字不输出数值,返回。
{ident}{
nchar+=yyleng;
yylval.ident=(char*)malloc(strlen(yytext)+1);
strcpy(yylval.ident,yytext);
enterWordtable("SYM_ident",SYM_ident,-1);
returnSYM_ident;
}
//以此为例,显现标识符那么统计字符个数的加上显现单词长度,同时;利用malloc函数分派存储空间同时注意有个串终止符因此加1。
以后进行拷贝并进入单词表,由于为标识符不输出数值,返回。
3)辅助进程:
voidenterWordtable(char*sym,intid,intnum)//进入单词表
voidlistWordtable()//输出词法分析结果
intyywrap(void)//约束,返回1表示扫描后程序终止,不然返回0
intyygetchar(void)//取得键盘输入
3语法分析程序
语法分析器是进行语法检查、并构建由输入的单词组成的数据结构。
通常利用一个独立的词法分析器从输入字符流中分离出一个个的“单词”,并将单词流作为其输入。
3.1流程图设计
开始
打开文件fileopen()
关闭文件fileclose()
结束
调用语法分析
过程输出?
错误判断?
输出过程等
Y
N
图3:
语法分析器流程图
词法分析
语法分析器流程主若是main函数的前提,依照流程图的操作对main函数进行书写。
由于全数写入main函数,代码过于冗杂,将部份函数,例如打开文件,关闭文件,错误检测单独列出来,减少main函数代码量。
程序开始后先打开文件,如此才能进行写入工作,以后判定文件是不是打开成功,不成功继续打开。
成功以后进行判定是不是进行输出,如此有助于快速查看结果。
判定终止后就开始对测试文件进行判定,是不是符合语法,输出结果,终止程序。
3.2模块设计
说明部份包括了YACC需要用来成立分析程序的有关记号、数据类型和文法规那么的信息。
它还包括了必需在它的开始时直接进入输入文件的任何C代码,主若是其他源代码文件的#include指示。
包括头文件表、全局变量reducecount、listreduce和printReduce函数说明。
以后开始概念符号、语义值,概念终结符,概念结合性(采纳左结合)。
规那么部份包括修改的BNF格式的文法规那么,和将在识别出识别出相关的文法规那么时被执行的C代码中的动作。
例如规那么<程序>:
:
=<程序开始><程序体>,当知足那个条件时就进行动作,输出那个进程。
依照PL/0语言文法的EBNF表示,进行规那么说明包括:
<程序>:
:
=<程序开始><程序体>
<程序开始>:
:
=program<标识符>分号
<程序体>:
:
=<分程序>
<分程序>:
:
=[<常量说明部份>][<变量说明部份>][<进程说明部份>]<语句>
<常量说明部份>:
:
=<无分号常量说明部份>
<无分号常量说明部份>:
:
=const<常量概念>{,<常量概念>},<常量概念>:
:
=<标识符>=<无符号整数>
<变量说明部份>:
:
=<无分号变量说明部份>
<无分号变量说明部份>:
:
=var<标识符>{<,标识符>}
<进程说明部份>:
:
=<进程首部><分程序>{;进程说明部份}
<进程首部>:
:
=procedure<标识符>,<语句>:
:
=<赋值语句>|<条件语句>|
<赋值语句>:
:
=<标识符>=<表达式>
<表达式>:
:
=<标识符>{[+|-]<项>}
<项>:
:
=<因子>{[*|/]<因子>}
<因子>:
:
=<标识符>|<无符号整数>|‘(’<表达式>‘)’
<条件语句>:
:
=if<条件>then<语句>
<条件>:
:
=<表达式><关系运算符><表达式>
<关系运算符>:
:
===|#|<|<=|>|>
:
=while<条件>do<语句>
:
=call<标识符>
<读语句>:
:
=read‘(’<标识符列表>‘)’
<标识符列表>:
:
=<标识符>{,<标识符>}
<表达式列表>:
:
=<表达式>{,<表达式>}
<写语句>:
:
=write‘(’<标识符列表>‘)’
<复合语句>:
:
=begin<语句序列>end
<语句序列>:
:
=<语句>{;<语句>}end。
程序部份包括词法分析子程序yylex()(利用LEX生成),语义动作子程序,犯错处置子程序yyerror(),加上打开文件、关闭文件、输出进程函数。
3.3具体功能设计
1)说明部份:
#include"code.h"//头文件
#include"windows.h"//头文件
intreducecount=1;//规约计数器,利用该全局变量为规约进程编号排序
intlistreduce=0;//判定,为0时不输出规约进程,为1时输出规约进程
intlistwordtable=0;//判定,为0时不输出单词表,为1时输出单词表
voidprintReduce(char*s);//函数声明
union{
char*ident;
intnumber;//保留数值
}
startprogram//必需以非终结符program开头
tokenSYM_program//以此为例概念终结符
……
leftSYM_plus//概念结合性为左结合,加法
2)规那么部份:
program:
programstartprogramblock
{printReduce("program->programstartprogramblock");}
……
//以此为例若是符合<程序>:
:
=<程序开始><程序体>规约那么执行动作输出规约进程。
3)程序部份:
voidprintReduce(char*s)//若是listreduce==1,输出规约进程
yyerror(char*s)//输犯错误个数及行数
voidfileopen()//先打开要写入文件,再打开输入的测试文件
voidfileclose()//关闭文件
voidcanList()//界面
voidmain(void)//主函数,用来挪用其他函数
4结果及测试
4.1总程序
,程序开始后先打开文件,如此才能进行写入工作,以后判定文件是不是打开成功,不成功继续打开。
成功以后进行判定是不是进行输出,如此有助于快速查看结果。
判定终止后就开始对测试文件进行判定,是不是符合语法在这当中挪用table.h和词法分析,分析以后不管是不是符合语法要求都输出结果,若是符合语法那么输出通过windows自带变色函数输出绿色符合字样,输出以后返回白色终止程序;不然利用变色函数输出红色错误字样,而且标犯错误位置和错误数量,以后返回白色,终止程序。
语法分析里的position函数在table.h中概念,用来判定位置。
4.2测试平台
测试平台:
联想idealpad
操作系统:
Windows7旗舰版64位
处置器:
Intel(R)Core(TM)i3-2350MCPU@2.30GHz
内存:
4.00G
4.3测试案例
programpro;
consta:
=10;
varb,c;
procedurep;
begin
c:
=b+a;
end;
begin
read(b);
whileb#0do
begin
callp;
write(2*c);
read(b);
end;
end;
4.4测试进程及结果
图:
开始界面
图:
测试完成界面部份一
图:
测试完成界面部份二
图:
测试完成界面部份三
图:
测试完成界面部份四
图:
测试完成界面部份五
图:
测试完成界面部份六
图:
测试完成界面中间代码
4.5测试分析
表1:
九组测试案例测试结果及分析
编号
错误个数
错误行数
错误类型
分析
1
0
无错误
无错误
符合语法分析
2
1
Line4
重复定义
b,c重复定义了不符合语法
3
1
Line5
没有定义
b,c没有定义不符合语法
4
1
Line2
超出范围
a=1000000000超出int范围
>32768
5
1
Line6
定义变量名
使用关键字
Read为关键字不能被定义为变量
6
1
Line6
赋值号左边出现常量
A为常量不能出现赋值号
左边应为一个变量
7
1
Line12
Call语句
Call后面应该接一个过程而b是一个变量
8
1
Line9
Read
Read后面应该接一个变量
而p是一个过程
9
1
Line6
表达式
表达式中标示符的属性应该为变量、常量、数字而p是一个过程
通过九组测试案例的测试,咱们小组将语法分析的一些情形考虑完善,当符合语法时能正确判定,同时能识别出以上列举出的多种错误,可是当关键字被概念成变量名时(varread,b,c;)的错误尽管能检测出来可是事实上是默许成了进行read语句,这一点尚未完善。
整体来讲,程序运行情形良好。
5总结
5.1不足
1)咱们小组本来打算进行中间代码的生成,可是由于自身能力不足和对知识把握得不够严谨没能在规按时刻内完成中间代码的生成,没能使咱们的代码加倍的完善;
2)当关键字被概念成变量名时(例如:
varread,b,c;)的错误尽管能检测出来可是事实上是默许成了进行read语句,这一点尚未完善。
5.2心得
5.3分工
参考文献:
[1]张素琴,吕映芝,蒋维社,戴桂兰.编译原理(第2版)[M].北京:
清华大学出版社,200
程序清单:
mylex.l
/*词法分析器*/
%{
#include"stdio.h"
"
#include"malloc.h"
#include"windows.h"
#include"myyacc_table.h"
intline=1;
intnchar=0;
intnword=0;
externFILE*fa1;
intyywrap(void);
voidyyerror(char*);
enumidentkind{constant,variable,procedure};
charkeyword[13][20]={
"const",
"procedure",
"begin",
"end",
"write",
"read",
"do",
"call",
"while",
"if",
"then",
"program",
"var"
};
typedefstructnode{
charname[20];
charsym[20];
intid;
intnum;
}wordType;
wordTypewordTable[200];
voidenterWordtable(char*,int,int);
%}
digit[0-9]
letter[a-zA-Z]
num[1-9]({digit})*|0
ident[_A-Za-z]([_A-Za-z]|[0-9])*
unlegalident[0-9]{ident}
%%
[\t]{;}
[\n]{line++;nchar++;}
"const"{nchar+=yyleng;enterWordtable("SYM_const",SYM_const,-1);returnSYM_const;}
"procedure"{nchar+=yyleng;enterWordtable("SYM_procedure",SYM_procedure,-1);returnSYM_procedure;}
"begin"{nchar+=yyleng;enterWordtable("SYM_begin",SYM_begin,-1);returnSYM_begin;}
"end"{nchar+=yyleng;enterWordtable("SYM_end",SYM_end,-1);returnSYM_end;}
"write"{nchar+=yyleng;enterWordtable("SYM_write",SYM_write,-1);returnSYM_write;}
"read"{nchar+=yyleng;enterWordtable("SYM_read",SYM_read,-1);returnSYM_read;}
"do"{nchar+=yyleng;enterWordtable("SYM_do",SYM_do,-1);returnSYM_do;}
"call"{nchar+=yyleng;enterWordtable("SYM_call",SYM_call,-1);returnSYM_call;}
"while"{nchar+=yyleng;enterWordtable("SYM_while",SYM_while,-1);returnSYM_while;}
"if"{nchar+=yyleng;enterWordtable("SYM_if",SYM_if,-1);returnSYM_if;}
"then"{nchar+=yyleng;enterWordtable("SYM_then",SYM_then,-1);returnSYM_then;}
"program"{nchar+=yyleng;enterWordtable("SYM_program",SYM_program,-1);returnSYM_program;}
"var"{nchar+=yyleng;enterWordtable("SYM_var",SYM_var,-1);returnSYM_var;}
":
="{nchar+=2;enterWordtable("OPR_become",OPR_become,-1);returnOPR_become;}
"+"{nchar++;enterWordtable("OPR_plus",OPR_plus,-1);returnOPR_plus;}
"-"{nchar++;enterWordtable("OPR_minus",OPR_minus,-1);returnOPR_minus;}
"*"{nchar++;enterWordtable("OPR_times",OPR_times,-1);returnOPR_times;}
"/"{nchar++;enterWordtable("OPR_slash",OPR_slash,-1);returnOPR_slash;}
"<"{nchar++;enterWordtable("OPR_lss",OPR_lss,-1);returnOPR_lss;}
"<="{nchar+=2;enterWordtable("OPR_leq",OPR_leq,-1);returnOPR_leq;}
">"{nchar++;enterWordtable("OPR_gtr",OPR_gtr,-1);returnOPR_gtr;}
">="{nchar+=2;enterWordtable("OPR_geq",OPR_geq,-1);returnOPR_geq;}
"!
="{nchar+=2;enterWordtable("O
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程设计 Pascal 语言 词法 语法 分析器 设计