编译原理:语义分析实验

合集下载

编译原理语法分析实验报告

编译原理语法分析实验报告

编译原理语法分析实验报告编译原理语法分析实验报告引言编译原理是计算机科学中的重要课程,它研究的是如何将高级语言转化为机器语言的过程。

语法分析是编译过程中的一个关键步骤,它负责将输入的源代码转化为抽象语法树,为后续的语义分析和代码生成提供便利。

本实验旨在通过实践,加深对语法分析的理解,并掌握常见的语法分析算法。

实验环境本次实验使用的是Python编程语言,因为Python具有简洁的语法和强大的库支持,非常适合用于编译原理的实验。

实验步骤1. 词法分析在进行语法分析之前,需要先进行词法分析,将源代码划分为一个个的词法单元。

词法分析器的实现可以使用正则表达式或有限自动机等方式。

在本实验中,我们选择使用正则表达式来进行词法分析。

2. 文法定义在进行语法分析之前,需要先定义源代码的文法。

文法是一种形式化的表示,它描述了源代码中各个语法成分之间的关系。

常见的文法表示方法有巴科斯范式(BNF)和扩展巴科斯范式(EBNF)。

在本实验中,我们选择使用BNF来表示文法。

3. 自顶向下语法分析自顶向下语法分析是一种基于产生式的语法分析方法,它从文法的起始符号开始,逐步展开产生式,直到生成目标字符串。

自顶向下语法分析的关键是选择合适的产生式进行展开。

在本实验中,我们选择使用递归下降分析法进行自顶向下语法分析。

4. 自底向上语法分析自底向上语法分析是一种基于移进-归约的语法分析方法,它从输入串的左端开始,逐步将输入符号移入分析栈,并根据产生式进行归约。

自底向上语法分析的关键是选择合适的归约规则。

在本实验中,我们选择使用LR(1)分析法进行自底向上语法分析。

实验结果经过实验,我们成功实现了自顶向下和自底向上两种语法分析算法,并对比了它们的优缺点。

自顶向下语法分析的优点是易于理解和实现,可以直接根据产生式进行展开,但缺点是对左递归和回溯的处理比较困难,而且效率较低。

自底向上语法分析的优点是可以处理任意文法,对左递归和回溯的处理较为方便,而且效率较高,但缺点是实现相对复杂,需要构建分析表和使用分析栈。

北邮 编译原理 语义分析实验报告

北邮 编译原理 语义分析实验报告

编译原理第六章语义分析目录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.实验分析和思考由于要求进行类型检查和求值,所以可以定义两个综合属性,一个记录值一个记录类型,存放在结构中,一并传入传出。

编译原理实验报告 语义分析

编译原理实验报告 语义分析

.编译原理课程实验报告实验3:语义分析. .. ...要求:对如下工作进行展开描核心数据结构的设(1Nod本程序使用了两个新的实体类,分别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图实验结果分析:. ..。

编译原理_ 语义分析_实验报告

编译原理_ 语义分析_实验报告

编译原理实验三语义分析实验报告◆学院:数学与计算机科学技术学院◆专业:计算机科学与技术◆班级:级计算机班◆小组组员:姓名:学号:姓名:学号:姓名:学号:姓名:学号:实验题目一、实验目的要求学生用与实验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) "ε" 表示空串。

编译原理实验三-自下而上语法分析及语义分析.docx

编译原理实验三-自下而上语法分析及语义分析.docx

电力学院编译原理课程实验报告实验名称:实验三自下而上语法分析及语义分析院系:计算机科学与技术学院专业年级:学生:学号:指导教师:实验日期:实验三自上而下的语法分析一、实验目的:通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。

二、实验学时:4学时。

三、实验容根据给出的简单表达式的语法构成规那么〔见五〕,编制LR分析程序,要求能对用给定的语法规那么书写的源程序进展语法分析和语义分析。

对于正确的表达式,给出表达式的值。

对于错误的表达式,给出出错位置。

四、实验方法采用LR分析法。

首先给出S-属性文法的定义〔为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。

属性文法的定义可参照书137页表6.1〕,并将其改造成用LR分析实现时的语义分析动作〔可参照书145页表6.5〕。

接下来给出LR分析表。

然后程序的具体实现:●LR分析表可用二维数组〔或其他〕实现。

●添加一个val栈作为语义分析实现的工具。

编写总控程序,实现语法分析和语义分析的过程。

注:对于整数的识别可以借助实验1。

