1、编译原理实验报告实验一 词法分析1、实验目的通过设计、编写和调试词法分析程序,了解词法分析程序的作用,组成结构,不同种类单词的识别方法,掌握由单词的词法规则出发,画出识别单词的状态转换图,然后在用程序实现词法分析程序设计方法。2、词法规则1、注释用和括起来。注释体中不能有。注释可以出现在任何记号的后面。2、记号间的空格可有可无,但关键字前后必须有空格、换行、程序的开头或者结尾的原点。3、标识符的记号id 与以字母开头的字母数字串相匹配:Letter-a-zA-ZDigit-0-9Id-letter (letter | digit)*4、记号num与无符号整数相匹配:Digits-digit d
2、igit*Optional_fraction - . Digits | Optional_exponent-(E(+ | - | ) digits) | Num -digits optional_fraction optional_exponent5、关键字要被保留且在文法中以黑体出现6、关系运算符(relop)指:=、=、7、Addop: + 、 - 、or8、Mulop:*、/ 、div、mod、and9、Assignop: :=3、词法分析程序详细设计及判别状态图1、无符号数(可带小数和指数)的状态转换图:2、标识符/关键字的状态转换图:程序详细设计:4、开发环境本程序在Microsof
3、t Visual C+ 6.0环境中编写,无特殊编译要求。5、函数清单void LexcialAnalysis(FILE *fp);/词法分析主函数int JudgeFirstLetter(char ch);/判断单词的第一个字符int IsDigit(char ch);/判断是否为数字int IsLetter(char ch);/判断是否为字母int IsSpecialPunc(char ch);/判断是否为特殊标点void RecogDigit(char StrLine);/用状态图识别无符号数字void RecogIdentifier(char strLine);/用状态图识别标识符vo
4、id RecogPunc(char strLine);/识别特殊标点int IsKeyWord(string str);/判断标识符是否为关键字void error();/出错处理6、测试程序program example(input, output);comments goes here!var x, y: integer;function gcd(a, b: integer): integer;begin if b =1.2e3 then gcd := a else gcd := gcd(b, a mod b)end;begin read(x, y); write(gcd(x, y);en
5、d.7、运行效果8、实验总结通过这次编译器词法分析程序的编写,我更好地了解了词法分析的作用及工作原理,讲课本中的知识融入到程序编写过程中,理论结合了实际。最先的时候觉得自己没有学过编译原理也可以写出语法分析,觉得书上的理论没有用,但是状态转换图则以一种十分规范的分析方式来分析程序, 这样的做法应该是让词法分析从简单的程序实现上升到理论.而不仅仅拘泥于程序语言范畴之内.自己通过状态转换图识别单词和数字的过程,我觉得这种思想是值得我们借鉴的,很美妙。当然,本次实验由于能力、时间等多方面因素只是实现了一个简单的词法分析程序,很多地方还不是很完善,如错误处理等。此外,在编写词法分析程序的过程中,我遇到
6、不少的问题,通过不断地调试才得以解决,锻炼了我调试程序的能力,这个能力是很难得的。实验二 语法分析9、实验目的 通过设计、编写和调试自顶向下语法分析程序,了解一般自顶向下语法分析程序的组成以及对文法的要求,掌握从给定文法出发构造相应的预测分析表的方法。10、实验设计本次语法分析实验我选用自顶向下的LL(1)预测分析方法,该方法实现的语法分析程序最主要的一点就是能构造出其文法对应的预测分析表,只有正确的预测分析表,才能得到正确的语法分析结果。我使用了一个队列(Queue)来存放词法分析的结果,在词法分析过程中就开始维护该队列,然后在语法分析的时候,从队列中读取词法分析的结果。此外,我还定义了一个
7、分析栈,供语法分析过程使用。11、文法规则终结符(VT)1.保留关键字Program const do begin end call if else then function var while int real 特殊标点: , ; : . ( )其他assignop := mulop *、/、div、mod、and addop +、-、or relop =、=、.(0 1 2 3 4 5 ) Id 变量名 num 数字非终结符P(program) Ds(declarations) Subp_Ds(subprogram_declarations) C_S(compound_statement
8、) ID_L(id_list) T(type) Subp_D(subprogram_delaclation) Subp_H(subprogram_head) A(arguments) P_L(parameter_list) OP_S(optional_statement) S_L(starement_list) S(statement) P_S(procedure_statememt) E_L(expression_list) E(expression) S_E(simple_expression) Tm(term) F(factor) 消除左递归后产生的新的非终结符ID_L , P_L, S
9、_L,E_L, S_E Tm, E, F改进后文法:1.P-program id(ID_L); Ds Subp_Ds C_S .2.ID_L-id ID_L3.ID_L-,id ID_L4.ID_L-5.Ds-var ID_L : T ;Ds6.Ds- 7.T- integer8.T-real9.Subp_Ds-Subp_D ;Subp_Ds10.Subp_Ds-11.Subp_D-Subp_H Ds C_S12.Subp_H-function id A :T ; 13.A-(P_L)14.A-15.P_L - ID_L: T P_L16.P_L - ; ID_L: T P_L17.P_L -
10、18.C_S - begin OP_S end19.OP_S - S_L20.OP_S - 21.S_L - S S_L22.S_L - ; S S_L23.S_L - 24.S id P_S25.P_S - assignop E26.P_S - (E_L)27.S - C_S28.S - if E then S else S29.S - while E do S30.E_L - E E_L31.E_L - , E E_L32.E_L - 33.E-S_E E34.E-relop S_E35.E- 36.S_E- Tm S_E37.S_E- addop Tm S_E38.S_E - 39. T
11、m - F Tm40.Tm - mulop F Tm41.Tm - 42. F -id F43. F -(E_L)44. F - 45.F-46.F-(E)47.F-not F以上文法构造出预测分析表,然后在程序中维护该预测分析表。(预测分析表见最后或源程序)12、函数清单及数据结构struct Queue/定义一个队列 int front; int rear; string *str;void InitQueue(Queue &q,int QueueSize)/初始化队列 q.front=q.rear=0; q.str=new stringQueueSize;void EnQueue(Que
12、ue &q,string str)/进队 q.strq.rear=str; q.rear+;void DeQueue(Queue &q,string &str)/出队 str=q.strq.front; q.front+;typedef struct/定义分析栈 int base; int top; symbol *symbol;Stack;void GetTop(Stack s,symbol &symbol)/获得栈顶元素 if(s.base=s.top) cout栈为空; return; symbol=s.symbols.top;void Push(Stack &s,symbol symb
13、ol)/进栈 s.top+; s.symbols.top=symbol;void Pop(Stack &s,symbol &symbol)/出栈 if(s.base=s.top) coutfNamePath; if(fp=fopen(ex.cpp,r)!=NULL)/文件可读就跳出循环 break; else cout文件路径错误!请输入源文件名(包括路径和后缀名):; LexcialAnalysis(fp);/词法分析 SyntaxAnalysis();/语法分析13、运行效果由于结果很长这里只贴上部分截屏 14、实验总结 通过本次设计、编写和调试语法分析程序的过程,我了解了一般自顶向下语法
14、分析程序的组成以及对文法的要求,掌握了从给定文法出发构造相应的预测分析表的方法。如构造First集、Follow集、Select集和LL(1)预测分析表。了解了语法分析的具体过程。由于时间的原因,我的语法分析程序还并不完善,出错处理还不是面面俱到,待以后有时间再完善也是一次不错的锻炼。 在语法分析的学习中,通过对自顶向下和自底向上理解, 让我领悟了一些有价值的考虑问题的方法. 在我看来编译原理从本质上来讲就是算法问题,本次的实验大多也都是算法思想的体现,只是由于编译器的复杂性,算法复杂性很高而已,不知道这样理解是不是很幼稚。 回到本次程序的语法层上, 利用的LL也就是从文法的起始符号开始反复使用产生式进行推导直至推导出输入符号串.自上而下分析通常要求文法的产生式不含左递归,否则会使分析程序死循环,所以先要对文法进行必要的化简, 然后根据所得的状态转移图来编制程序, 以前程序很多时候都是看题目后直接上手, 这次编程步骤的条理性的确又上升了一个层次. 所以这次小的课程设计从另外一方面也加强了我的程序设计功底。 编译原理上机就此告一段落,虽然在编写代码上用的时间不像课程那样长,但在编写程序期间的感受颇多。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1