编译原理-实验4
- 格式:doc
- 大小:72.00 KB
- 文档页数:4
实验1简单的词法分析子程序【实验目的】●理解词法分析在编译程序中的作用●初步了解和掌握词法分析程序的实现方法和技术【实验内容】1. 编写程序,输入一串字符,判断该字符串是否为合法标识符或合法整型常量。
2. 无符号数的算术四则运算中的各类单词的识别。
输入:由无符号数、+、-、*、/、(、)构成的算术表达式。
输出:对识别出的每一单词均单行输出。
如,输入:8*2.5-1.0e2则,输出:8*2.5-1.0e2描述无符号数的确定的、最小化的状态转换图如图1所示。
其中编号1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。
图1 文法G[<无符号数>]的状态转换图实验2词法分析程序设计【实验目的】●理解词法分析中的正规式和自动机●掌握词法分析程序的实现方法和技术【实验内容】某一高级程序设计语言的部分语言子集定义如下:(1)关键字:for if then else while do(所有关键字都是小写)(2)运算符和分隔符:+ - * / : = <><= <>>= == ; ( ) #(3)其他标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter|digit)*NUM=digit·digit*(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、分隔符和关键字,词法分析阶段通常被忽略。
各种词法单元对应的词法记号如下:编写程序,实现词法分析功能。
输入:源程序输出:二元组(词法记号,属性值/其在符号表中的位置)构成的序列。
例如:输入源程序x=5;if (x>0)thenx=2*x+1/3;elsex=2/x;#(# 表示输入结束)经词法分析后输出如下序列:(10,x)(18,=)(11,5)(26,;)(2,if)(27,()…说明:关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
计算机硬件实验室实验报告姓名学号班级成绩设备名称及软件环境逆波兰一、实验目的:将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式,并计算用逆波兰式来表示的算术表达式的值。
二、实验要求:输出的格式如下:(1)逆波兰式的生成及计算程序,编制人:姓名,学号,班级(2)输入一以#结束的中缀表达式(包括+—*/()数字#):在此位置输入符号串如(28+68)*2#(3)逆波兰式为:28&68+2*(4)逆波兰式28&68+2*计算结果为192备注:(1)在生成的逆波兰式中如果两个数相连则用&分隔,如28和68,中间用&分隔;(2)在此位置输入符号串为用户自行输入的符号串。
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、数字,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);三、实验过程:(一)准备:1.阅读课本有关章节,2.考虑好设计方案;3.设计出模块结构、测试数据,初步编制好程序。
(1)定义部分:定义常量、变量、数据结构。
(2)初始化:设立算符优先分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(3)控制部分:从键盘输入一个表达式符号串;(4)利用算符优先分析算法进行表达式处理:根据算符优先分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
(5)对生成的逆波兰式进行计算。
(二)上课上机:将源代码拷贝到机上调试,发现错误,再修改完善。
第二次上机调试通过。
四、实验结果(1)写出程序流程图(2)给出运行结果程序:#include<stdio.h>#include<math.h>#include<stdlib.h>#define max 100char ex[max]; /*存储后缀表达式*/void trans(){ /*将算术表达式转化为后缀表达式*/char str[max]; /*存储原算术表达式*/char stack[max]; /*作为栈使用*/char ch;int sum,i,j,t,top=0;// printf("*****************************************\n");printf("逆波兰式的生成及计算程序,编制人:武普泉,20号,1020562班\n");printf("输入一以#结束的中缀表达式(包括+ - * /()数字# ):");// printf("******************************************\n");// printf("算数表达式:");i=0; /*获取用户输入的表达式*/do{i++;scanf("%c",&str[i]);}while(str[i]!='#' && i!=max);sum=i;t=1;i=1;ch=str[i];i++;while(ch!='#'){switch(ch){case '(': /*判定为左括号*/top++;stack[top]=ch;break;case ')': /*判定为右括号*/while(stack[top]!='('){ex[t]=stack[top];top--;t++;}top--;break;case '+': /*判定为加减号*/case '-':while(top!=0&&stack[top]!='('){ex[t]=stack[top];top--;t++;}top++;stack[top]=ch;break;case '*': /*判定为乘除号*/case '/':while(stack[top]=='*'||stack[top]=='/'){ex[t]=stack[top];top--;t++;}top++;stack[top]=ch;break;case ' ':break;default:while(ch>='0'&&ch<='9'){ /*判定为数字*/ ex[t]=ch;t++;ch=str[i];i++;}i--;ex[t]='&';t++;}ch=str[i];i++;}while(top!=0){ex[t]=stack[top];t++;top--;}ex[t]='#';// printf("\n\t原来表达:");// for(j=1;j<sum;j++)// printf("%c",str[j]);printf("\n逆波兰式为:",ex);for(j=1;j<t;j++)printf("%c",ex[j]);}void compvalue(){ /*计算后缀表达式的值*/float stack[max],d; /*作为栈使用*/char ch;int t=1,top=0; /*t为ex下标,top为stack下标*/ch=ex[t];t++;while(ch!='#'){switch(ch){case '+':stack[top-1]=stack[top-1]+stack[top];top--;break;case '-':stack[top-1]=stack[top-1]-stack[top];top--;break;case '*':stack[top-1]=stack[top-1]*stack[top];top--;break;case '/':if(stack[top]!=0)stack[top-1]=stack[top-1]/stack[top];else{printf("\n\t除零错误!\n");exit(0); /*异常退出*/}top--;break;default:d=0;while(ch>='0'&&ch<='9'){d=10*d+ch-'0'; /*将数字字符转化为对应的数值*/ch=ex[t];t++;}top++;stack[top]=d;}ch=ex[t];t++;}printf("\n逆波兰式");for(int j=0;j<t-1;j++)printf("%c",ex[j]);printf("计算结果:%g\n",stack[top]);}void main(){trans();compvalue();}。
国开电大编译原理实验4:语法分析实
验报告
1. 实验目的
本实验的目的是研究和掌握语法分析的原理和实现方法。
2. 实验内容
本次实验主要包括以下内容:
- 设计并实现自顶向下的LL(1)语法分析器;
- 通过语法分析器对给定的输入串进行分析,并输出相应的分析过程;
- 编写测试用例,验证语法分析器的正确性。
3. 实验步骤
3.1 设计LL(1)文法
首先,根据实验要求和给定的语法规则,设计LL(1)文法。
3.2 构建预测分析表
根据所设计的LL(1)文法,构建预测分析表。
3.3 实现LL(1)语法分析器
根据预测分析表,实现自顶向下的LL(1)语法分析器。
3.4 对输入串进行分析
编写程序,通过LL(1)语法分析器对给定的输入串进行分析,并输出相应的分析过程和结果。
3.5 验证语法分析器的正确性
设计多组测试用例,包括正确的语法串和错误的语法串,验证语法分析器的正确性和容错性。
4. 实验结果
经过实验,我们成功设计并实现了自顶向下的LL(1)语法分析器,并对给定的输入串进行了分析。
实验结果表明该语法分析器具有较好的准确性和容错性。
5. 实验总结
通过本次实验,我们对语法分析的原理和实现方法有了更深入的了解。
同时,我们也学会了如何设计并实现自顶向下的LL(1)语
法分析器,并验证了其正确性和容错性。
这对于进一步研究编译原理和深入理解编程语言的语法结构具有重要意义。
6. 参考资料
- 《编译原理与技术》
- 课程实验文档及代码。
编译原理第四版附录c编译程序实验
编译原理第四版附录C编译程序实验指的是一项编译器开发实验,旨在让学生通过实践掌握编译器的设计和实现原理。
该实验一般分为以下几个步骤:
1. 了解编译器的基本原理和流程:这包括词法分析、语法分析、语义分析、代码生成等基本步骤,以及编译器的组成结构、工作流程等概念。
2. 设计编译器的语法和语义规则:在了解编译器的基本原理之后,需要根据具体的编译语言和需求设计语法和语义规则,通常采用自顶向下或自底向上的语法分析方法。
3. 实现编译器的核心算法和数据结构:编译器的核心算法包括词法分析器、语法分析器、语义分析器和代码生成器等,需要实现相应的数据结构和算法。
4. 测试和调试编译器:在完成编译器的实现之后,需要进行测试和调试,包括对编译器的正确性、效率和容错性进行测试和评估,以及对编译器的性能进行优化。
5. 扩展编译器的功能:在完成基本的编译器实现之后,可以考虑对编译器进行功能扩展,例如支持更丰富的语言特性、优化代码生成等。
总的来说,编译原理第四版附录C编译程序实验是一项非常有挑战性和实用性的实验,旨在让学生深入了解编译器的设计和实现原理,提高编程能力和实践经验。
竭诚为您提供优质文档/双击可除编译原理中间代码生成实验报告篇一:编译原理-分析中间代码生成程序实验报告课程名称编译原理实验学期至学年第学期学生所在系部年级专业班级学生姓名学号任课教师实验成绩计算机学院制开课实验室:年月日篇二:编译原理实验中间代码生成实验四中间代码生成一.实验目的:掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。
二.实验内容:1、逆波兰式定义:将运算对象写在前面,而把运算符号写在后面。
用这种表示法表示的表达式也称做后缀式。
2、抽象(语法)树:运算对象作为叶子结点,运算符作为内部结点。
3、三元式:形式序号:(op,arg1,arg2)4、四元式:形式(op,arg1,arg2,result)三、以逆波兰式为例的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。
如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。
(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
四、程序代码://这是一个由中缀式生成后缀式的程序#include#include#include#include#definemaxbuffer64voidmain(){chardisplay_out(charout_ch[maxbuffer],charch[32]);//intcaculate_array(charout_ch[32]);staticinti=0;staticintj=0;charch[maxbuffer],s[maxbuffer],out[maxbuffer];cout cin>>ch;for(i=0;i {out[i]=ch[i];}cout while(out[j]!=#)cout j++;}cout display_out(s,out);//caculate_array;}chardisplay_out(charout_ch[32],charch[]) {inttop=-1;inti=0,data[maxbuffer],n;intj=0;charsta[20];while(ch[i]!=#){if(isalnum(ch[i])){while(isalnum(ch[i])){out_ch[j]=ch[i];j++;i++;}out_ch[j]=;j++;else{switch(ch[i]){case+:case-:if(sta[top]==(||top==-1) {top++;sta[top]=ch[i];i++;}else{//j--;out_ch[j]=sta[top];j++;top--;//i++;}break;//break;case*:case/:if(sta[top]==*/) {out_ch[j]=sta[top];j++;//i++;top--;}else{top++;sta[top]=ch[i];i++;}break;//break;case(:top++;sta[top]=ch[i];i++;break;case):if(sta[top]==() {top--;i++;}if(top==-1){//cout }else{//while(sta[top]!=?(?){ out_ch[j]=sta[top];top--;j++;//}break;}break;/*case?#?:out_ch[j]=?#?; j++;break;*/default:cout ch[i]=#;j=0;break;}}}while(top!=-1){out_ch[j]=sta[top];j++;top--;}out_ch[j]=#;n=0;co(:编译原理中间代码生成实验报告)utwhile(out_ch[n]!=#){cout n++;}cout j=0;returnout_ch[maxbuffer];}五、实验结果:要求:自己给出3个测试用例,观察结果。
河南工业大学实验报告课程名称编译原理_ 实验项目实验四LR(1)分析法院系____信息科学与工程学院____ 专业班级计科F1402班姓名苏朋辉学号0211指导老师侯惠芳日期批改日期成绩一.实验目的1.掌握LR(1)分析法的基本原理2.掌握LR(1)分析表的构造方法3.掌握LR(1)驱动程序的构造方法二.实验内容及要求构造LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。
根据某一文法编制调试LR(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对LR(1)分析法的理解。
程序输入/输出示例:对下列文法,用LR(1)分析法对任意输入的符号串进行分析:(1)E->E+T(2)E->E—T(3)T->T*F(4)T->T/F(5)F->(E)(6)F->i输出的格式如下:(1)LR(1(2)输入一以#结束的符号串((3)输出过程如下:步骤状态栈符号栈剩余输入串动作10#i+i*i#移进(或者为合法符号串)备注:(1)在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;4.可采用的其它的文法。
三.实验过程str3 = str3 + ch2;}cout << step++ << '\t' << str3 << '\t' << str2 << '\t';print(point, input);cout << str1 << ':' << LR[n - 1] << "归约" << endl;}//*********出错else if(str1=="error"){cout << "Error!\n" << "程序错误,分析结束!" << endl;flag = false;}//**********分析成功else if(str1 == "acc"){cout << "Acc!\n"<<"分析成功,终止程序!" << endl;flag = false;}}}int main(){analyse();return 0;}运行结果如图2 ,图3图2图3四、实验总结(心得)通过完成实验,对LR(1)分析法的基本原理、LR(1)分析表的构造方法、LR(1)驱动程序的构造方法有了新的认识;通过实验我学习了到LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。
一、实验目的1. 理解编译原理的基本概念和原理。
2. 掌握编译器的各个阶段及其实现方法。
3. 能够运用编译原理的知识解决实际问题。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 20194. 实验内容:词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成三、实验内容1. 词法分析(1)实验目的:实现一个简单的词法分析器,将源代码中的字符序列转换为词法符号序列。
(2)实验步骤:1)定义词法符号类型,包括标识符、关键字、运算符、常量等。
2)设计词法分析器算法,对源代码进行遍历,将字符序列转换为词法符号序列。
3)实现词法分析器程序,输出词法符号序列。
(3)实验结果:输入源代码:int a = 10;输出词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}2. 语法分析(1)实验目的:实现一个简单的语法分析器,将词法符号序列转换为抽象语法树(AST)。
(2)实验步骤:1)定义语法规则,包括产生式、非终结符、终结符等。
2)设计语法分析算法,根据语法规则对词法符号序列进行解析,生成AST。
3)实现语法分析器程序,输出AST。
(3)实验结果:输入词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}输出AST:```AST:- ExpressionStatement- Expression- BinaryExpression- Identifier: a- Operator: =- Constant: 10```3. 语义分析(1)实验目的:实现语义分析器,对AST进行语义检查,确保程序的正确性。
(2)实验步骤:1)定义语义规则,包括类型检查、作用域检查等。
编译原理实验报告题目表达式语法分析程序的构造学院专业班级学号学生姓名指导教师西安思源学院教务处制二〇一年实验四表达式语法分析程序的构造一、实验目的1 掌握C++语言编译的语法分析程序2 分别掌握LL(1)、算符优先、LR等语法分析方法的构造。
二、实验环境Microsoft Visual C++ 6.0三、实验内容给定某一文法,试构造其简单优先矩阵(或LL(1)矩阵),并编制程序。
给出相应句子的语法分析过程,判其正确性。
例如:给定文法G:E→T E1E1→+TE1/εT→FT1T1→*F/εF→id/(E)(1)先构造其SELECT集合,判定其是否为LL(1)文法(2)是则构造其分析表(3)给出句子id+id*id$的语法分析过程四、设计说明LL(1):#include<stdio.h>#include<string>typedef int datatype;char a[N3]={'$','E'};char c[N4]={'$','z','*','z','+','z'};char *B[N1][N2]={" ", "z ", "+ " , "*" , "(" , ")", "$ ","E " , "xT", " " , " ", "xT", " ", " ","x ", " ", "xT+", " ", " ", "", "","T ", "yF", " ", " ", "yF ", " ", " ","y ", " ", "", "yF*", " ", "" , "","F ", "z", " ", " ", ")E(", " ", " ",};void FXB(){int i,j;cout<<"分析表为: "<<endl;for(i=0;i<N1;i++){for(j=0;j<N2;j++){cout<<B[i][j]<<" "; }cout<<endl;}}void WF(){ int s;char *w[5]={"E->TE'","E'->TE'/e","T->FT'","T'->*F/e","F->(E)/id"}; cout<<"文法为: "<<endl;for(s=0;s<5;s++){cout<<w[s]<<endl;}}void SELECT(){cout<<"SELECT集合为:"<<endl;cout<<"1. select(E->TE')=FIRST(TE')={(,id}"<<endl;cout<<"2. select(E'->+TE')=FIRST(+TE')={+}"<<endl;cout<<"3. select(E'->e)=FIRST(E)UFOLLOW(E')-{e}={$,)}"<<endl;cout<<"4. select(T->FT')={(,id}"<<endl;cout<<"5. select(T'->*F)={*}"<<endl;cout<<"6. select(T'->e)={+,),$}"<<endl;cout<<"7. select(F->(E))={(}"<<endl;cout<<"8. select(F->id)={id}"<<endl;cout<<"为LL(1)文法"<<endl;}void showa(){ int i;cout<<"分析栈为:"<<endl;for(i=0;i<N3;i++){if(a[i]!=0) cout<<a[i];}cout<<endl;}void showb(){ int j;cout<<"输入流为:"<<endl;for(j=0;j<N4;j++){if(c[j]!=NULL) cout<<c[j];}cout<<endl;}void FX(){cout<<"分析如下:"<<endl;showa();showb();int i,j,m,n;i=I();j=J();m=M();n=N();while(a[m]!='$'){if ((a[m]!=c[n])&&(B[i][j]!=NULL)){a[m]=B[i][j][0];a[m+1]=B[i][j][1];a[m+2]=B[i][j][2];showa();showb();m=M();n=N();if(a[m]==c[n]){ }else{m=M();n=N();i=I();j=J();}}else if(a[m]==c[n]){a[m]=NULL; c[n]=NULL;showa();showb();m=M();n=N();i=I();j=J();}}}void main(){WF();SELECT();FXB();FX();}算符优先:void main(){ int i,j,k=0;printf("请输入文法规则数:");scanf("%d",&r);printf("请输入文法规则:\n");for(i=0;i<r;i++){scanf("%s",st[i]);//存储文法规则,初始化FIRSTVT集和LASTVT集first[i][0]=0;/*first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数*/last[i][0]=0;}for(i=0;i<r;i++) //判断文法是否合法{for(j=0;st[i][j]!='\0';j++){if(st[i][0]<'A'||st[i][0]>'Z'){printf("不是算符文法!\n"); exit(-1);}if(st[i][j]>='A'&&st[i][j]<='Z'){if(st[i][j+1]>='A'&&st[i][j+1]<='Z'){printf("不是算符文法!\n");exit(-1);}}}}for(i=0;i<r;i++){for(j=0;st[i][j]!='\0';j++){if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='|')lable[k++]=st[i][j];}}lable[k]='#';lable[k+1]='\0'; table();printf("每个非终结符的FIRSTVT集为:\n"); //输出每个非终结符的FIRSTVT集for(i=0;i<r;i++){ printf("%c: ",st[i][0]);for(j=0;j<first[i][0];j++){printf("%c ",first[i][j+1]);}printf("\n");}printf("每个非终结符的LASTVT集为:\n"); //输出每个非终结符的LASTVT集for(i=0;i<r;i++){ printf("%c: ",st[i][0]);for(j=0;j<last[i][0];j++){printf("%c ",last[i][j+1]);}printf("\n");}printf("算符优先分析表如下:\n");for(i=0;lable[i]!='\0';i++)printf("\t%c",lable[i]);printf("\n");for(i=0;i<k+1;i++){ printf("%c\t",lable[i]);for(j=0;j<k+1;j++){printf("%c\t",data[i][j]);}printf("\n");}printf("请输入文法输入符号串以#结束:");scanf("%s",input);deal();}int deal(){ int i,j;int x,y;int z; //输入串的长度k=1;s[k]='#'; //栈置初值for(i=0;input[i]!='\0';i++); //计算输入串的长度z=i--;i=0;while((a=input[i])!='\0'){ if(zhongjie(s[k]))j=k;elsej=k-1;x=xiabiao(s[j]);y=xiabiao(a);if(data[x][y]=='>'){ out(1,k,s);printf("%c",a);out(i+1,z,input);printf("规约\n");do{ q=s[j];if(zhongjie(s[j-1]))j=j-1;else j=j-2;x=xiabiao(s[j]);y=xiabiao(q);}while(data[x][y]!='<');int m,n,N;for(m=j+1;m<=k;m++){for(N=0;N<r1;N++)for(n=1;string[N][n]!='\0';n++){if(!zhongjie(s[m])&&!zhongjie(string[N][n])){if(zhongjie(s[m+1])&&zhongjie(string[N][n+1])&&s[m+1]==string[N][n+1]){s[j+1]=string[N][0]; break;}}elseif(zhongjie(s[m]))if(s[m]==string[N][n]){s[j+1]=string[N][0]; break;}}}k=j+1;if(k==2&&a=='#'){ out(1,k,s);printf("%c",a);out(i+1,z,input);printf("结束\n");printf("输入串符合文法的定义!\n");return 1; //输入串符合文法的定义}}elseif(data[x][y]=='<'||data[x][y]=='='){ //移进out(1,k,s);printf("%c",a);out(i+1,z,input);printf("移进\n");k++;s[k]=a;i++;}else{printf("\nflase");return 0;}}printf("\nflase");return 0;}SLR(1):void main(){string a[12][9]={{"s5","e","e","s4","e","e", "1","2","3"},{"e","s6","e","e","e","ACC", "e","e","e"},{"e","r2","s7","e","r2","r2", "e","e","e"},{"e","r4","r4","e","r4","r4", "e","e","e"},{"s5","e","e","s4","e","e", "8","2","3"},{"e","r6","r6","e","r6","r6", "e","e","e"},{"s5","e","e","s4","e","e", "e","9","3"},{"s5","e","e","s4","e","e", "e","e","a"},{"e","s6","e","e","sb","e", "e","e","e"},{"e","r1","s7","e","r1","r1", "e","e","e"},{"e","r3","r3","e","r3","r3", "e","e","e"},{"e","r5","r5","e","r5","r5", "e","e","e"}};string s[7]={"","E6","E2","T6", "T2","F6","F2"};char c,cc;string myss="";int flag=0; //看数字或标示符是否结束list<char> ss,ll;list<char>::iterator myit;cout<<"请输入要分析的表达式:"<<endl;while((c=getchar())!='\n'){flag=0;while(isdigit(c)||isalpha(c)){flag=1;c=getchar();}if(flag) ss.push_back('I');if(c=='\n')break;ss.push_back(c);}ss.push_back('$');ll.push_back('$');ll.push_back('0');while(1){if(get(ss.front())!=-1) //输入栈myss=a[getI(ll.back())][get(ss.front())];else {cout<<"错误!"<<endl;break;}if(myss.at(0)=='s') {ll.push_back(ss.front()); //i进入ss.pop_front(); //将I删除ll.push_back(myss.at(1)); //5进入}else if(myss.at(0)=='r'){for(int i=0;i<s[myss.at(1)-48].at(1)-48;i++)ll.pop_back(); //出栈n位cc=ll.back(); //保存当前状态ll.push_back(s[myss.at(1)-48].at(0)); //大写字母ll.push_back(a[getI(cc)][get(ll.back())].at(0));}else if(myss.at(0)=='e') {cout<<"错误!"<<endl;break;}else if(myss.at(0)=='A') {cout<<"匹配成功!"<<endl;break;}for(myss="",myit=ll.begin();myit!=ll.end();myit++)myss+=*myit;cout<<left<<setw(18)<<myss;for(myss="",myit=ss.begin();myit!=ss.end();myit++)myss+=*myit;cout<<right<<setw(16)<<myss;cout<<endl;}cout<<"分析完毕!"<<endl;}运行结果:输入流:算符优先:五、实验总结通过编写算法,对三种方法都有了更好的了解,对编译原理这门课也有了更清晰的认识。
一、实验名称编译原理实验二、实验目的1. 理解编译原理的基本概念和原理。
2. 掌握文法分析、词法分析和语法分析的基本方法。
3. 学会使用编译工具,如Lex和Yacc,实现简单的编译器。
三、实验内容本次实验主要分为三个部分:1. 词法分析2. 语法分析3. 编译器构建四、实验步骤1. 词法分析- 使用Lex工具实现词法分析器。
- 定义输入文件格式,包括源代码和标记。
- 编写Lex规则,将源代码转换为标记序列。
- 使用Flex生成词法分析器程序。
2. 语法分析- 使用Yacc工具实现语法分析器。
- 定义语法规则,包括产生式和文法符号。
- 编写Yacc规则,将标记序列转换为语法分析树。
- 使用Bison生成语法分析器程序。
3. 编译器构建- 将词法分析器和语法分析器程序结合,构建简单的编译器。
- 实现编译器的中间代码生成功能。
- 实现编译器的目标代码生成功能。
五、实验结果1. 词法分析- 输入:`int a = 10;`- 输出:`TOKEN: int, TOKEN: a, TOKEN: =, TOKEN: 10, TOKEN: ;`2. 语法分析- 输入:`int a = 10;`- 输出:`Syntax Tree: Program -> Declaration -> Variable Declaration -> Identifier -> a, Token -> int, Token -> =, Token -> 10, Token -> ;`3. 编译器构建- 输入:`int a = 10;`- 输出:`Target Code: int a = 10;`六、实验心得1. 通过本次实验,我深入理解了编译原理的基本概念和原理,包括词法分析、语法分析和编译器构建。
2. 我学会了使用Lex和Yacc等编译工具,实现了简单的编译器。
3. 本次实验让我认识到编译原理在软件开发中的重要性,以及编译器在代码生成和优化方面的作用。
编译原理实验报告江苏科技大学电子信息学院2005年8月19日目录实验一:词法分析设计 (2)实验二:LL(1)预测分析 (10)实验三:逆波兰表达式的产生及计算 (26)实验四:SLR(1)语法分析设计 (48)实验五:应用DAG进行局部优化 (52)实验一词法分析设计一.实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二.实验内容用VC++/VB/JAV A语言实现对C语言子集的源程序进行词法分析。
通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。
三.实验步骤1.基于实验的内容,构造程序所需的模块2.根据已建构的模块,写出各个模块的相应程序代码3.在主函数中调用模块来完成所要得到的效果四.参考答案1.源程序'#################################################################### #########################################'####'## 存在问题:如何能较好的判断符号的优先级??##'####'#################################################################### #########################################'******************************************************************** ********************************************' 定义变量'******************************************************************** ********************************************Dim str_stack(1 To 20) As String, str_input As String, str_output As String, current As StringDim stack_p As Double, str_feihouzhui As String'******************************************************************** ********************************************' 函数定义'******************************************************************** ********************************************Private Sub chansheng()Dim i As Double, j As Double, int_length As Long, stack_top As String,temp_stack_p As DoubleDim str_temp As String, int_length2 As Long, success As Boolean, str_temp_stack(1 To 20) As StringDim msg As Doublesuccess = TrueFor i = 1 To 20str_stack(i) = ""Nextstr_input = "": str_output = "": current = ""i = 1: j = 1: stack_p = 1temp_stack_p = 0 '用于存放优先级较高的运算符的临时堆栈的指针str_input = InputBox("请输入待转换的非后缀式:", "输入非后缀式", "(a+b*c)*d", 3000, 5000) & "#"str_feihouzhui = str_inputint_length = Len(str_input)int_length2 = int_lengthgrid.Rows = 100 '初始化表格控件grid.Cols = 4grid.TextMatrix(0, 0) = "当前符号"grid.TextMatrix(0, 1) = "输入区"grid.TextMatrix(0, 2) = "符号栈"grid.TextMatrix(0, 3) = "输出区"grid.ColWidth(0) = 2100 '设置列宽grid.ColWidth(1) = 2100grid.ColWidth(2) = 2075grid.ColWidth(3) = 3100Do While (success)current = Mid(str_input, 1, 1)l0: stack_top = str_stack(stack_p)str_temp = ""Select Case currentCase "0" To "9", "a" To "z"str_output = str_output & currentint_length2 = int_length2 - 1Case "*", "/"Select Case stack_topCase ""str_stack(stack_p) = currentint_length2 = int_length2 - 1Case "*", "/", "+", "-", "("stack_p = stack_p + 1str_stack(stack_p) = currentint_length2 = int_length2 - 1End SelectCase "+", "-"Select Case stack_topCase ""str_stack(stack_p) = currentFor j = temp_stack_p To 1 Step -1If str_temp_stack(temp_stack_p) <> "" Thenstack_p = stack_p + 1str_stack(stack_p) = str_temp_stack(j)temp_stack_p = temp_stack_p - 1End IfNextint_length2 = int_length2 - 1Case "*", "/"str_output = str_output & str_stack(stack_p) '若优先级低于栈顶运算符,则弹出栈顶运算符并输出If stack_p > 1 Thenstack_p = stack_p - 1Elsestr_stack(stack_p) = ""End IfGoTo l0Case "+", "-", "("stack_p = stack_p + 1str_stack(stack_p) = currentint_length2 = int_length2 - 1For j = temp_stack_p To 1 Step -1If str_temp_stack(temp_stack_p) <> "" Thenstack_p = stack_p + 1str_stack(stack_p) = str_temp_stack(j)temp_stack_p = temp_stack_p - 1End IfNextEnd SelectCase "("Select Case stack_topCase ""str_stack(stack_p) = currentint_length2 = int_length2 - 1Case "*", "/", "+", "-", "("stack_p = stack_p + 1str_stack(stack_p) = currentint_length2 = int_length2 - 1End SelectCase ")"Select Case stack_topCase ""msg = MsgBox("错误,没有匹配的“(”。