五、文法定义简单的表达式文法如下:(1)E->E+T(2)E->E-T(3)E->T(4)T->T*F(5)T->T/F(6)T->F(7)F->(E)(8)F->i五、处理程序例和处理结果例例如1:20213191*(20213191+3191)+ 3191#六、源代码【cifa.h】//cifa.h#include<string>using namespace std;//单词构造定义struct WordType{int code;string pro;};//函数声明WordType get_w();void getch();void getBC();bool isLetter();bool isDigit();void retract();int Reserve(string str); string concat(string str); 【Table.action.h】//table_action.hclass Table_action{int row_num,line_num;int lineName[8];string tableData[16][8]; public:Table_action(){row_num=16;line_num=8;lineName[0]=30;lineName[1]=7;lineName[2]=13;lineName[3]=8;lineName[4]=14;lineName[5]=1;lineName[6]=2;lineName[7]=15;lineName[8]=0;for(int m=0;m<row_num;m++)for(int n=0;n<line_num;n++)tableData[m][n]="";tableData[0][0]="S5";tableData[0][5]="S4";tableData[1][1]="S6";tableData[1][2]="S12";tableData[1][7]="acc";tableData[2][1]="R3";tableData[2][3]="S7"; tableData[2][4]="S13"; tableData[2][6]="R3"; tableData[2][7]="R3"; tableData[3][1]="R6"; tableData[3][2]="R6"; tableData[3][3]="R6"; tableData[3][4]="R6"; tableData[3][6]="R6"; tableData[3][7]="R6"; tableData[4][0]="S5"; tableData[4][5]="S4"; tableData[5][1]="R8"; tableData[5][2]="R8"; tableData[5][3]="R8"; tableData[5][4]="R8"; tableData[5][6]="R8"; tableData[5][7]="R8"; tableData[6][0]="S5"; tableData[6][5]="S4"; tableData[7][0]="S5";tableData[8][1]="S6"; tableData[8][2]="S12"; tableData[8][6]="S11"; tableData[9][1]="R1"; tableData[9][2]="R1"; tableData[9][3]="S7"; tableData[9][4]="S13"; tableData[9][6]="R1"; tableData[9][7]="R1"; tableData[10][1]="R4"; tableData[10][2]="R4"; tableData[10][3]="R4"; tableData[10][4]="R4"; tableData[10][6]="R4"; tableData[10][7]="R4"; tableData[11][1]="R7"; tableData[11][2]="R7"; tableData[11][3]="R7"; tableData[11][4]="R7"; tableData[11][6]="R7"; tableData[11][7]="R7";tableData[12][5]="S4";tableData[13][0]="S5";tableData[13][5]="S4";tableData[14][1]="R2";tableData[14][2]="R2";tableData[14][3]="S7";tableData[14][4]="S13";tableData[14][6]="R2";tableData[14][7]="R2";tableData[15][1]="R5";tableData[15][2]="R5";tableData[15][3]="R5";tableData[15][4]="R5";tableData[15][5]="R5";tableData[15][6]="R5";tableData[15][7]="R5";}string getCell(int rowN,int lineN) {int row=rowN;int line=getLineNumber(lineN);if(row>=0&&row<row_num&&line>=0&&line<=line_num) return tableData[row][line];elsereturn"";}int getLineNumber(int lineN){for(int i=0;i<line_num;i++)if(lineName[i]==lineN)return i;return -1;}};【Table_go.h】//table_go.hclass Table_go{int row_num,line_num;//行数、列数string lineName[3];int tableData[16][3];public:Table_go(){row_num=16;line_num=3;lineName[0]="E";lineName[1]="T";lineName[2]="F";for(int m=0;m<row_num;m++)for(int n=0;n<line_num;n++)tableData[m][n]=0;tableData[0][0]=1;tableData[0][1]=2;tableData[0][2]=3;tableData[4][0]=8;tableData[4][1]=2;tableData[4][2]=3;tableData[6][1]=9;tableData[6][2]=3;tableData[7][2]=10;tableData[12][1]=14;tableData[12][2]=3;tableData[13][2]=15;}int getCell(int rowN,string lineNa){int row=rowN;int line=getLineNumber(lineNa);if(row>=0&&row<row_num&&line<=line_num) return tableData[row][line];elsereturn -1;}int getLineNumber(string lineNa){for(int i=0;i<line_num;i++)if(lineName[i]==lineNa)return i;return -1;}};【Stack_num.h】class Stack_num{int i; //栈顶标记int *data; //栈构造public:Stack_num() //构造函数{data=new int[100];i=-1;}int push(int m) //进栈操作{i++;data[i]=m;return i;}int pop() //出栈操作{i--;return data[i+1];}int getTop() //返回栈顶{return data[i];}~Stack_num() //析构函数{delete []data;}int topNumber(){return i;}void outStack(){for(int m=0;m<=i;m++)cout<<data[m];}};【Stack_str.h】class Stack_str{int i; //栈顶标记string *data; //栈构造public:Stack_str() //构造函数{data=new string[50];i=-1;}int push(string m) //进栈操作{i++;data[i]=m;return i;}int pop() //出栈操作{data[i]="";i--;return i;}string getTop() //返回栈顶{return data[i];}~Stack_str() //析构函数{delete []data;}int topNumber(){return i;}void outStack(){for(int m=0;m<=i;m++)cout<<data[m];}};【cifa.cpp】//cifa.cpp#include<iostream>#include<string>#include"cifa.h"using namespace std;//关键字表和对应的编码string codestring[10]={"main","int","if","then","else","return","void","cout","endl"}; int codebook[10]={26,21,22,23,24,25,27,28,29};//全局变量char ch;int flag=0;/*//主函数int main(){WordType word;cout<<"请输入源程序序列:";word=get_w();while(word.pro!="#")//#为自己设置的完毕标志{cout<<"("<<word.code<<","<<"“"<<word.pro<<"〞"<<")"<<endl;word=get_w();};return 0;}*/WordType get_w(){string str="";int code;WordType wordtmp;getch();//读一个字符getBC();//去掉空白符if(isLetter()){ //以字母开头while(isLetter()||isDigit()){str=concat(str);getch();}retract();code=Reserve(str);if(code==-1){wordtmp.code=0;wordtmp.pro=str;}//不是关键字else{wordtmp.code=code;wordtmp.pro=str;}//是关键字}else if(isDigit()){ //以数字开头while(isDigit()){str=concat(str);getch();}retract();wordtmp.code=30;wordtmp.pro=str;}else if(ch=='(') {wordtmp.code=1;wordtmp.pro="(";} else if(ch==')') {wordtmp.code=2;wordtmp.pro=")";}else if(ch=='{') {wordtmp.code=3;wordtmp.pro="{";} else if(ch=='}') {wordtmp.code=4;wordtmp.pro="}";} else if(ch==';') {wordtmp.code=5;wordtmp.pro=";";}else if(ch=='=') {wordtmp.code=6;wordtmp.pro="=";} else if(ch=='+') {wordtmp.code=7;wordtmp.pro="+";} else if(ch=='*') {wordtmp.code=8;wordtmp.pro="*";} else if(ch=='>') {wordtmp.code=9;wordtmp.pro=">";} else if(ch=='<') {wordtmp.code=10;wordtmp.pro="<";} else if(ch==',') {wordtmp.code=11;wordtmp.pro=",";} else if(ch=='\'') {wordtmp.code=12;wordtmp.pro="\'";} else if(ch=='-') {wordtmp.code=13;wordtmp.pro="-";} else if(ch=='/') {wordtmp.code=14;wordtmp.pro="/";} else if(ch=='#') {wordtmp.code=15;wordtmp.pro="#";} else if(ch=='|') {wordtmp.code=16;wordtmp.pro="|";}else {wordtmp.code=100;wordtmp.pro=ch;}return wordtmp;}void getch(){if(flag==0) //没有回退的字符ch=getchar();else //有回退字符,用回退字符,并设置标志flag=0;}void getBC(){while(ch==' '||ch=='\t'||ch=='\n')ch=getchar();}bool isLetter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return true;elsereturn false;}bool isDigit(){if(ch>='0'&&ch<='9')return true;elsereturn false;}string concat(string str){return str+ch;}void retract(){flag=1;}int Reserve(string str){int i;for(i=0;i<=8;i++){if(codestring[i]==str) //是某个关键字,返回对应的编码return codebook[i];}if(i==9) //不是关键字return -1;}【LR.cpp】#include<iostream>#include<string>#include<cstdlib>#include"cifa.h"#include"stack_num.h"#include"stack_str.h"#include"table_action.h"#include"table_go.h"using namespace std;void process(){int stepNum=1;int topStat;Stack_num statusSTK; //状态栈Stack_str symbolSTK; //符号栈Stack_num valueSTK; //值栈WordType word;Table_action actionTAB; //行为表Table_go goTAB; //转向表cout<<"请输入源程序,以#完毕:";word=get_w();//总控程序初始化操作symbolSTK.push("#");statusSTK.push(0);valueSTK.push(0);cout<<"步骤\t状态栈\t符号栈\t值栈\t当前词\t动作\t转向"<<endl;//分析while(1){topStat=statusSTK.getTop(); //当前状态栈顶string act=actionTAB.getCell(topStat,word.code);//根据状态栈顶和当前单词查到的动作//输出cout<<stepNum++<<"\t";statusSTK.outStack(); cout<<"\t";symbolSTK.outStack(); cout<<"\t";valueSTK.outStack(); cout<<"\t";cout<<word.pro<<"\t";//行为为“acc〞,且当前处理的单词为#,且状态栈里就两个状态//说明正常分析完毕if(act=="acc"&&word.pro=="#"&&statusSTK.topNumber()==1){cout<<act<<endl;cout<<"分析成功!"<<endl;cout<<"结果为:"<<valueSTK.getTop()<<endl;return;}//读到act表里标记为错误的单元格else if(act==""){cout<<endl<<"不是文法的句子!"<<endl;cout<<"错误的位置为单词"<<word.pro<<"附近。

