编译原理课程设计Pascal语言词法、语法分析器设计.doc_第1页
编译原理课程设计Pascal语言词法、语法分析器设计.doc_第2页
编译原理课程设计Pascal语言词法、语法分析器设计.doc_第3页
编译原理课程设计Pascal语言词法、语法分析器设计.doc_第4页
编译原理课程设计Pascal语言词法、语法分析器设计.doc_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

编译原理课程设计题 目: pascal语言词法、语法分析器设计 姓 名: 学 院: 专 业: 班 级: 学 号: 指导教师: 职称: 副教授 2014 年06月09日南京农业大学教务处制目录1 实验设计21.1 系统整体框架21.2 实验目的21.3系统设计构思22 词法分析程序32.1 模块设计32.2 具体功能设计43 语法分析程序53.1 流程图设计53.2 模块设计63.3 具体功能设计84结果及测试94.1 总程序94.2 测试平台114.3测试案例114.4 测试过程及结果114.5 测试分析165 总结175.1 不足175.2 心得175.3 分工18附录1.程序清单 mylex.lmyyacc.ycode.htable.h2. 测试报告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表示单词数。int yywrad(void)是系统里面自带的函数。void yyerror(char *)是报错函数。enum identkindconstant,variable,procedure是标识符类型,分为常量,变量和过程三种。char keyword1320是用一个数组定义关键字,int id13定义标识符,typedef struct node定义一个单词数组char name20是单词名字,char sym20是对应的标识符,int id是对应的标识符号,int num是对应的数值。wordtype wordtable200是一个单词表,存放输入的单词,void enterwordtable(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-9ident是不合法的标识符。标识部分中定义了关键字,如 t;空格,nline+; nchar+;换行。constnchar+=yyleng;enterwordtable(sym_const,sym_const,-1);常量,每读到一个关键字的字符,单词的长度就加一,所读到的字符就进入单词表存起来;,-1表示不输出。运算符,如=nchar+;enterwordtable(opr_become,opr_become,-1);return opr_become;等号。边界符(nchar+;enterwordtable(bdy_lparen,bdy_lparen,-1);return bdy_lparen;左括号。ident是把识别到的标识符独到单词表里去,num是返回对应的数值,unlegalident如果词法分析上不通过,就会报错。辅助过程中void enterwordtable(char *sym,int id,int num)是单词进表,参数分别表示标识符,id号和数值。void listwordtable()表示输出单词表。int yywrap(void)是系统自带的,读到文件最后返回1,void setinputdirect(file *input)是读文件。int yygetchar(void)是获取字符。2.2 具体功能设计1)说明部分:#include stdio.h /头文件#include string.h /头文件#include malloc.h /头文件#include windows.h /头文件#include myyacc_table.h /头文件int line=1; /统计行数int nchar=0; /统计字符数int nword=0; /统计单词数int yywrap(void); /约束,返回1表示扫描后程序结束,否则返回0void yyerror(char *); /typedef struct nodechar name20;char sym20;int id;int num;wordtype;wordtype wordtable200; /单词表数组void enterwordtable(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-9ident /不合法的标识符2)识别规则:constnchar+=yyleng;enterwordtable(sym_const,sym_const,-1);return sym_const;/以此为例,如果出现const则统计字符个数的加上出现单词长度,并进入单词表,由于为保留字不输出数值,返回。identnchar+=yyleng;yylval.ident=(char *)malloc(strlen(yytext)+1);strcpy(yylval.ident,yytext);enterwordtable(sym_ident,sym_ident,-1);return sym_ident;/以此为例,出现标识符则统计字符个数的加上出现单词长度,同时;利用malloc函数分配存储空间同时注意有个串结束符因此加1。之后进行拷贝并进入单词表,由于为标识符不输出数值,返回。3)辅助过程:void enterwordtable(char *sym,int id,int num)/进入单词表void listwordtable() /输出词法分析结果int yywrap(void) /约束,返回1表示扫描后程序结束,否则返回0int yygetchar(void) /获得键盘输入3 语法分析程序语法分析器是进行语法检查、并构建由输入的单词组成的数据结构。通常使用一个独立的词法分析器从输入字符流中分离出一个个的“单词”,并将单词流作为其输入。3.1 流程图设计开始打开文件fileopen()关闭文件fileclose()结束调用语法分析过程输出?错误判断?输出过程等yn图3:语法分析器流程图词法分析语法分析器流程主要是main函数的前提,根据流程图的操作对main函数进行书写。由于全部写入main函数,代码过于冗杂,将部分函数,例如打开文件,关闭文件,错误检测单独列出来,减少main函数代码量。程序开始后先打开文件,这样才能进行写入工作,之后判断文件是否打开成功,不成功继续打开。成功之后进行判断是否进行输出,这样有助于快速查看结果。判断结束后就开始对测试文件进行判断,是否符合语法,输出结果,结束程序。3.2 模块设计说明部分包括了yacc需要用来建立分析程序的有关记号、数据类型以及文法规则的信息。它还包括了必须在它的开始时直接进入输入文件的任何c代码,主要是其他源代码文件的#include指示。包含头文件表、全局变量reducecount、listreduce以及printreduce函数说明。之后开始定义符号、语义值,定义终结符,定义结合性(采用左结合)。规则部分包括修改的bnf格式的文法规则,以及将在识别出识别出相关的文法规则时被执行的c代码中的动作。例如规则:=,当满足这个条件时就进行动作,输出这个过程。根据pl/0语言文法的ebnf表示,进行规则说明包括::=:=program分号:=:=:=:=const,,:=:=:=var:=;过程说明部分:=procedure,:=|:=:=+|-:=*|/:=|():=ifthen:=:=|#|:=whiledo:=call:=read():=,:=,:=write():=beginend:=;end。程序部分包括词法分析子程序yylex()(利用lex生成),语义动作子程序,出错处理子程序yyerror(),加上打开文件、关闭文件、输出过程函数。3.3 具体功能设计1)说明部分:#include code.h /头文件#includewindows.h /头文件int reducecount=1; /规约计数器,利用该全局变量为规约过程编号排序int listreduce=0; /判断,为0时不输出规约过程,为1时输出规约过程int listwordtable=0; /判断,为0时不输出单词表,为1时输出单词表void printreduce(char *s); /函数声明unionchar *ident;int number; /保存数值 start program /必须以非终结符program开头token sym_program /以此为例定义终结符left sym_plus /定义结合性为左结合,加法2)规则部分:program:programstart programblock printreduce(program-programstart programblock);/以此为例如果符合:=规约则执行动作输出规约过程。3)程序部分:void printreduce(char *s) /如果listreduce=1,输出规约过程yyerror(char *s) /输出错误个数及行数void fileopen() /先打开要写入文件,再打开输入的测试文件void fileclose() /关闭文件void canlist() /界面void main(void) /主函数,用来调用其他函数4结果及测试4.1 总程序双击lex.yy.exe文件即可运行,程序开始后先打开文件,这样才能进行写入工作,之后判断文件是否打开成功,不成功继续打开。成功之后进行判断是否进行输出,这样有助于快速查看结果。判断结束后就开始对测试文件进行判断,是否符合语法在这之中调用table.h以及词法分析,分析之后无论是否符合语法要求都输出结果,如果符合语法则输出通过windows自带变色函数输出绿色符合字样,输出之后返回白色结束程序;否则利用变色函数输出红色错误字样,并且标出错误位置以及错误数量,之后返回白色,结束程序。语法分析里的position函数在table.h中定义,用来判断位置。4.2 测试平台测试平台:联想 idealpad操作系统: windows 7 旗舰版 64位处理器: intel(r) core(tm)i3-2350m cpu 2.30 ghz内存:4.00g4.3测试案例program pro;const a:=10;var b,c;procedure p;beginc:=b+a;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b);end;end;4.4 测试过程及结果图:开始界面图:测试完成界面部分一图:测试完成界面部分二图:测试完成界面部分三图:测试完成界面部分四图:测试完成界面部分五图:测试完成界面部分六图:测试完成界面中间代码4.5 测试分析表1:九组测试案例测试结果及分析编号错误个数错误行数错误类型分析10无错误无错误符合语法分析21line4重复定义b,c重复定义了不符合语法31line5没有定义b,c没有定义不符合语法41line2超出范围a=1000000000超出int范围3276851line6定义变量名使用关键字read为关键字不能被定义为变量61line6赋值号左边出现常量a为常量不能出现赋值号左边应为一个变量71line12call语句call后面应该接一个过程而b是一个变量81line9readread后面应该接一个变量而p是一个过程91line6表达式表达式中标示符的属性应该为变量、常量、数字而p是一个过程经过九组测试案例的测试,我们小组将语法分析的一些情况考虑完善,当符合语法时能正确判断,同时能识别出以上列举出的多种错误,但是当关键字被定义成变量名时(var read,b,c;)的错误虽然能检测出来但是实际上是默认成了进行read语句,这一点还没有完善。总体来说,程序运行情况良好。5 总结5.1 不足1)我们小组原本打算进行中间代码的生成,但是由于自身能力不足以及对知识掌握得不够严谨没能在规定时间内完成中间代码的生成,没能使我们的代码更加的完善;2)当关键字被定义成变量名时(例如:var read,b,c;)的错误虽然能检测出来但是实际上是默认成了进行read语句,这一点还没有完善。5.2 心得5.3 分工参考文献:1张素琴,吕映芝,蒋维社,戴桂兰.编译原理(第2版)m . 北京:清华大学出版社,2005.2程序清单:mylex.l/*词法分析器*/%#include stdio.h#include string.h#include malloc.h#include windows.h#include myyacc_table.hint line=1;int nchar=0;int nword=0;extern file *fa1;int yywrap(void);void yyerror(char *);enum identkindconstant,variable,procedure;char keyword1320=const,procedure,begin,end,write,read,do,call,while,if,then,program,var;typedef struct nodechar name20;char sym20;int id;int num;wordtype;wordtype wordtable200;void enterwordtable(char *,int,int);%digit 0-9letter a-za-znum 1-9(digit)*|0ident _a-za-z(_a-za-z|0-9)*unlegalident 0-9ident% t;n line+; nchar+;const nchar+=yyleng;enterwordtable(sym_const,sym_const,-1);return sym_const;procedurenchar+=yyleng;enterwordtable(sym_procedure,sym_procedure,-1);return sym_procedure;begin nchar+=yyleng;enterwordtable(sym_begin,sym_begin,-1);return sym_begin;end nchar+=yyleng;enterwordtable(sym_end,sym_end,-1);return sym_end;write nchar+=yyleng;enterwordtable(sym_write,sym_write,-1);return sym_write;read nchar+=yyleng;enterwordtable(sym_read,sym_read,-1);return sym_read;do nchar+=yyleng;enterwordtable(sym_do,sym_do,-1);return sym_do;call nchar+=yyleng;enterwordtable(sym_call,sym_call,-1);return sym_call;while nchar+=yyleng;enterwordtable(sym_while,sym_while,-1);return sym_while;if nchar+=yyleng;enterwordtable(sym_if,sym_if,-1);return sym_if;then nchar+=yyleng;enterwordtable(sym_then,sym_then,-1);return sym_then;programnchar+=yyleng;enterwordtable(sym_program,sym_program,-1);return sym_program;varnchar+=yyleng;enterwordtable(sym_var,sym_var,-1);return sym_var;:=nchar+=2;enterwordtable(opr_become,opr_become,-1);return opr_become;+nchar+;enterwordtable(opr_plus,opr_plus,-1);return opr_plus;-nchar+;enterwordtable(opr_minus,opr_minus,-1);return opr_minus;*nchar+;enterwordtable(opr_times,opr_times,-1);return opr_times;/nchar+;enterwordtable(opr_slash,opr_slash,-1);return opr_slash;nchar+;enterwordtable(opr_lss,opr_lss,-1);return opr_lss;nchar+;enterwordtable(opr_gtr,opr_gtr,-1);return opr_gtr;= nchar+=2;enterwordtable(opr_geq,opr_geq,-1);return opr_geq;!= nchar+=2;enterwordtable(opr_neq,opr_neq,-1);return opr_neq;= nchar+=2;enterwordtable(opr_eql,opr_eql,-1);return opr_eql;# nchar+;enterwordtable(opr_jin,opr_jin,-1);return opr_jin;(nchar+;enterwordtable(bdy_lparen,bdy_lparen,-1);return bdy_lparen;)nchar+;enterwordtable(bdy_rparen,bdy_rparen,-1);return bdy_rparen;,nchar+;enterwordtable(bdy_comma,bdy_comma,-1);return bdy_comma;.nchar+;enterwordtable(bdy_period,bdy_period,-1);return bdy_period;nchar+;enterwordtable(bdy_semicolon,bdy_semicolon,-1);return bdy_semicolon;nchar+;enterwordtable(bdy_lhua,bdy_lhua,-1);return bdy_lhua;nchar+;enterwordtable(bdy_rhua,bdy_rhua,-1);return bdy_rhua ;: nchar+;enterwordtable(bdy_colon,bdy_colon,-1);return bdy_colon;identnchar+=yyleng;yylval.ident=(char *)malloc(strlen(yytext)+1);strcpy(yylval.ident,yytext);enterwordtable(sym_ident,sym_ident,-1);return sym_ident;numnchar+=yyleng;yylval.number=atoi(yytext);enterwordtable(sym_number,300,yylval.number);return sym_number;unlegalidentnchar+=yyleng;nword+;setconsoletextattribute(getstdhandle(std_output_handle),foreground_intensity |foreground_red);printf(%s is unlegal ident!,yytext);setconsoletextattribute(getstdhandle(std_output_handle),foreground_intensity |foreground_red |foreground_green | foreground_blue);.setconsoletextattribute(getstdhandle(std_output_handle),foreground_intensity |foreground_red);printf(unknown character);setconsoletextattribute(getstdhandle(std_output_handle),foreground_intensity |foreground_red |foreground_green | foreground_blue);%void enterwordtable(char *sym,int id,int num)strcpy(wordt,yytext);strcpy(wordtablenword.sym,sym);wordtablenword.id=id;wordtablenword.num=num;nword+;void listwordtable()int i;printf(*词法分析结果*:n);fprintf(fa1,*词法分析结果*:n);printf( name sym idnumn);fprintf(fa1,symidnumn);for(i=0;inword;i+)printf(%-15s%-20s%-20d,wordt,wordtablei.sym,wordtablei.id);fprintf(fa1,%-15s%-20s%-18d,wordt,wordtablei.sym,wordtablei.id);if(wordtablei.num!=-1)printf(%dn,wordtablei.num);fprintf(fa1,%dn,wordtablei.num);elseprintf(n);fprintf(fa1,n);int yywrap(void)return 1;void setinputdirect(file *input)yyin=input;int yygetchar(void)int c;c=getc(yyin);printf(%c,c);return c;myyacc.y/*语法分析器/*说明部分*/%#include code.h#includewindows.hint reducecount=1;int listreduce=0;int listwordtable=0;extern char keyword1320;extern int nchar;extern int nword;void printreduce(char *s);void enterp(int);int getdx(int);void initlevelreg();void backsize();%unionchar *ident;int number;%start program%token sym_program%token sym_const%token sym_procedure%token sym_begin%token sym_end%token sym_write%token sym_read%token sym_do%token sym_call%token sym_while%token sym_if%token sym_else%token sym_then%token sym_repeat%token sym_until%token sym_ident%token sym_number%token sym_var%token opr_jin%token opr_become%token opr_plus%token opr_minus%token opr_times%token opr_slash%token opr_lss%token opr_leq%token opr_gtr%token opr_geq%token opr_neq%token opr_eql%token bdy_lparen%token bdy_rparen%token bdy_comma%token bdy_period%token bdy_semicolon%token bdy_lhua%token bdy_rhua%token bdy_colon%left sym_plus%left sym_minus%left sym_times%left sym_slash/*规则部分*/%/*:=*/program:programstart programblock gen(opr,0,0);printreduce(program-programstart programblock);/*:=programbdy_semicolon*/programstart:sym_program sym_ident bdy_semicolon dx=0;initlevelreg();printreduce(programstart-sym_program sym_ident bdy_semicolon);/*:=*/programblock:sonprogramblockprintreduce(programblock-sonprogramblock);/*:=*/sonprogramblock:sentenceprintreduce(sonprogramblock-sentence);|constexplain sentenceprintreduce(sonprogramblock-constexplain sentence);|varexplain sentenceprintreduce(sonprogramblock-varexplain sentence);|proexplain sentenceprintreduce(sonprogramblock-proexplain sentence);|constexplain varexplain sentenceprintreduce(sonprogramblock-constexplain varexplain sentence);|varexplain proexplain sentenceprintreduce(sonprogramblock-varexplain proexplain sentence);|constexplain varexplain varexplain proexplain sentence|constexplain proexplain sentenceprintreduce(sonprogramblock-constexplain proexplain sentence);|constexplain varexplain proexplain sentenceprintreduce(constexplain varexplain proexplain sentence);/*:=;*/constexplain:noconstexplainbdy_semicolonprintreduce(constexplain-noconstexplain bdy_semicolon);/*:=const,*/noconstexplain:sym_const constdefineprintreduce(noconstexplain-sym_const constdefine);|noconstexplain bdy_comma constdefineprintreduce(noconstexplain-noconstexplain bdy_comma constdefine);/*:=;*/constdefine:sym_ident opr_become sym_numberint i;i=iskeyword($1);if(i!=-1)error(4,$1);return;i=position($1);if(i!=0)error(1,$1);return;kind=constant;strcpy(name,$1);num=$3;enter(kind);printreduce(constdefine-sym_ident opr_become sym_number);/*:=*/varexplain:novarexplain bdy_semicolonprintreduce(varexplain-novarexplain bdy_semicolon);/*:=var*/novarexplain:sym_var sym_identint i;i=iskeyword($2);if(i!=-1)error(4,$2);return;i=position($2);if(i!=0)error(1,$2);return;kind=variable;strcpy(name,$2);num=$2;enter(kind);printreduce(varexplain-sym_var sym_ident);|novarexplain bdy_comma sym_identint i;i=iskeyword($3);if(i!=-1)error(4,$3);return;i=position($3);if(i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论