编译原理实验报告.docx
- 文档编号:27944753
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:17
- 大小:103.92KB
编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
编译原理
实验报告
学院:
软件学院
方向:
软件开发
班级:
软件xxxx
学号:
20xxxxxx
姓名:
xxxxx
指导教师:
xxxxx
时间:
20xx年xx月xx日
本科实验报告
课程名称:
编译原理
实验项目:
实验一、无符号数的词法分析程序
实验地点:
xxxxx
专业班级:
xxxxxx学号:
20xxxxx
学生姓名:
xxx
指导教师:
xxxx
xxx年xx月xx日
一、实验目的和要求(必填)
目的:
1.培养学生初步掌握编译原理实验的技能。
2.验证所学理论、巩固所学知识并加深理解。
3.对学生进行实验研究的基本训练。
要求:
从键盘上输入一串字符(包括字母、数字等),最后以“;”结束,编写程序识别出其中的无符号数。
二、实验内容和原理(必填)
内容:
掌握词法分析的基本思想,并用高级语言编写无符号数的词法分析程序。
无符号数文法规则可定义如下:
<无符号数>→<无符号实数>│<无符号整数>
<无符号实数>→<无符号整数>.<数字串>[E<比例因子>]│
<无符号整数>E<比例因子>
<比例因子>→<有符号整数>
<有符号整数>→[+│-]<无符号整数>
<无符号整数>→<数字串>
<数字串>→<数字>{<数字>}
<数字>→0123......9
三、主要仪器设备(必填)
笔记本电脑VisualStudio2012
四、操作方法与实验步骤(可选)
1.学习第四章词法分析,储备实验必须知识
2.理解单词符号的种类等概念,并且学习读无符号数的程序流程
3.复习C#语言中变量声明与函数定义等知识
4.选择VisualStudio作为开发平台
五、实验数据记录和处理(可选)
Console.WriteLine("请输入预判别的语句:
(软件1024班xxxxxxxxxxxx)");
stringStr=Console.ReadLine();
char[]charNum={'0','1','2','3','4','5','6','7','8','9','E','e'};
char[]charOperator={'+','-','*','%','/'};
List
stringNum="";
for(inti=0;i { if(charNum.Contains(Str[i])) { if(Num! =""&&Num.Substring(Num.Length-1)! ="E"&&Num.Substring(Num.Length-1)! ="e") Num=Num+Str[i].ToString(); if(Num=="") Num=Num+Str[i].ToString(); } elseif(charOperator.Contains(Str[i])) { if((Str[i]=='+'||Str[i]=='-')&&(Num! =""&&(Num.Substring(Num.Length-1)=="E"||Num.Substring(Num.Length-1)=="e"))) { Num=Num+Str[i].ToString(); } else { if(Num! ="") StrArray.Add(Num); StrArray.Add(Str[i].ToString()); Num=""; } } } if(Num! ="") { StrArray.Add(Num); } foreach(stringsinStrArray) { Console.WriteLine(s); } Console.WriteLine("软件xxxx班xxxxxxxxxxxx"); Console.ReadLine(); } 六、实验结果与分析(必填) 七、讨论、心得(可选) 经过不断的尝试与调试,这个读取无符号数的程序终于得以运行。 在这个过程中加深了我对编译过程中词法分析的理解,并且通过后续的学习,了解到词法分析是非常重要的编译过程对后续的语法分析影响很大。 是编译程序得以运行的基础,学到了知识。 并且加深了我对C#语言的掌握 本科实验报告 课程名称: 编译原理 实验项目: 实验二、逆波兰式生成程序 实验地点: xxxxxx 专业班级: xxxxxx学号: xxxxxx 学生姓名: xxxxxx 指导教师: xxxxxx 20xx年xx月xx日 一、实验目的和要求(必填) 内容: 掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序; 要求: 利用逆波兰式生成算法编写程序,将从键盘上输入的算术表达式(中缀表达式)转化成逆波兰式。 二、实验内容和原理(必填) 逆波兰表达式的生成过程涉及到运算符的优先级,下表中列出几个常用运算符的优先关系。 + - * / ↑ ( ) + > > < < < < > - > > < < < < > * > > > > < < > / > > > > < < > ↑ > > > > > < > ( < < < < < < = ) > > > > > > 常用运算符优先关系矩阵 如上表所示的优先关系矩阵表示了+,-,*,/,↑,(,)等七种运算符之间的相互优先关系。 “>、<、=”三种符号分别代表“大于”、“小于”、“相等”三种优先关系。 左边的“=”与右边的“(”之间没有优先关系存在,所以表中为空白。 逆波兰表达式生成算法的关键在于比较当前运算符与栈顶运算符的优先关系,若当前运算符的优先级高于栈顶运算符,则当前运算符入栈,若当前运算符的优先级低于栈顶运算符,则栈顶运算符退栈。 下面给出了逆波兰表达式生成算法的流程图。 (为了便于比较相邻运算符的优 先级,需要设立一个工作栈,用来存放暂时不能处理的运算符,所以又称运算符栈)。 三、主要仪器设备(必填) 笔记本电脑VisualStudio2012 四、操作方法与实验步骤(可选) 1.学习课本上有关逆波兰式的知识,为实验做准备 2.研究运算符优先关系矩阵,理解算符优先分析方法 3.复习数据结构中栈的知识,并学习其C语言实现 4.选择Win-TC作为开发平台,进行开发、调试 五、实验数据记录和处理(可选) staticvoidMain(string[]args) { varrpn=newReversePolishNotation(); Console.WriteLine("请输入想要转换的中缀表达式(xxxxxx班xxxxxxxxxxxx)"); varexpression=Console.ReadLine().ToString(); try { Console.WriteLine(rpn.RpnExpression(expression)); Console.WriteLine(rpn.Calculate(expression)); } catch(Exceptionex) { Console.WriteLine(ex.Message); } Console.WriteLine("xxxxxx班xxxxxxxxxxxx"); Console.ReadKey(); } classReversePolishNotation { Dictionary publicInnerOperator[]Operators { get { InnerOperator[]opts=newInnerOperator[operators.Count]; inti=0; foreach(variteminoperators.Values) { opts[i]=item; i++; } returnopts; } } publicvoidAddOperation(Operatoropt) { if(operators.ContainsKey(opt.Symbol)) thrownewArgumentException("opt: 指定的操作符符号已存在! "); operators.Add(opt.Symbol,opt); } publicReversePolishNotation() { operators=newDictionary operators.Add(')',newRightBrace(')',"右括号",1)); operators.Add('(',newLeftBrace('(',"左括号",2)); operators.Add('+',newAdd('+',"加",3)); operators.Add('-',newMinus('-',"减",3)); operators.Add('*',newMutiply('*',"乘",4)); operators.Add('/',newDivide('/',"除",4)); } publicstringRpnExpression(stringexpression) { if(string.IsNullOrEmpty(expression)) thrownewArgumentException("表达式不存在或者是空的! "); expression=expression.Replace("",string.Empty); if(expression.IndexOf("..")>=0) thrownewArgumentException("表达式中某些数字可能不合法,或者表达式无法理解! "); boolisDigit=false; Stack stringresult=string.Empty; charlastopt=char.MinValue; for(inti=0;i { boolisNegative=false; if((lastopt==char.MinValue||lastopt=='(')&&expression[i]=='-') { isNegative=true; if(++i==expression.Length) break; } if(char.IsDigit(expression[i])) { stringstrNum=string.Empty; do { strNum+=expression[i].ToString(); if(++i==expression.Length) break; if(char.IsDigit(expression[i])||expression[i]=='.') isDigit=true; else isDigit=false; }while(isDigit); if(isNegative) result+="-"+strNum+""; else result+=strNum+""; } if(i { if(! operators.ContainsKey(expression[i])) thrownewArgumentException("算式中含有不支持的运算符! "); while(opts.Count>0&&(operators[opts.Peek()].Pri>=operators[expression[i]].Pri)&&expression[i]! ='(') { result+=opts.Pop().ToString()+""; } opts.Push(expression[i]); lastopt=expression[i]; } } while(opts.Count>0) { result+=opts.Pop().ToString()+""; } result=result.Replace("(",string.Empty).Replace(")",string.Empty).TrimEnd(); if(this.isRPN(result)) returnresult; else thrownewArgumentException("表达式不能被理解! "); } boolisRPN(stringrpn) { Stack for(inti=0;i { stringstrTemp=string.Empty; while(i ='') { strTemp+=rpn[i].ToString(); i++; } if(strTemp.Length==1&&operators.ContainsKey(strTemp[0])) { if(rpnStack.Count<2) returnfalse; rpnStack.Pop(); } else { rpnStack.Push(strTemp); } } if(rpnStack.Count==1&&! operators.ContainsKey(rpnStack.Pop()[0])) returntrue; else returnfalse; } publicdoubleCalculate(stringexpression) { stringrpn=this.RpnExpression(expression); Stack for(inti=0;i { stringstrTemp=string.Empty; while(i ='') { strTemp+=rpn[i].ToString(); i++; } if(strTemp.Length==1&&operators.ContainsKey(strTemp[0])) { varop2=double.Parse(rpnStack.Pop()); varop1=double.Parse(rpnStack.Pop()); rpnStack.Push((operators[strTemp[0]]asIOperator).Calc(op1,op2).ToString()); } else { rpnStack.Push(strTemp); } } returndouble.Parse(rpnStack.Pop()); } publicabstractclassInnerOperator { intpri; stringname; charsymbol; publiccharSymbol { get{returnsymbol;} } publicstringName { get{returnname;} } publicintPri { get{returnpri;} } publicInnerOperator(charsymbol,stringname,intpri) { this.symbol=symbol; this.name=name; this.pri=pri; } } publicinterfaceIOperator { doubleCalc(doubleop1,doubleop2); } classAdd: InnerOperator,IOperator { publicAdd(charsymbol,stringname,intpri): base(symbol,name,pri){} publicdoubleCalc(doubleop1,doubleop2) { returnop1+op2; } } classMinus: InnerOperator,IOperator { publicMinus(charsymbol,stringname,intpri): base(symbol,name,pri){} publicdoubleCalc(doubleop1,doubleop2) { returnop1-op2; } } classMutiply: InnerOperator,IOperator { publicMutiply(charsymbol,stringname,intpri): base(symbol,name,pri){} publicdoubleCalc(doubleop1,doubleop2) { returnop1*op2; } } classDivide: InnerOperator,IOperator { publicDivide(charsymbol,stringname,intpri): base(symbol,name,pri){} publicdoubleCalc(doubleop1,doubleop2) { returnop1/op2; } } classLeftBrace: InnerOperator { publicLeftBrace(charsymbol,stringname,intpri): base(symbol,name,pri){} } classRightBrace: InnerOperator { publicRightBrace(charsymbol,stringname,intpri): base(symbol,name,pri){} } publicabstractclassOperator: InnerOperator,IOperator { publicOperator(charsymbol,stringname,intpri) : base(symbol,name,pri) { if(pri<3) thrownewArgumentException("pri: 优先级最低不能小于3(加、减符号的优先级)! "); } publicabstractdoubleCalc(doubleop1,doubleop2); } 六、实验结果与分析(必填) 七、讨论、心得(可选) 在这个实验中,我体会到了逆波兰式在计算机执行中的巨大优势。 同时对算符优先分析方法的学习,也为后续的语义分析及中间代码的学习酿造了一个良好的开始。 同时通过该实验我还复习了数据结构中有关栈的知识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告