编译原理实验报告语义分析

编译原理实验报告语义分析

编译原理实验报告语义分析实验名称:语义分析实验目的:1.掌握词法分析器生成的词法单元序列的构造;2.学会设计语法分析器,实现对程序的基本语法结构检查,并生成抽象语法树;3.学习语义规约的实现,实现对程序的语义分析和错误检查;4.熟悉语义分析向语法分析的接口。

实验原理:语义分析是编译过程的一个重要环节,它的主要任务是对生成的抽象语法树进行遍历,并验证程序的类型一致性、语义规则的正确性、错误的检查和恢复等。

语义分析的输入是由语法分析生成的抽象语法树,输出是继续优化的抽象语法树或中间代码,以供后续的中间代码生成等工作使用。

实验步骤:1.设计语法分析器,包括语法规则、优先级关系等;2.生成词法单元序列;3.构建语法分析器,进行语法分析,并生成抽象语法树;4.针对不同的语义规约,设计语义动作,实现对程序的语义分析和错误检查;5.完成语义分析器的构建和测试。

实验设备:1.计算机;2. 编程语言:C++/Java/Python等;3. 开发环境:Visual Studio/ Eclipse/PyCharm等。

实验结果:通过对语法分析生成的抽象语法树进行遍历,实现了对程序的语义分析和错误检查。

具体实现包括:1.类型检查:根据语义规约,对程序中的类型进行检查,包括变量的声明及使用、函数的调用、赋值语句的一致性等;2.作用域检查:检查变量的作用域和可见性等;3.错误检查:检测语义错误,如变量未声明、函数重复定义等;4.错误恢复:当检测到错误时,采取适当的错误恢复措施,如跳过错误的部分继续分析、提示错误信息等。

实验心得:本次实验主要学习了语义分析的原理和实现方法,深入了解了编译过程中各个环节的作用和关系。

通过实践操作,加深了对语法分析和语义分析的理解,提高了编程能力和解决问题的能力。

同时,实验过程中也遇到了一些挑战和困难,例如语义规约的设计和实现、错误检查和恢复等,但通过查阅资料和与同学讨论,最终解决了这些问题。

通过本次实验,我对编译原理和语义分析有了更深入的了解,并且对以后的学习和工作有了更好的准备。

编译原理语义分析实验报告

编译原理语义分析实验报告

