编译原理实验报告 语义分析
编译原理语法分析实验报告
![编译原理语法分析实验报告](https://img.taocdn.com/s3/m/be92fb45e97101f69e3143323968011ca200f748.png)
编译原理语法分析实验报告编译原理语法分析实验报告引言编译原理是计算机科学中的重要课程,它研究的是如何将高级语言转化为机器语言的过程。
语法分析是编译过程中的一个关键步骤,它负责将输入的源代码转化为抽象语法树,为后续的语义分析和代码生成提供便利。
本实验旨在通过实践,加深对语法分析的理解,并掌握常见的语法分析算法。
实验环境本次实验使用的是Python编程语言,因为Python具有简洁的语法和强大的库支持,非常适合用于编译原理的实验。
实验步骤1. 词法分析在进行语法分析之前,需要先进行词法分析,将源代码划分为一个个的词法单元。
词法分析器的实现可以使用正则表达式或有限自动机等方式。
在本实验中,我们选择使用正则表达式来进行词法分析。
2. 文法定义在进行语法分析之前,需要先定义源代码的文法。
文法是一种形式化的表示,它描述了源代码中各个语法成分之间的关系。
常见的文法表示方法有巴科斯范式(BNF)和扩展巴科斯范式(EBNF)。
在本实验中,我们选择使用BNF来表示文法。
3. 自顶向下语法分析自顶向下语法分析是一种基于产生式的语法分析方法,它从文法的起始符号开始,逐步展开产生式,直到生成目标字符串。
自顶向下语法分析的关键是选择合适的产生式进行展开。
在本实验中,我们选择使用递归下降分析法进行自顶向下语法分析。
4. 自底向上语法分析自底向上语法分析是一种基于移进-归约的语法分析方法,它从输入串的左端开始,逐步将输入符号移入分析栈,并根据产生式进行归约。
自底向上语法分析的关键是选择合适的归约规则。
在本实验中,我们选择使用LR(1)分析法进行自底向上语法分析。
实验结果经过实验,我们成功实现了自顶向下和自底向上两种语法分析算法,并对比了它们的优缺点。
自顶向下语法分析的优点是易于理解和实现,可以直接根据产生式进行展开,但缺点是对左递归和回溯的处理比较困难,而且效率较低。
自底向上语法分析的优点是可以处理任意文法,对左递归和回溯的处理较为方便,而且效率较高,但缺点是实现相对复杂,需要构建分析表和使用分析栈。
北邮 编译原理 语义分析实验报告
![北邮 编译原理 语义分析实验报告](https://img.taocdn.com/s3/m/ff1ba665b84ae45c3b358c13.png)
编译原理第六章语义分析目录1. 实验题目和要求 (2)2. 实验分析和思考 (3)3. 翻译方案 (4)4. LR实现自底向上分析(摘自语法分析实验) (5)4.1.构造识别所有活前缀的DFA (5)5.1. 扩充分析栈 ................................................................................................................ 7 5.2. 改造分析程序 ............................................................................................................ 7 5.3. 编程实现 .................................................................................................................... 76.运行结果截图: (13)1. 实验题目和要求题目:语义分析程序的设计与实现。
实验内容:编写语义分析程序,实现对算术表达式的类型检查和求值。
要求所分析算术表达式由如下的文法产生。
numE idF F F T F T T T T E T E E |)(||/|*||→→-+→ 实验要求:用自底向上的语法制导翻译技术实现对表达式的分析和翻译。
(1) 写出满足要求的语法制导定义或翻译方案。
(2) 编写分析程序,实现对表达式的类型进行检查和求值,并输出: ① 分析过程中所有产生式。
② 识别出的表达式的类型。
③ 识别出的表达式的值。
(3) 实验方法:可以选用以下两种方法之一。
① 自己编写分析程序。
② 利用YACC 自动生成工具。
2.实验分析和思考由于要求进行类型检查和求值,所以可以定义两个综合属性,一个记录值一个记录类型,存放在结构中,一并传入传出。
编译原理实验报告
![编译原理实验报告](https://img.taocdn.com/s3/m/972c840dce84b9d528ea81c758f5f61fb736282b.png)
编译原理实验报告一、实验目的和要求本次实验旨在对PL_0语言进行功能扩充,添加新的语法特性,进一步提高编译器的功能和实用性。
具体要求如下:1.扩展PL_0语言的语法规则,添加新的语法特性;2.实现对新语法的词法分析和语法分析功能;3.对扩展语法规则进行语义分析,并生成中间代码;4.验证扩展功能的正确性。
二、实验内容1.扩展语法规则本次实验选择扩展PL_0语言的语句部分,添加新的控制语句,switch语句。
其语法规则如下:<switch_stmt> -> SWITCH <expression> CASE <case_list><default_stmt> ENDSWITCH<case_list> -> <case_stmt> , <case_stmt> <case_list><case_stmt> -> CASE <constant> : <statement><default_stmt> -> DEFAULT : <statement> ,ε2.词法分析和语法分析根据扩展的语法规则,需要对新的关键字和符号进行词法分析,识别出符号类型和记号类型。
然后进行语法分析,建立语法树。
3.语义分析在语义分析阶段,首先对switch语句的表达式进行求值,判断其类型是否为整型。
然后对case语句和default语句中的常量进行求值,判断是否与表达式的值相等。
最后将语句部分生成中间代码。
4.中间代码生成根据语法树和语义分析的结果,生成对应的中间代码。
例如,生成switch语句的跳转表,根据表达式的值选择相应的跳转目标。
5.验证功能的正确性设计一些测试用例,验证新语法的正确性和扩展功能的实用性。
三、实验步骤与结果1.扩展语法规则,更新PL_0语法分析器的词法规则和语法规则。
编译原理实验报告
![编译原理实验报告](https://img.taocdn.com/s3/m/c309b6a5d4bbfd0a79563c1ec5da50e2534dd164.png)
编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理语法分析实验报告
![编译原理语法分析实验报告](https://img.taocdn.com/s3/m/b04dec03f011f18583d049649b6648d7c0c70878.png)
编译原理语法分析实验报告第一篇:编译原理语法分析实验报告实验2:语法分析1.实验题目和要求题目:语法分析程序的设计与实现。
实验内容:编写语法分析程序,实现对算术表达式的语法分析。
要求所分析算术表达式由如下的文法产生。
E→E+T|E-T|TT→T*F|T/F|F F→id|(E)|num实验要求:在对输入表达式进行分析的过程中,输出所采用的产生式。
方法1:编写递归调用程序实现自顶向下的分析。
方法2:编写LL(1)语法分析程序,要求如下。
(1)编程实现算法4.2,为给定文法自动构造预测分析表。
(2)编程实现算法4.1,构造LL(1)预测分析程序。
方法3:编写语法分析程序实现自底向上的分析,要求如下。
(1)构造识别所有活前缀的DFA。
(2)构造LR分析表。
(3)编程实现算法4.3,构造LR分析程序。
方法4:利用YACC自动生成语法分析程序,调用LEX自动生成的词法分析程序。
实现(采用方法1)1.1.步骤:1)对文法消除左递归E→TE'E'→+TE'|-TE'|εT→FT'T'→*FT'|/FT'|εF→id|(E)|num2)画出状态转换图化简得:3)源程序在程序中I表示id N表示num1.2.例子:a)例子1 输入:I+(N*N)输出:b)例子2 输入:I-NN 输出:第二篇:编译原理实验报告编译原理实验报告报告完成日期 2018.5.30一.组内分工与贡献介绍二.系统功能概述;我们使用了自动生成系统来完成我们的实验内容。
我们设计的系统在完成了实验基本要求的前提下,进行了一部分的扩展。
增加了声明变量类型、类型赋值判定和声明的变量被引用时作用域的判断。
从而使得我们的实验结果呈现的更加清晰和易懂。
三.分系统报告;一、词法分析子系统词法的正规式:标识符(|)* 十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)* 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和分隔符 +| * | / | > | < | = |(|)| <=|>=|==;对于标识符和关键字: A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε综上正规文法为: S—〉I1|I2|I3|A4|A5 I1—〉0|A1 A1—〉B1C1|ε C1—〉E1D1|ε D1—〉E1C1|εE1—〉0|1|2|3|4|5|6|7|8|9 B1—〉1|2|3|4|5|6|7|8|9 I2—〉0A2 A2—〉0|B2 B2—〉C2D2 D2—〉F2E2|ε E2—〉F2D2|εC2—〉1|2|3|4|5|6|7 F2—〉0|1|2|3|4|5|6|7 I3—〉0xA3 A3—〉B3C3 B3—〉0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f C3—〉(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)|C3|εA4—〉+ |-| * | / | > | < | = |(|)| <=|>=|==; A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε状态图流程图:词法分析程序的主要数据结构与算法考虑到报告的整洁性和整体观感,此处我们仅展示主要的程序代码和算法,具体的全部代码将在整体的压缩包中一并呈现另外我们考虑到后续实验中,如果在bison语法树生成的时候推不出目标的产生式时,我们设计了报错提示,在这个词的位置出现错误提示,将记录切割出来的词在code.txt中保存,并记录他们的位置。
编译原理实验报告
![编译原理实验报告](https://img.taocdn.com/s3/m/7bd0e2317f21af45b307e87101f69e314332faa0.png)
编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。
本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。
二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。
此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。
三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。
在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。
首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。
然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。
在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。
对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。
(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。
在本次实验中,我们使用了递归下降的语法分析方法。
首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。
在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。
为了处理语法错误,在分析过程中添加了错误检测和处理机制。
当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。
(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。
在本次实验中,我们使用了三地址码作为中间代码的表示形式。
在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。
对于符合语义规则的语法结构,生成相应的三地址码指令。
四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。
编译原理语义分析实验报告
![编译原理语义分析实验报告](https://img.taocdn.com/s3/m/b7000e4da31614791711cc7931b765ce05087acc.png)
实验3 语义分析实验报告一、实验目的二、通过上机实习, 加深对语法制导翻译原理的理解, 掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
三、实验要求四、采用递归下降语法制导翻译法, 对算术表达式、赋值语句进行语义分析并生成四元式序列。
五、算法思想1.设置语义过程。
(1)emit(char *result,char *ag1,char *op,char *ag2)该函数的功能是生成一个三地址语句送到四元式表中。
四元式表的结构如下:struct{ char result[8];char ag1[8];char op[8];char ag2[8];}quad[20];(2) char *newtemp()该函数回送一个新的临时变量名, 临时变量名产生的顺序为T1, T2, …char *newtemp(void){ char *p;char m[8];p=(char *)malloc(8);k++;itoa(k,m,10);strcpy(p+1,m);p[0]=’t’;return(p);}六、 2.函数lrparser 在原来语法分析的基础上插入相应的语义动作: 将输入串翻译成四元式序列。
在实验中我们只对表达式、赋值语句进行翻译。
源程序代码:#include<stdio.h>#include<string.h>#include<iostream.h>#include<stdlib.h>struct{char result[12];char ag1[12];char op[12];char ag2[12];}quad;char prog[80],token[12];char ch;int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针, m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"};void scaner();char *factor(void);char *term(void);char *expression(void);int yucu();void emit(char *result,char *ag1,char *op,char *ag2);char *newtemp();int statement();int k=0;void emit(char *result,char *ag1,char *op,char *ag2){strcpy(quad.result,result);strcpy(quad.ag1,ag1);strcpy(quad.op,op);strcpy(quad.ag2,ag2);cout<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;}char *newtemp(){char *p;char m[12];p=(char *)malloc(12);k++;itoa(k,m,10);strcpy(p+1,m);p[0]='t';return (p);}void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'*':syn=13;token[0]=ch;break; case'/':syn=14;token[0]=ch;break; case'+':syn=15;token[0]=ch;break; case'-':syn=16;token[0]=ch;break; case'=':syn=25;token[0]=ch;break; case';':syn=26;token[0]=ch;break; case'(':syn=27;token[0]=ch;break; case')':syn=28;token[0]=ch;break; case'#':syn=0;token[0]=ch;break; default: syn=-1;break;}}int lrparser(){//cout<<"调用lrparser"<<endl;int schain=0;kk=0;if(syn==1){scaner();schain=yucu();if(syn==6){scaner();if(syn==0 && (kk==0))cout<<"success!"<<endl;}else{if(kk!=1)cout<<"缺end!"<<endl;kk=1;}}else{cout<<"缺begin!"<<endl;kk=1;}return(schain);}int yucu(){// cout<<"调用yucu"<<endl;int schain=0;schain=statement();while(syn==26){scaner();schain=statement();}return(schain);}int statement(){//cout<<"调用statement"<<endl;char *eplace,*tt;eplace=(char *)malloc(12);tt=(char *)malloc(12);int schain=0;switch(syn){case 10:strcpy(tt,token);scaner();if(syn==18){scaner();strcpy(eplace,expression());emit(tt,eplace,"","");schain=0;}else{cout<<"缺少赋值符!"<<endl;kk=1;}return(schain);break;}return(schain);}char *expression(void){char *tp,*ep2,*eplace,*tt;tp=(char *)malloc(12);ep2=(char *)malloc(12);eplace=(char *)malloc(12);tt =(char *)malloc(12);strcpy(eplace,term ()); //调用term分析产生表达式计算的第一项eplacewhile((syn==15)||(syn==16)){if(syn==15)strcpy(tt,"+");else strcpy(tt,"-");scaner();strcpy(ep2,term()); //调用term分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *term(void){// cout<<"调用term"<<endl;char *tp,*ep2,*eplace,*tt;tp=(char *)malloc(12);ep2=(char *)malloc(12);eplace=(char *)malloc(12);tt=(char *)malloc(12);strcpy(eplace,factor());while((syn==13)||(syn==14)){if(syn==13)strcpy(tt,"*");else strcpy(tt,"/");scaner();strcpy(ep2,factor()); //调用factor分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *factor(void){char *fplace;fplace=(char *)malloc(12);strcpy(fplace,"");if(syn==10){strcpy(fplace,token); //将标识符token的值赋给fplacescaner();}else if(syn==11){itoa(sum,fplace,10);scaner();}else if(syn==27){scaner();fplace=expression(); //调用expression分析返回表达式的值if(syn==28)scaner();else{cout<<"缺)错误!"<<endl;kk=1;}}else{cout<<"缺(错误!"<<endl;kk=1;}return(fplace);}void main(){p=0;cout<<"**********语义分析程序**********"<<endl;cout<<"Please input string:"<<endl;do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();}七、结果验证1、给定源程序begin a:=2+3*4; x:=(a+b)/c end#输出结果2、源程序begin a:=9; x:=2*3-1; b:=(a+x)/2 end#输出结果八、收获(体会)与建议通过此次实验, 让我了解到如何设计、编制并调试语义分析程序, 加深了对语法制导翻译原理的理解, 掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
编译原理_ 语义分析_实验报告
![编译原理_ 语义分析_实验报告](https://img.taocdn.com/s3/m/e4333780e53a580216fcfe35.png)
编译原理实验三语义分析实验报告◆学院:数学与计算机科学技术学院◆专业:计算机科学与技术◆班级:级计算机班◆小组组员:姓名:学号:姓名:学号:姓名:学号:姓名:学号:实验题目一、实验目的要求学生用与实验2相同的语言,编制语义分析程序。
二、实验准备微机CPU主频1.3G以上,128M内存,安装好C语言,PASCAL语言,或C++。
三、实验时间13学时四、实验内容要求学生用与实验2相同的语言,编制语义分析程序。
定义该语言的语义成分,将语义分析程序编制成子程序,在实验2分析出各语法单位后,分析其含义,并将可执行语句或表达式翻译为四元式输出,并将错误信息输出。
实验报告必须包括设计的思路,以及测试报告(输入测试例子,输出结果)。
五、上交文档1.实验报告(书面);2.程序文件(通过网络提交)。
<program> ::= <block> .<block> ::= <const-decl> <var-decl> <proc-decl> <statement><const-decl> ::= const <const-assignment-list> ; | ε<const-assignment-list> ::= <ident> = <number>| <const-assignment-list> , <ident> = <number><var-decl> ::= var <ident-list> ; |ε<ident-list> ::= <ident> | <ident-list> , <ident><proc-decl> ::= <proc-decl> procedure <ident> ; <block> ; |ε<statement> ::= <ident> := <expression>| call <ident>| begin <statement-list> end| if <condition> then <statement>| while <condition> do <statement>|ε<statement-list> ::= <statement> | <statement-list> ; <statement><condition> ::= odd <expression> | <expression> <relation> <expression><relation> ::= = | <> | < | > | <= | >=<expression> ::= <term> | <adding-operator> <term>| <expression> <adding-operator> <term><adding-operator> ::= + | -<term> ::= <factor> | <term> <multiplying-operator> <factor><multiplying-operator> ::= * | /<factor> ::= <ident> | <number> | ( <expression> )注意:(1) "ε" 表示空串。
编译原理的实验报告
![编译原理的实验报告](https://img.taocdn.com/s3/m/1521ce20a9956bec0975f46527d3240c8547a16a.png)
一、实验目的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)定义语义规则,包括类型检查、作用域检查等。
编译原理实验报告语义分析
![编译原理实验报告语义分析](https://img.taocdn.com/s3/m/a38b7371ef06eff9aef8941ea76e58fafab045c2.png)
编译原理实验报告语义分析实验名称:语义分析实验目的:1.掌握词法分析器生成的词法单元序列的构造;2.学会设计语法分析器,实现对程序的基本语法结构检查,并生成抽象语法树;3.学习语义规约的实现,实现对程序的语义分析和错误检查;4.熟悉语义分析向语法分析的接口。
实验原理:语义分析是编译过程的一个重要环节,它的主要任务是对生成的抽象语法树进行遍历,并验证程序的类型一致性、语义规则的正确性、错误的检查和恢复等。
语义分析的输入是由语法分析生成的抽象语法树,输出是继续优化的抽象语法树或中间代码,以供后续的中间代码生成等工作使用。
实验步骤:1.设计语法分析器,包括语法规则、优先级关系等;2.生成词法单元序列;3.构建语法分析器,进行语法分析,并生成抽象语法树;4.针对不同的语义规约,设计语义动作,实现对程序的语义分析和错误检查;5.完成语义分析器的构建和测试。
实验设备:1.计算机;2. 编程语言:C++/Java/Python等;3. 开发环境:Visual Studio/ Eclipse/PyCharm等。
实验结果:通过对语法分析生成的抽象语法树进行遍历,实现了对程序的语义分析和错误检查。
具体实现包括:1.类型检查:根据语义规约,对程序中的类型进行检查,包括变量的声明及使用、函数的调用、赋值语句的一致性等;2.作用域检查:检查变量的作用域和可见性等;3.错误检查:检测语义错误,如变量未声明、函数重复定义等;4.错误恢复:当检测到错误时,采取适当的错误恢复措施,如跳过错误的部分继续分析、提示错误信息等。
实验心得:本次实验主要学习了语义分析的原理和实现方法,深入了解了编译过程中各个环节的作用和关系。
通过实践操作,加深了对语法分析和语义分析的理解,提高了编程能力和解决问题的能力。
同时,实验过程中也遇到了一些挑战和困难,例如语义规约的设计和实现、错误检查和恢复等,但通过查阅资料和与同学讨论,最终解决了这些问题。
通过本次实验,我对编译原理和语义分析有了更深入的了解,并且对以后的学习和工作有了更好的准备。
编译原理实验报告-语义分析
![编译原理实验报告-语义分析](https://img.taocdn.com/s3/m/edee3b92195f312b3069a532.png)
编译原理课程实验报告实验3:语义分析图2-1本程序根据之前两个实验的结果进一步进行语义分析,主要是通过在第二个实验句法分析过程中添加语义分析功能完成的。
在代码编写之前,我将程序的功能模块分为界面及主控程序,实体类和工具类三大部分。
MyCompiler是整个程序运行的入口,是主控程序;ComplierFrame完成程序的界面,以及界面里事件的响应;Token是词法分析中词法单元的实体类;ErrorToken是错误的词法单元实体类;Symbol是句法分析中符号的实体类;Production是产生式的实体类;ErrorProduction是句法分析中产生错误的时候使用的产生式实体类;Id是标示符实体类,保存了语义分析后的标识符表;Node是语法分析树的节点类,帮助完成语法分析树的构造;LL类使用LL(1)分析法完成句法分析,同时完成语义分析;MyScanner完成了词法分析。
图2-2三、详细设计及实现得分要求:对如下工作进行展开描述(1)核心数据结构的设计本程序使用了两个新的实体类,分别是Id和Node。
Id是标识符,里面也包含了该标识符在本程序中存储的地址和长度等信息。
Id的属性如下:private String name; //名private String type;//基本类型private int offset;//起始地址private int length;//长度开始输入词法分析读入Token尝试匹配是否错误存储错误记录,处理栈顶与Token 序列是否为语义符号存储产生式,处理栈顶与Token 序列判断动作符号执行语义动作是否读到Token末尾打印结果结束分析结果以及错误报告:图4-1 标识符表:图4-2。
编译原理语义分析实验报告
![编译原理语义分析实验报告](https://img.taocdn.com/s3/m/59b5855554270722192e453610661ed9ad5155a3.png)
编译原理语义分析实验报告编译原理语义分析实验报告引言编译原理是计算机科学的重要基础课程之一,它主要研究如何将高级语言转换为低级语言,使计算机能够理解和执行人类可读的代码。
语义分析是编译过程中的重要环节,它负责对代码进行语义检查和语义解释,以确保代码的正确性和可执行性。
本实验报告旨在介绍编译原理中语义分析的基本原理和实验过程。
一、实验目的本次实验的主要目的是通过实现一个简单的语义分析器,加深对编译原理中语义分析的理解。
具体来说,我们将实现以下功能:1. 识别并解析变量声明和赋值语句;2. 检查变量的重复声明和赋值类型的一致性;3. 计算并输出表达式的值。
二、实验环境和工具为了完成本次实验,我们需要准备以下环境和工具:1. 操作系统:Windows、Linux或MacOS;2. 编程语言:C++、Java或Python;3. 开发工具:编译器和调试器。
三、实验原理语义分析是编译过程中的重要环节,它主要负责对代码进行语义检查和语义解释。
在编译器中,语义分析器通常通过构建抽象语法树(AST)来实现。
AST是一种树状的数据结构,用于表示代码的语法结构和语义信息。
在语义分析的过程中,我们需要进行变量声明和赋值语句的解析和检查。
首先,我们需要识别代码中的变量声明和赋值语句,并将其转换成AST。
在解析过程中,我们需要检查变量的重复声明和赋值类型的一致性。
如果发现错误,我们需要报告相应的错误信息,并终止编译过程。
接下来,我们需要对表达式进行求值。
表达式是编程语言中的核心概念,它由操作数和运算符组成。
在求值过程中,我们需要考虑运算符的优先级和结合性。
为了实现这一功能,我们可以使用递归下降法或者使用运算符优先级算法。
四、实验过程1. 识别变量声明和赋值语句我们首先需要编写词法分析器,将代码中的字符序列转换成标记序列。
在词法分析的过程中,我们需要识别变量声明和赋值语句的关键字和标识符,并将其转换成相应的标记。
2. 构建抽象语法树在词法分析的基础上,我们可以构建抽象语法树。
编译原理语法分析实验报告
![编译原理语法分析实验报告](https://img.taocdn.com/s3/m/96838998250c844769eae009581b6bd97e19bc63.png)
编译原理语法分析实验报告一、实验目的本实验主要目的是学习和掌握编译原理中的语法分析方法,通过实验了解和实践LR(1)分析器的实现过程,并对比不同的文法对语法分析的影响。
二、实验内容1.实现一个LR(1)的语法分析器2.使用不同的文法进行语法分析3.对比不同文法对语法分析的影响三、实验原理1.背景知识LR(1)分析器是一种自底向上(bottom-up)的语法分析方法。
它使用一个分析栈(stack)和一个输入缓冲区(input buffer)来处理输入文本,并通过移进(shift)和规约(reduce)操作进行语法分析。
2.实验步骤1)构建文法的LR(1)分析表2)读取输入文本3)初始化分析栈和输入缓冲区4)根据分析表进行移进或规约操作,直至分析过程结束四、实验过程与结果1.实验环境本实验使用Python语言进行实现,使用了语法分析库ply来辅助实验。
2.实验步骤1)构建文法的LR(1)分析表通过给定的文法,根据LR(1)分析表的构造算法,构建出分析表。
2)实现LR(1)分析器使用Python语言实现LR(1)分析器,包括读取输入文本、初始化分析栈和输入缓冲区、根据分析表进行移进或规约操作等功能。
3)使用不同的文法进行语法分析选择不同的文法对编写的LR(1)分析器进行测试,观察语法分析的结果。
3.实验结果通过不同的测试案例,实验结果表明编写的LR(1)分析器能够正确地进行语法分析,能够识别出输入文本是否符合给定文法。
五、实验分析与总结1.实验分析本实验通过实现LR(1)分析器,对不同文法进行语法分析,通过实验结果可以观察到不同文法对语法分析的影响。
2.实验总结本实验主要学习和掌握了编译原理中的语法分析方法,了解了LR(1)分析器的实现过程,并通过实验提高了对语法分析的理解。
六、实验心得通过本次实验,我深入学习了编译原理中的语法分析方法,了解了LR(1)分析器的实现过程。
在实验过程中,我遇到了一些问题,但通过查阅资料和请教老师,最终解决了问题,并完成了实验。
编译原理教程实验报告
![编译原理教程实验报告](https://img.taocdn.com/s3/m/02243a6eb80d6c85ec3a87c24028915f804d84c4.png)
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。
2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。
3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。
4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。
5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。
6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。
四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。
2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。
3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。
4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。
5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。
6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。
五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。
编译原理语义实验报告
![编译原理语义实验报告](https://img.taocdn.com/s3/m/6c806108c950ad02de80d4d8d15abe23482f0332.png)
编译原理语义实验报告编译原理语义实验报告引言:编译原理是计算机科学中的重要课程之一,它研究的是如何将高级程序语言转化为机器语言,使得计算机能够理解并执行程序。
语义分析是编译过程中的重要环节,它负责对程序的语义进行分析和处理。
本实验报告将介绍我们在编译原理课程中进行的语义实验,并分享我们的实验结果和心得体会。
实验目的:本次实验的主要目的是掌握语义分析的基本原理和方法,了解如何构建语法树以及如何进行类型检查和语义规则的验证。
通过实验,我们将能够更好地理解编译器是如何对程序进行处理和优化的。
实验环境和工具:为了完成本次实验,我们使用了一些常见的编程语言和工具。
其中,我们选择了C语言作为实验的目标语言,并使用了Flex和Bison作为词法分析器和语法分析器的生成工具。
此外,我们还使用了一些辅助工具和库,如LLVM和GCC 等。
实验过程:在实验过程中,我们首先需要设计和实现一个简单的编程语言,包括其语法和语义规则。
然后,我们使用Flex和Bison来生成词法分析器和语法分析器,并通过这些工具将源代码转换为语法树。
接下来,我们对语法树进行类型检查和语义规则的验证,以确保程序的正确性和合法性。
最后,我们将生成的中间代码转化为目标代码,并进行优化和生成可执行文件。
实验结果:通过实验,我们成功地设计和实现了一个简单的编程语言,并使用Flex和Bison生成了相应的词法分析器和语法分析器。
我们还实现了类型检查和语义规则的验证,确保了程序的正确性和合法性。
最终,我们成功地将生成的中间代码转化为目标代码,并生成了可执行文件。
实验心得:通过本次实验,我们深入理解了编译原理中的语义分析过程。
我们学会了如何构建语法树,并对其进行类型检查和语义规则的验证。
我们还学会了使用一些常见的编程语言和工具,如C语言、Flex、Bison等。
通过实验,我们不仅提高了自己的编程能力,还加深了对编译原理的理解和认识。
结论:编译原理是计算机科学中的重要课程,语义分析是编译过程中的关键环节。
编译原理课程实验语义分析
![编译原理课程实验语义分析](https://img.taocdn.com/s3/m/e7dcef36aeaad1f346933fe2.png)
编译原理课程实验报告班级:软件51学号:姓名:曹建兵提交日期:2009年3月17日联系方式:一、实验内容:实现一个《程序设计语言子集》的编译系统。
包括:词法分析,语法分析,语义分析,符号表,出错处理等语言成分:(1)数据类型:整型,布尔型;(2)简单变量;(3)算术表达式(+,×);(4)布尔表达式(∧,∨,┐);(5)语句:(6)赋值语句;(7)分支语句(if-then, if-then-else);(8)循环语句(while);(9)定义语句等。
输入方式:文本文件(如: .txt);二、实验过程:1.程序设计语言的形式化描述语法分析:S->V; | If B then V; | If B then V else V; | while B do V;| int i;| bool i;(不考虑直接表达式形式)B->┐(B)F | i F (由于要求只有布尔型常量或变量)F->∨ B | ∧ B;V->i := E (赋值语句,这里i 只能是变量) E->iT | (E) (表达式语句)T->*E | +E | ε(表达式中间状态)2.单词种别定义3.语法分析程序:package compiler;import java.util.ArrayList;import java.util.HashMap;public class GrammarAnalysis {private String SYM ;private ArrayList<Word> result ;private HashMap<Integer,String> reverse ;private int current = 0 ;private int row = 1 ;private int number = 1 ;private boolean flag = true ;private int count=0;private int NXQ=1;private ArrayList<SiYuanShi> output;private int totalVar=0;private HashMap<String,String> var;private boolean t=true;public GrammarAnalysis(ArrayList<Word> al){ result = new ArrayList<Word>();reverse = new HashMap<Integer,String>();int i;for(i=0;i<al.size();i++)if(al.get(i).getType()==0) break;if(i==al.size())result=al;else result=null;var=new HashMap<String,String>();output=new ArrayList<SiYuanShi>();output.add(new SiYuanShi(0,"-","-","-","0")); // reverse.put("1","program");// reverse.put("2","begin");// reverse.put("4","var");reverse.put(2,"true");reverse.put(3,"false");reverse.put(4,"bool");reverse.put(5,"int");reverse.put(6,"if");reverse.put(7,"then");reverse.put(8,"else");reverse.put(9,"do");reverse.put(10,"while");reverse.put(11, "identifier"); //标识符reverse.put(12, "constants"); //常量reverse.put(13,"+");//reverse.put("14","-");reverse.put(15,"(");reverse.put(16,")");reverse.put(17,"=");reverse.put(18,">");reverse.put(19,"<");reverse.put(20,";");reverse.put(21,":");reverse.put(23,",");//reverse.put("24", "/");reverse.put(24, "*");reverse.put(25, "{");reverse.put(26, "}");reverse.put(27,"∧");reverse.put(28,"∨");reverse.put(29,"┐");if(result!=null)ADVANCE();}public void run(){if(result!=null){while(current<result.size()){if(flag)P();else break;}if(t){System.out.println("生成四元式如下:");for(int i=1;i<output.size();i++)System.out.println(output.get(i).toString());System.out.println("符号表如下:");System.out.println(var.toString());}/*结果输出*/}else System.out.println("请先除去未定义符号");}private int newTemp(){count++;return count;}private int entry(String i){return 0;}private void gen(String op,String arg1 ,String arg2 ,String result){SiYuanShi a=new SiYuanShi(NXQ,op,arg1,arg2,result);//System.out.println(a.toString());output.add(a);NXQ++;}private void ADVANCE(){if(current<result.size()){SYM = reverse.get(result.get(current).getType());current ++ ;number ++ ;}}private int merge(int p1,int p2){try{int i=p2;if(p1!=0&&p2!=0){while(Integer.parseInt(output.get(i).getResult())!=0)i=Integer.parseInt(output.get(i).getResult());output.get(i).setResult(Integer.toString(p1));return p2;}}catch(Exception e){System.out.println("Error1");}return p2;}private void backpatch(int p,int m){try{int i=p;int t=0;if(p!=0){while(Integer.parseInt(output.get(i).getResult())!=0){ t=Integer.parseInt(output.get(i).getResult());output.get(i).setResult(Integer.toString(m));i=t;}output.get(i).setResult(Integer.toString(m));}}catch(Exception e){System.out.println(" Error2 ");}}private void ERROR(int i){t&=false;flag = flag & false ;System.out.println("判断句子以分号为标准。
编译原理实验三 语义分析
![编译原理实验三 语义分析](https://img.taocdn.com/s3/m/69eda50f76a20029bc642d4c.png)
编译原理实验三语法分析并进行语义分析输入:经过词法分析后形成的token[]和tokenstring[]输出:检查有无语法错误,形成语法树,并检查是否符合语义。
样例程序已经能对变量声明填符号表、进行类型检查。
文法:stmt_seq -->statement ; stmt_seq | statementstatement-->decl_stmt | assign_stmtdecl_stmt-->type var_listtype-->int |floatvar_list-->id , var_list | idassign_stmt--> id := expexp-->exp + term | exp - term |termterm--> term * factor | term * factor | factorfactor-->id | num | ( exp )要求掌握理解程序设计方法。
样例程序#include<stdio.h>#include<ctype.h>typedef enum {MINUS,PLUS,TIMES,OVER,LPAREN,RPAREN,SEMI,ASSIGN,NUM,ID,INT,FLOAT,COM MA,DOLLAR} tokentype;/*记号*/typedef enum {stmtk,expk} nodekind;typedef enum {ifk,assignk,declk} stmtkind;typedef enum {opk,constk,idk} expkind;typedef enum {integer,real} exptype;typedef struct treenode{ struct treenode * child[3];struct treenode * sibling;nodekind nodek;exptype dtype ;union { stmtkind stmt; expkind exp;} kind;union { tokentype op;int val;char * name; } attr;} treenode;typedef struct bucket{char * name; exptype dtype; struct bucket * next;} bucket;bucket * hashtable[211];/*tokentype token[6]={ID,ASSIGN,NUM,PLUS,NUM,INT,FLOAT,COMMA,DOLLAR};char tokenstring[6][30]={"ab",":=","12","+","5","$"};*/tokentype token[]={INT,ID,COMMA,ID,SEMI, ID,ASSIGN,NUM,PLUS,NUM,TIMES,NUM,SEMI,ID,ASSIGN,NUM,DOLLAR};chartokenstring[][30]={"int","ab",",","xy",";","ab",":=","12","+","5","*","3",";","xy",":=","34","$"}; int wordindex=0; /*以上两个数组的索引*/treenode * decl();treenode * factor();treenode * term();treenode * exp();treenode * assign_stmt();treenode * stmt_seq();pretraverse(treenode *);int hash ( char * );void st_insert( char * ,exptype);int st_lookup ( char * );void buildsymtab(treenode * );void setnodetype(treenode * );main(){treenode * t;t=stmt_seq(); /*语法分析建语法树*/buildsymtab(t); /*建符号表*/pretraverse(t); /*遍历语法树*/setnodetype(t); /*类型检查设置*/}treenode * stmt_seq(){treenode * t;treenode * p;if(( token[wordindex]==INT)||(token[wordindex]==FLOA T)){t=decl(); }if(token[wordindex]==ID) t=assign_stmt();p=t;while( (token[wordindex]==SEMI)&& (token[wordindex]!=DOLLAR)){treenode * q;wordindex++;q=assign_stmt();p->sibling=q;p=q;}return t;}treenode * assign_stmt(){treenode * t=(treenode *)malloc(sizeof(treenode));if(token[wordindex]==ID){t->nodek=stmtk;t->kind.stmt=assignk;t->=tokenstring[wordindex];wordindex++;}else {printf("error");exit(1);}if(token[wordindex]==ASSIGN)wordindex++;else {printf("error");exit(1);}t->child[0]=exp();t->child[1]=NULL;t->child[2]=NULL;t->sibling=NULL;return t;}treenode * exp(){treenode * t;t=term();while((token[wordindex]==PLUS)||(token[wordindex]==MINUS)) {treenode * p=(treenode *)malloc(sizeof(treenode));p->nodek=expk;p->kind.exp=opk;p->attr.op=token[wordindex];p->child[0]=t;t=p;wordindex++;t->child[1]=term();t->child[2]=NULL;t->sibling=NULL;}return t;}treenode * term(){treenode * t=factor();while((token[wordindex]==TIMES)||(token[wordindex]==OVER)) {treenode * p=(treenode *)malloc(sizeof(treenode));p->nodek=expk;p->kind.exp=opk;p->attr.op=token[wordindex];p->child[0]=t;t=p;wordindex++;t->child[1]=factor();t->child[2]=NULL;t->sibling=NULL;}return t;}treenode * factor(){treenode * t;switch(token[wordindex]){case LPAREN :wordindex++;t=exp();if(token[wordindex]==RPAREN)wordindex++;else {printf("error");exit(1);}break;case NUM :t=(treenode *)malloc(sizeof(treenode));t->nodek=expk;t->kind.exp=constk;t->attr.val=atoi(tokenstring[wordindex]);t->child[0]=NULL;t->child[1]=NULL;t->child[2]=NULL;t->sibling=NULL;wordindex++;break;case ID :t=(treenode *)malloc(sizeof(treenode));t->nodek=expk;t->kind.exp=idk;t->=tokenstring[wordindex];wordindex++;break;default:printf("error");}return t;}pretraverse(treenode * t){if (t!=NULL){ if (t->nodek==stmtk) printf("stmt-id:%s\n",t->);if (t->nodek==expk && t->kind.exp==idk) printf("exp-id:%s\n",t->);if (t->nodek==expk && t->kind.exp==opk) printf("exp-op:%d\n",t->attr.op);if (t->nodek==expk && t->kind.exp==constk) printf("exp-val:%d\n",t->attr.val);if(t->child[0]!=NULL) pretraverse(t->child[0]);if(t->child[1]!=NULL) pretraverse(t->child[1]);if(t->child[2]!=NULL) pretraverse(t->child[2]);if(t->sibling!=NULL) pretraverse(t->sibling);}}treenode * decl(){treenode * p,* q,* t1;treenode * t=(treenode *)malloc(sizeof(treenode));t->nodek=stmtk;t->kind.stmt=declk;t->=tokenstring[wordindex];t->child[1]=NULL;t->child[2]=NULL;wordindex++;if(token[wordindex]==ID){t1=(treenode *)malloc(sizeof(treenode));t->child[0]=t1;t1->nodek= expk;t1->kind.exp=idk;t1->=tokenstring[wordindex];t1->child[0]=NULL;t1->child[1]=NULL;t1->child[2]=NULL;t1->sibling=NULL;wordindex++;p=t1;while( token[wordindex]==COMMA){ wordindex++;q=(treenode *)malloc(sizeof(treenode));q->nodek= expk;q->kind.exp=idk;q->=tokenstring[wordindex];q->child[0]=NULL;q->child[1]=NULL;q->child[2]=NULL;q->sibling=NULL;p->sibling=q;wordindex++;p=q;}return t;}}int hash ( char * key ){ int temp = 0;int i = 0;while (key[i] != '\0'){ temp = ((temp << 4) + key[i]) % 211;++i;}return temp;}void st_insert( char * name,exptype datatype){ int h = hash(name);bucket * l = hashtable[h];while ((l != NULL) && (strcmp(name,l->name) != 0)) l = l->next;if (l == NULL) /* variable not yet in table */{ l = (bucket *) malloc(sizeof(bucket));l->name = name;l->dtype=datatype;l->next = NULL;l->next = hashtable[h];hashtable[h] = l; }}int st_lookup ( char * name ){ int h = hash(name);bucket * l = hashtable[h];while ((l != NULL) && (strcmp(name,l->name) != 0)) l = l->next;if (l == NULL) return -1;else return 1;}void buildsymtab(treenode * t){exptype datatype;treenode * q;if (t!=NULL){ if (t->nodek==stmtk && t->kind.stmt==declk){ if (strcmp(t->,"int")==0) datatype=integer;if(t->=="float") datatype=real;q=t->child[0];while(q!=NULL){ st_insert(q->,datatype);q=q->sibling;}}if(t->nodek!=stmtk && t->kind.stmt!=declk && t->child[0]!=NULL) buildsymtab(t->child[0]);if(t->child[1]!=NULL) buildsymtab(t->child[1]);if(t->child[2]!=NULL) buildsymtab(t->child[2]);if(t->sibling!=NULL) buildsymtab(t->sibling);}}void setnodetype(treenode * t){if(t!=NULL){if(t->child[0]!=NULL) setnodetype (t->child[0]);if(t->child[1]!=NULL) setnodetype (t->child[1]);if (t->nodek==expk && t->kind.exp==idk) {int h = hash(t->);bucket * l = hashtable[h];while ((l != NULL) && (strcmp(t->,l->name) != 0))l = l->next;if (l==NULL) {printf("no declare");exit(1);}else t->dtype=l->dtype;}if (t->nodek==expk && t->kind.exp==constk) t->dtype=integer;if (t->nodek==expk && t->kind.exp==opk) {if(t->child[1]==NULL) t->dtype=t->child[0]->dtype;elseif(t->child[0]->dtype==t->child[1]->dtype )t->dtype=t->child[0]->dtype;else {printf("type no match");exit(1);}} if (t->nodek==stmtk) t->dtype=t->child[0]->dtype;if(t->sibling!=NULL) setnodetype (t->sibling);}}查看主要内存变量:t-> t->attr.valt->child[0]-> t->child[0]->attr.valt->child[1]-> t->child[1]->attr.valt->sibling-> t->sibling->attr.val语法树样例:。
编译原理语义分析实验报告 免费
![编译原理语义分析实验报告 免费](https://img.taocdn.com/s3/m/e30f3a64ee06eff9aff80719.png)
编译原理综合训练语义分析实验报告指导老师:班级:学生:zeadom学号:学生:学号:2011/6/29目录语言文法的形式化描述 (3)语义规则 (3)运行环境介绍 (5)关键算法的流程图及文字解释 (5)1、本编译器的总框架 (5)2、在语义分析中的主要函数介绍 (6)3、产生布尔表达式 (7)4、While-do语句的语义分析 (8)5、词法、语法和语义分析的衔接 (8)测试报告 (8)附录 (12)语言文法的形式化描述(BNF式)程序开始P->program i;SDn SC;定义语句SDn->SDSDn|nullSD->var int iSDTSDT -> null|,iSDT复合语句SC->begin Sn endSn->S;Sn||null单个语句S->SD|SA|SIF|SW|SC赋值语句SA->i:=E算术表达式E->cET|iET|(E)ETET->AE|CE|DE|null;C->+|-|*|/;布尔表达式B->EAEBT|NOT B|(B)BTBT->DB|nullA->>|<|=|>=|<=|<>D->AND|ORif语句SIF->if B then S SELSESELSE->null|else S2while语句SW->while B do S语义规则(属性文法)EE1+E2EE1*E2E-E1E(E1)E iE iE i1 R i2E┐E1E( E1 )M εE E1∧ME2E E1∨ME2E E1∧ME2S if E then M S1M εN εS if E then M1 S1 N else M2 S2S.nextlist:=merge(S1.nextlist, N.nextlist, S2.nextlist) }S while M1 E do M2 S1 { backpatch(S1.nextlist, M1.quad ); Gen( j , —, —, M1.quad ); backpatch(E.truelist, M2.quad ); S.nextlist:= E.falselist }S begin L end { S.nextlist:=L.nextlist }S A { S.nextlist:= makelist() /*空链*/ }L S { L.nextlist:=S.nextlist }L L1;M S { backpatch(L1.nextlist, M.quad );L.nextlist:=S.nextlist }运行环境介绍运行环境是DEVC++Dev-C++是一个C&C++开发工具,它是一款自由软件,遵守GPL协议。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
.
编译原理课程实验报告实验3:语义分析
. .
. .
.
.
要求:对如下工作进行展开描核心数据结构的设(1
Nod本程序使用了两个新的实体类,分别I的属性I是标识符里面也包含了该标识符在本程序中存储的地址和长度等信息I下/privat String name;
/基本类privat String type/起始地privatin offset/长in length privat/该数组各维的长publi List<Integer> arr_length得/变量的维度可以根arr_length.size(
的属性如下Nod是语法生成树的节点Nod
节点/privat String nam父节/privat Node fathe/子节publi List<Node>son/属
Map<String,String>attribut publi
使用哈希表这是因为各个节点的属性不是统一的的类型是哈Ma其atrribut以方便地创建、使用属性
主要功能函数说(2
因为语义分析过程与语法分析同步进此次试验的语义分析部分并没有新的功能函数
文法符号匹配的过程中,插入语义的,代码都是在第二次第二次实验的基础上,LL(l的功能发作代码。
所以,只有句法分析函analysis(List<Token> token_list了变化,添加了语义分析的功能,其他函数功能基本与实验二相同
(3程序核心部分的程序流程图.
.
是否否
是否
是
3-1
图四、实验结果及分析得分
.
.
要求:对实验结果进行描述和分析,基本内容包括针对一测试程序输出其语义分析结果输出针对此测试程序对应的语义错误报告输出针对此测试程序经过语义分析后的符号表对实验结果进行分析注:其中的测试样例需先用已编写的词法分析程序进行处理
测试程序void main () {
double d;
int a[2][3];
d = 0;
a[0][1] = 2;
if (d == 0) {
a[0][1] = d;
}
else {
a[1][1] = 0;
}
while (a[0][1]<3) {
++a[0][1];
}
}
分析结果以及错误报告:. .
4-1 图
标识符表:
4-2
图
实验结果分析:. .
.。