action[5][LE].i=5; action[6][RI].ch='R'; action[6][RI].i=1; action[6][EMY].ch='R'; action[6][EMY].i=1; action[7][Z].ch='S'; action[7][Z].i=4; action[7][LE].ch='S'; action[7][LE].i=5; action[8][X].ch='R'; action[8][X].i=4; action[8][RI].ch='R'; action[8][RI].i=4; action[8][EMY].ch='R'; action[8][EMY].i=4; action[9][Z].ch='S'; action[9][Z].i=4; action[9][LE].ch='S'; action[9][LE].i=5; action[10][RI].ch='S'; action[10][RI].i=13; action[11][X].ch='S'; action[11][X].i=7; action[11][RI].ch='R'; action[11][RI].i=3; action[11][EMY].ch='R';//R! ! action[11][EMY].i=3; action[12][Y].ch='S'; action[12][Y].i=9; action[12][X].ch='R'; action[12][X].i=6; action[12][RI].ch='R'; action[12][RI].i=6; action[12][EMY].ch='R'; action[12][EMY].i=6; action[13][X].ch='R';

编译原理实验四语义分析及中间代码生成

编译原理实验四语义分析及中间代码生成

编译原理实验四语义分析及中间代码⽣成⼀、实验⽬的(1)通过上机实验,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译⽅法。

(2)掌握⽬前普遍采⽤的语义分析⽅法─语法制导翻译技术。

(3)给出 PL/0 ⽂法规范,要求在语法分析程序中添加语义处理,对于语法正确的表达式,输出其中间代码;对于语法正确的算术表达式,输出其计算值。

⼆、实验内容(1)语义分析对象重点考虑经过语法分析后已是正确的语法范畴,本实验重点是语义⼦程序。

已给 PL/0 语⾔⽂法,在实验⼆或实验三的表达式语法分析程序⾥,添加语义处理部分,输出表达式的中间代码,⽤四元式序列表⽰。

(2) PL/0 算术表达式的语义计算:PL/0 算术表达式,例如:2+35 作为输⼊。

输出: 17PL/0 表达式的中间代码表⽰:PL/0 表达式,例如: a(b+c)。

输出: (+,b,c,t1)(,a,t1,t2)三、设计思想1.原理属性⽂法:是在上下⽂⽆关⽂法的基础上为每个⽂法符号(终结符或⾮终结符)配备若⼲个相关的“值”(称为属性)。

属性:代表与⽂法符号相关的信息,和变量⼀样,可以进⾏计算和传递。

综合属性:⽤于“⾃下⽽上”传递信息。

在语法树中,⼀个结点的综合属性的值,由其⼦结点的属性值确定。

S—属性⽂法:仅仅使⽤综合属性的属性⽂法。

语义规则: 属性计算的过程即是语义处理的过程。

对于⽂法的每⼀个产⽣式配备⼀组属性的计算规则,则称为语义规则。

(1)终结符只有综合属性,它由词法分析器提供。

(2)⾮终结符既可以有综合属性也可以有继承属性,⽂法开始符号的所有继承属性作为属性计算前的初始值。

(3)产⽣式右边符号的继承属性和产⽣式左边符号的综合属性都必须提供⼀个计算规则。

(4)产⽣式左边符号的继承属性和产⽣式右边符号的综合属性由其它产⽣式的属性规则计算。

⼀遍扫描的处理⽅法: 与树遍历的属性计算⽅法不同,⼀遍扫描的处理⽅法是在语法分析的同时计算属性值,⽽不是语法分析构造语法树之后进⾏属性的计算,⽽且⽆需构造实际的语法树。

编译原理语义分析与中间代码生成实验报告

编译原理语义分析与中间代码生成实验报告

编译原理语义分析与中间代码生成实验报告专题6_语法制导翻译程序设计原理与实现技术***-***** 李若森计科1301一、实验目的语法制导的基本概念;目标代码结构分析的基本方法;赋值语句语法制导生成四元式的基本原理和方法;该过程包括语法分析和语义分析过程。

二、实验内容2.1 实验项目完成以下描述赋值语句和算术表达式文法的语法制导生成中间代码四元式的过程。

G[A]:A→V=EE→E+T|E-T|T T→T*F|T/F|F F→(E)|i V→i2.2 设计说明终结符号i为用户定义的简单变量,即标识符的定义。

2.3 设计要求(1) 设计语法制导翻译过程,给出每一产生式对应的语义动作;(2) 设计中间代码四元式的结构(暂不与符号表有关);(3) 输入串应是词法分析的输出二元式序列,即某算术表达式“专题1”的输出结果。

输出为输入串的四元式序列中间文件;(4) 设计两个测试用例(尽可能完备),并给出程序执行结果。

2.4 任务分析重点解决赋值语句文法的改写和语义动作的添加。

三、实现过程3.1 扩展文法G[s]:S→AA→V=EE→E+T|E-T|T T→T*F|T/F|F F→(E)|i V→i3.2 非终结符FOLLOW集FOLLOW(S) = { # } FOLLOW(A) = { # } FOLLOW(V) = { = }FOLLOW(E) = { +, -, ), # }FOLLOW(T) = { +, -, *, /, ), # } FOLLOW(F) = { +, -, *, /, ), # }3.3 LR(0)分析器的构造设DFA M的一个状态为i,该状态识别出的所有活前缀的有效项目集为Ci。

则DFA M的状态集Q={C0, C1, C2, … , Cn}=C。

C称为文法的LR(0)有效项目集规范族。

对Ci有三种操作:求文法的LR(0)有效项目集规范族C的算法:由上述算法可求得有效项目集规范族C={C0, C1, C2, … , C19}。

编译原理实验:语义分析实验

编译原理实验:语义分析实验

实验四:语义分析一.实验目的:通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法二.实验要求:采用的是递归下降语法制导翻译法,对算术表达式,赋值语进行语义分析并生成四元式序列。

1.实验的输入和输出分别为以下:输入是语法分析后提供的正确的单词串,输出为三地址指令形式的四元式序列。

例如:对于语句串begin a:=2+3*4;x:=(a+b)/c end #输出的三地址指令如下所示:(1)t1=3*4;(2)t2=2+t1;(3)a=t2;(4)t3=a+b;(5)t4=t3/c;(6)x=t4;2.实验算法的思想为:(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];2char *newtemp()该函数的功能是回送一个新的变量名,临时变量的名称产生的顺序依次为T1, T2 ,……..Char *newtemp(){Char *p;Char m[8];P=(char *)malloc(8);K++;Iota(k,m,10);Strcpy(p+1,m);P[0]=’t’;Return (p);}(2)主程序的示意图如图所示:(3)函数lrparser在原来语法分析的基础上插入相应的语义分析动作,将输入串翻译成四元式序列,在实验中我们仅仅所作的是对表达式和赋值语句进行翻译。

三,实验程序源码代码如下:#include "stdio.h"#include "string.h"#include "ctype.h"char token[20] ;char prog[100];char ch;char *rwtab[6]={"begin","if","then","while","do","end"};int syn,p,m,n,sum;#define STACK_SIZE 100int compute(int x,char c,int y);int stack_num[STACK_SIZE];int num_top=-1;bool notfull_num(){if(num_top==STACK_SIZE)return false;elsereturn true;}void push_num(int value){if(notfull_num()){num_top++;stack_num[num_top]=value;}}void pop_num(){num_top--;}int num_top_value(){int m=stack_num[num_top];// printf("sing=====%d\n",m);return m;}bool empty_num(){if(num_top==-1)return true;elsereturn false;}char stack_operation[STACK_SIZE]; int operation_top=-1;bool notfull_operation(){if(operation_top==STACK_SIZE) return false;elsereturn true;}void push_operation(char c){if(notfull_operation())stack_operation[++operation_top]=c; }void pop_operation(){operation_top--;}char operation_top_value(){return stack_operation[operation_top];}bool empty_operation(){if(operation_top==-1)return true ;elsereturn false;}int compute(int x,char c,int y){int m;if(c=='+')m=x+y;else if(c=='-') m=x-y;else if(c=='*') m=x*y;else if(c=='/') m=x/y;return m;}struct {int result;int ag1;char op ;int ag2;}quad[20];void scanner();int findf(char c);int findg(char c);int findf(char c){if(c=='^' ) return 7;else if(c=='*') return 5;else if(c=='/') return 5;else if(c=='+') return 3;else if(c=='-') return 3;else if(c=='$') return 0;}int findg(char c){if(c=='^') return 6;else if(c=='*') return 4;else if(c=='/') return 4;else if (c=='+') return 2;else if(c=='-') return 2;else if (c=='$') return 0;}void main(){p=0;printf("please input the string\n");int quadsign=0;do{scanf("%c",&ch); //输入所需要的文字prog[p]=ch;p++;}while(ch!='#');p=0;push_operation('$');// printf("OK\n");do{ scanner();/*case 11:printf("(11,%d)",sum);break;case -1:printf("error");break;default:printf("(%d, %s)",syn,token);break;*/if(syn==11){ push_num(sum);// printf("sum==%d\n",sum);sum=0;}else if(syn==13||syn==14||syn==15||syn==16||syn==100){if( findf(operation_top_value()) <=findg(token[0]))push_operation(token[0]);else{do{quad[quadsign].ag2=num_top_value();pop_num();// printf("%d\n",quad[quadsign].ag2);for(int i=0;i<num_top;i++)// printf("stack==%d\n",stack_num[i]);//输出的为栈中的元素quad[quadsign].op=operation_top_value();pop_operation();quad[quadsign].ag1=num_top_value();pop_num();// printf("%d\n",quad[quadsign].ag1);quad[quadsign].result=compute(quad[quadsign].ag1,quad[quadsign].op,quad[quadsig n].ag2); //compute(int x,char c,int y);push_num(quad[quadsign].result);quadsign++;}while(!empty_operation()&&findf(operation_top_value())>findg(token[0]));push_operation(token[0]);}}}while(syn!=0);for(int i=0;i<quadsign;i++)printf("%d=%d%c%d\n",quad[i].result,quad[i].ag1,quad[i].op,quad[i].ag2); }void scanner(){for(n=0;n<8;n++)token[n]=0;ch=prog[p++];while(isspace(ch))ch=prog[p++];m=0; //设置token数组为空if(isalpha(ch)){while (isalnum(ch)){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(isdigit(ch)){while(isdigit(ch)){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}elseswitch(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=20;p--;} break;case'>':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=23;p--;}break;case':':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=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;case'$':syn=100;token[0]=ch;break;default:syn=-1;}}。

编译原理语义分析实验报告

编译原理语义分析实验报告

编译原理语义分析实验报告编译原理语义分析实验报告引言编译原理是计算机科学的重要基础课程之一,它主要研究如何将高级语言转换为低级语言,使计算机能够理解和执行人类可读的代码。

语义分析是编译过程中的重要环节,它负责对代码进行语义检查和语义解释,以确保代码的正确性和可执行性。

本实验报告旨在介绍编译原理中语义分析的基本原理和实验过程。

一、实验目的本次实验的主要目的是通过实现一个简单的语义分析器,加深对编译原理中语义分析的理解。

具体来说,我们将实现以下功能:1. 识别并解析变量声明和赋值语句;2. 检查变量的重复声明和赋值类型的一致性;3. 计算并输出表达式的值。

二、实验环境和工具为了完成本次实验,我们需要准备以下环境和工具:1. 操作系统:Windows、Linux或MacOS;2. 编程语言:C++、Java或Python;3. 开发工具:编译器和调试器。

三、实验原理语义分析是编译过程中的重要环节,它主要负责对代码进行语义检查和语义解释。

在编译器中,语义分析器通常通过构建抽象语法树(AST)来实现。

AST是一种树状的数据结构,用于表示代码的语法结构和语义信息。

在语义分析的过程中,我们需要进行变量声明和赋值语句的解析和检查。

首先,我们需要识别代码中的变量声明和赋值语句,并将其转换成AST。

在解析过程中,我们需要检查变量的重复声明和赋值类型的一致性。

如果发现错误,我们需要报告相应的错误信息,并终止编译过程。

接下来,我们需要对表达式进行求值。

表达式是编程语言中的核心概念,它由操作数和运算符组成。

在求值过程中,我们需要考虑运算符的优先级和结合性。

为了实现这一功能,我们可以使用递归下降法或者使用运算符优先级算法。

四、实验过程1. 识别变量声明和赋值语句我们首先需要编写词法分析器,将代码中的字符序列转换成标记序列。

在词法分析的过程中,我们需要识别变量声明和赋值语句的关键字和标识符,并将其转换成相应的标记。

2. 构建抽象语法树在词法分析的基础上,我们可以构建抽象语法树。

编译原理语义分析报告

编译原理语义分析报告

《编译原理》实验报告专业班级_软工1502 姓名_赵翘楚_ 学号_20151107062_1.题目要求:1.1实验目的通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

1.2实验原理采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。

2.算法分析2.1主程序示意图置初值调用scaner调用lrparser输出四元组结束图12.2设置语义过程emit(char *result,char *arg1,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.3函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。

在实验中我们只对表达式、赋值语句进行翻译。

3、实验步骤#include "stdio.h"#include "string.h"#include "stdlib.h"char prog[100],token[8],ch;char*rwtab[6]={"begin","if","then","while","do"," end"};int syn,p,m,n,sum,q;int kk;struct { char result1[8];char ag11[8];char op1[8];char ag21[8];} quad[20];char *factor();char *expression();int yucu();char *term();int statement();int lrparser();char *newtemp();scaner();emit(char *result,char *ag1,char *op,char *ag2);void main(){ int j; q=p=kk=0;printf("\nplease input a string (end with '#'): ");do{ scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();if(q>19)printf(" to long sentense!\n"); elsefor(j=0;j<q;j++)printf("%s=%s%s%s\n\n", quad[j].result1,quad[j].ag11,quad[j].op1,quad[j].ag21);//getch();}int lrparser(){ int schain=0;kk=0;if (syn==1){ scaner(); //读下一个单词符号schain=yucu(); //调用语句串分析函数进行分析if(syn==6){ scaner(); //读下一个单词符号if((syn==0)&&(kk==0))printf("Success!\n"); //输出(“success”)}else { if(kk!=1)printf("short of 'end' !\n"); //输出 ‘缺end ’ 错误kk=1; // getch(); exit(0); } } else { printf("short of 'begin' !\n"); //输出’begin ’错误kk=1; // getch(); exit(0); } return (schain); } int yucu() { int schain=0; schain=statement(); //调用语句分析函数进行分析 while(syn==26) { scaner(); //读下一个单词符号 schain=statement(); //调用语句分析函数进行分析 } return (schain); } int statement() { char tt[8],eplace[8]; int schain=0; if (syn==10) { strcpy(tt,token); scaner(); if(syn==18) { scaner(); //读下一个单词符号strcpy(eplace,expression()); emit(tt,eplace,"",""); schain=0; } else { printf("short of sign ':=' !\n"); //输出’缺少赋值号’的错误kk=1; // getch(); exit(0); } return (schain); } } char *expression() { 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 分析产生表达式计算的第一项eplace while((syn==13)||(syn==14)) { if (syn==13)strcpy(tt,"+"); //操作符 tt= ‘+’或者‘—’ else strcpy(tt,"-"); scaner(); //读下一个单词符号 strcpy(ep2,term()); //调用term 分析产生表达式计算的第二项ep2 strcpy(tp,newtemp()); //调用newtemp 产生临时变量tp 存储计算结果 emit(tp,eplace,tt,ep2); //生成四元式送入四元式表 strcpy(eplace,tp); } return (eplace); } char *term() //仿照函数expression 编写 { 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==15)||(syn==16)) { if (syn==15)strcpy(tt,"*"); else strcpy(tt,"/"); scaner(); //读下一个单词符号 strcpy(ep2,factor());strcpy(tp,newtemp()); emit(tp,eplace,tt,ep2); strcpy(eplace,tp); } return (eplace);}char *factor(){ char *fplace;fplace=(char *)malloc(12);strcpy(fplace,"");if(syn==10){ strcpy(fplace,token);scaner(); //读下一个单词符号}else if(syn==11){ itoa(sum,fplace,10);scaner(); //读下一个单词符号}else if(syn==27){ scaner(); //读下一个单词符号fplace=expression(); //调用expression分析返回表达式的值if(syn==28) scaner(); //读下一个单词符号else { printf("error on ')' !\n");kk=1;// getch();exit(0);}}else { printf("error on '(' !\n");kk=1;// getch();exit(0);}return (fplace);}char *newtemp(){ char *p;char m[8];p=(char *)malloc(8);kk++;itoa(kk,m,10);strcpy(p+1,m);p[0]='t';return(p);}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;m=0;ch=prog[p++];while(ch==' ')ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>= 'A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&& (ch>='A'))||((ch>='0')&&(ch<='9'))){token[m++]=ch;ch=prog[p++];}p--;syn=10;token[m++]='\0';for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}else if((ch>='0')&&(ch<='9')){ while((ch>='0')&&(ch<='9')){ sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':m=0;ch=prog[p++];if(ch=='>'){ syn=21;}else if(ch=='='){ syn=22;}else{ syn=20;p--;}break;case '>':m=0;ch=prog[p++];if(ch=='='){ syn=24;}else{ syn=23;p--;}break;case ':':m=0;ch=prog[p++];if(ch=='='){ syn=18;}else{ syn=17;p--;}break;case '+': syn=13; break; case '-': syn=14; break;case '*': syn=15;break;case '/': syn=16;break;case '(': syn=27;break;case ')': syn=28;break;case '=': syn=25;break;case ';': syn=26;break;case '#': syn=0;break;default: syn=-1;break;}}emit(char *result,char *ag1,char *op,char *ag2){strcpy(quad[q].result1,result);strcpy(quad[q].ag11,ag1);strcpy(quad[q].op1,op);strcpy(quad[q].ag21,ag2);q++;}4、实验结果实验的输入和输出:输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。

编译原理教程实验报告

编译原理教程实验报告

一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。

二、实验内容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. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。

编译原理语义实验报告

编译原理语义实验报告

编译原理语义实验报告编译原理语义实验报告引言:编译原理是计算机科学中的重要课程之一,它研究的是如何将高级程序语言转化为机器语言,使得计算机能够理解并执行程序。

语义分析是编译过程中的重要环节,它负责对程序的语义进行分析和处理。

本实验报告将介绍我们在编译原理课程中进行的语义实验,并分享我们的实验结果和心得体会。

实验目的:本次实验的主要目的是掌握语义分析的基本原理和方法,了解如何构建语法树以及如何进行类型检查和语义规则的验证。

通过实验,我们将能够更好地理解编译器是如何对程序进行处理和优化的。

实验环境和工具:为了完成本次实验,我们使用了一些常见的编程语言和工具。

其中,我们选择了C语言作为实验的目标语言,并使用了Flex和Bison作为词法分析器和语法分析器的生成工具。

此外,我们还使用了一些辅助工具和库,如LLVM和GCC 等。

实验过程:在实验过程中,我们首先需要设计和实现一个简单的编程语言,包括其语法和语义规则。

然后,我们使用Flex和Bison来生成词法分析器和语法分析器,并通过这些工具将源代码转换为语法树。

接下来,我们对语法树进行类型检查和语义规则的验证,以确保程序的正确性和合法性。

最后,我们将生成的中间代码转化为目标代码,并进行优化和生成可执行文件。

实验结果:通过实验,我们成功地设计和实现了一个简单的编程语言,并使用Flex和Bison生成了相应的词法分析器和语法分析器。

我们还实现了类型检查和语义规则的验证,确保了程序的正确性和合法性。

最终,我们成功地将生成的中间代码转化为目标代码,并生成了可执行文件。

实验心得:通过本次实验,我们深入理解了编译原理中的语义分析过程。

我们学会了如何构建语法树,并对其进行类型检查和语义规则的验证。

我们还学会了使用一些常见的编程语言和工具,如C语言、Flex、Bison等。

通过实验,我们不仅提高了自己的编程能力,还加深了对编译原理的理解和认识。

结论:编译原理是计算机科学中的重要课程,语义分析是编译过程中的关键环节。

编译原理课程实验语义分析

编译原理课程实验语义分析

编译原理课程实验报告班级:软件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("判断句子以分号为标准。

编译原理实验三 语义分析

编译原理实验三   语义分析

编译原理实验三语法分析并进行语义分析输入:经过词法分析后形成的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语法树样例:。

编译原理语义分析实验报告 免费

编译原理语义分析实验报告 免费

编译原理综合训练语义分析实验报告指导老师:班级:学生:zeadom学号:学生:学号:2011/6/29目录语言文法的形式化描述 (3)语义规则 (3)运行环境介绍 (5)关键算法的流程图及文字解释 (5)1、本编译器的总框架 (5)2、在语义分析中的主要函数介绍 (5)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语义规则(属性文法)运行环境介绍运行环境是DEVC++Dev-C++是一个C&C++开发工具,它是一款自由软件,遵守GPL协议。

它集合了GCC、MinGW32等众多自由软件,并且可以取得最新版本的各种工具支持,而这一切工作都是来自全球的狂热者所做的工作,并且你拥有对这一切工具自由使用的权利,包括取得源代码等,前提是你也必须遵守GNU协议。

Dev-C++每一天都在进步着,因为它是一个自由软件。

语义分析实验报告

语义分析实验报告

云南大学编译原理实验报告实验题目:语义分析学院:信息学院专业:计算机科学与技术学号: 20091060064姓名:刘继远目录一、实验目的 0二、实验内容 0三、源程序分析 (2)1、程序采用的BNF (2)2、根据语义要求得到对应的翻译模式 (3)3、实现原理 (4)4、文法的属性分析 (4)5、过程设计 (5)6、子程序说明 (6)四、设计的基本思想(包括修改之后的属性文法、属性类型分析、翻译模式) (6)1、增加除法运算 (7)2、禁止同名重复声明 (8)五、结果及分析 (8)一、实验目的进一步理解递归下降分析原理和实现方法,理解语义分析的基本机制,掌握语义子程序的构造方法。

二、实验内容将带变量声明的表达式翻译为四元式序列,其中包括以下要求:非终结符号D实现定义两种类型int, real变量的声明;非终结符号S实现变量之间的*,+,: =(赋值运算)两个关键字 int 和real变量之间的*,+,: =(赋值) 运算只能使用声明过的变量,所以要检查使用的变量是否声明过。

对每个*,+,: =(赋值) 运算生成一条四元式如(*,A,B,T1),其中T1是临时变量*优先级别高于+,*满足左结合规则三、源程序分析这是一个简单的包含词法、语法、语义分析的程序:语义分析.h和语义分析.cpp。

实现的基本原理是自顶向下分析,单遍扫描,以语法分析为核心,调用词法分析,并实现语义分析。

1、程序采用的BNFP→ DS.D→B; DD→εB→int L | real LL→id | L,idS→ V := E HH→;S | εE→E+T | TT→T*F|FF→( E )F→idV→id消除左递归之后的等价文法start→ DS.D→B; DD→εB→int L | real LL→id AA→ ,idAA→εS→ V := E HH→;S | εE→T RR→+T RR→εT→F PP→* F PP→εF→( E )F→idV→id2、根据语义要求得到对应的翻译模式start→ DS.D→ B; DD→εB→ int L { L.type := int } | real L { L.type := real }L→ id { A.Type := L.type enter(v.entry, L.type)}AA→ ,idA { A1.Type := A.type enter(v.entry,A.type)}A→εS→ V := E { gen( ":=", E.place,0,V.place) } HH→;S | εE→T { R.i:=T.place} R {E.place:=R.s}R→+T { R1.i:= newtemp; gen( "+", R.i, T.place , R1.i) } R {R.s:= R1.s; }R→ ε {Rs=R.i}T→F { P.i:=F.place} P { T.place:=P.s}P→* F { p1.i:= newtemp; gen( "*", P.i, F.place , T) } P {P.s:=p1.s; }P→ε {P.s=P.i}F→( E ) { F.place := E.place}F→id {F.place:=position (id)}V→id {V.place:=position(id)}3、实现原理基于翻译模式的自上而下语义处理(翻译)1.对每个非终结符 A,构造一个函数,以 A 的每个继承属性为形参,以A的综合属性为返回值(若有多个综合属性,可返回记录类型的值)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include "stdio.h"#include "string.h"#include "stdlib.h"char prog[100],token[8],ch;char *rwtab[6]={"begin","if","then","while","do","end"};int syn,p,m,n,sum,q;int kk;struct { char result1[8];char ag11[8];char op1[8];char ag21[8];} quad[20];char *factor();char *expression();int yucu();char *term();int statement();int lrparser();char *newtemp();scaner();emit(char *result,char *ag1,char *op,char *ag2);main(){ int j;q=p=kk=0;printf("\nplease input a string (end with '#'): ");do{ scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();if(q>19)printf(" to long sentense!\n");else for (j=0;j<q;j++)printf(" %s = %s %s %s \n\n",quad[j].result1,quad[j].ag11,quad[j].op1,quad[j].ag21);//getch();system("pause");}int lrparser(){ int schain=0;kk=0;if (syn==1){ scaner();schain=yucu();if(syn==6){ scaner();if((syn==0)&&(kk==0)) printf("Success!\n"); }else { if(kk!=1)printf("short of 'end' !\n");kk=1;// getch();exit(0);}}else { printf("short of 'begin' !\n");kk=1;// getch();exit(0);}return (schain);}int yucu(){ int schain=0;schain=statement();while(syn==26){ scaner();schain=statement();}return (schain);}int statement(){ char tt[8],eplace[8];int schain=0;if (syn==10){ strcpy(tt,token);scaner();if(syn==18){ scaner();strcpy(eplace,expression());emit(tt,eplace,"","");schain=0;}else { printf("short of sign ':=' !\n");kk=1;// getch();exit(0);}return (schain);}}char *expression(){ char *tp,*ep2,*eplace,*tt;tp=(char *)malloc(12);ep2=(char *)malloc(12); eplace=(char *)malloc(12);tt=(char *)malloc(12);strcpy(eplace,term());while((syn==13)||(syn==14)) { if (syn==13)strcpy(tt,"+");else strcpy(tt,"-");scaner();strcpy(ep2,term());strcpy(tp,newtemp());emit(tp,eplace,tt,ep2);strcpy(eplace,tp);}return (eplace);}char *term(){ 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==15)||(syn==16)) { if (syn==15)strcpy(tt,"*");else strcpy(tt,"/");scaner();strcpy(ep2,factor());strcpy(tp,newtemp());emit(tp,eplace,tt,ep2);strcpy(eplace,tp);}return (eplace);}char *factor(){ char *fplace;fplace=(char *)malloc(12); strcpy(fplace,"");if(syn==10){ strcpy(fplace,token);scaner();}else if(syn==11){ itoa(sum,fplace,10);scaner();}else if(syn==27){ scaner();fplace=expression();if(syn==28) scaner();else { printf("error on ')' !\n");kk=1;// getch();exit(0);}}else { printf("error on '(' !\n");kk=1;// getch();exit(0);}return (fplace);}char *newtemp(){ char *p;char m[8];p=(char *)malloc(8);kk++;itoa(kk,m,10);strcpy(p+1,m);p[0]='t';return(p);}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;m=0;ch=prog[p++];while(ch==' ')ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}p--;syn=10;token[m++]='\0';for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}else if((ch>='0')&&(ch<='9')){ while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':m=0;ch=prog[p++];if(ch=='>'){ syn=21;}else if(ch=='='){ syn=22;}else{ syn=20;p--;}break;case '>':m=0;ch=prog[p++];if(ch=='='){ syn=24;}else{ syn=23;p--;}break;case ':':m=0;ch=prog[p++];if(ch=='='){ syn=18;}else{ syn=17;p--;}break;case '+': syn=13; break;case '-': syn=14; break;case '*': syn=15;break;case '/': syn=16;break;case '(': syn=27;break;case ')': syn=28;break;case '=': syn=25;break;case ';': syn=26;break;case '#': syn=0;break;default: syn=-1;break;}}emit(char *result,char *ag1,char *op,char *ag2) {strcpy(quad[q].result1,result);strcpy(quad[q].ag11,ag1);strcpy(quad[q].op1,op);strcpy(quad[q].ag21,ag2);q++;}。

相关文档
最新文档