编译原理上机实验
编译原理上机实习指导书解析
编译原理上机实习》指导书一、上机实习目的理解编译程序的构造原理,掌握编译程序的构造方法与技术。
通过实习,使学生既加深对编译原理基础理论的理解,又提高动手能力,特别是提高软件设计能力。
二、上机实习要求在理解编译原理基本思想的基础上,选择一个自己熟悉的程序设计语言,完成编译程序的设计和实现过程。
编译程序的设计可以采用自顶向下和自底向上两种不同的方法。
由于许多高级语言(如PASCAL C)中的语法成分都是递归定义的,所以本实验要求学生采用递归下降分析技术,这是一种自顶向下的的编译方法,其基本思想是对语言的每个(或若干个)语法成分编制一个处理子程序,从处理<程序>这个语法成分的子程序开始,在分析过程中调用一系列过程或函数,对源程序进行语法和语义分析,直到整个源程序处理完毕为止。
本上机实习是为C语言(子集)设计一个编译程序,完成词法分析、语法分析、语义分析等功能,并生成某种机器上的目标代码(汇编语言)或中间代码(四元式)。
三、上机实习步骤1.阅读《上机实习指导书》。
2.根据设计要求写算法,画程序框图3.根据框图编写编译程序4.输入编译程序并上机调试5.撰写上机实习报告四、上机实习内容1、题目:C语言小子集编译程序的实现2、C语言小子集的文法规则:<程序>::=ma in (){<分程序>}<分程序>::=< 变量说明部分>;<语句部分><变量说明部分>::=< 变量说明><标识符表><变量说明>::=int<标识符表>::=< 标识符表>,<标识符><标识符表>::=< 标识符><标识符>::=< 字母><标识符>::=< 标识符><字母><标识符>::=< 标识符><数字><语句部分>::=< 语句部分>;<语句>|<语句><语句>::= <赋值语句>|<条件语句>|<循环语句>|<赋值语句>::=< 标识符>=<表达式><条件>::=< 表达式> <关系运算符><表达式><表达式>::=< 项>|< 表达式><加法运算符><项><项>::=< 因子>|< 项> <乘法运算符><因子><因子>::= <标识符>|<常量>|(<表达式>)<常量>::= <无符号整数><无符号整数>::=< 数字序列><数字序列>::=< 数字序列><数字><数字序列>::=< 数字><加法运算符>::=+卜<乘法运算符>::=*| /<关系运算符>::=<|>|!=|>=|<=|==<复合语句>::={< 语句部分>}<语句1>::= <语句>|<复合语句><条件语句>::=if (<条件>)<语句1>else< 语句1><循环语句>::=while (<条件>)do<语句1><字母>::=a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z< 数字>::=0|1|2|3|4|5|6|7|8|93、实现功能:(1)词法分析扫描源程序,根据词法规则,识别单词,填写相应的表。
编译原理上机实验
实验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,()…说明:关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
编译原理上机实验-LL(1)语法分析-C#
编译原理上机实验报告小组成员:王金名、周攀、汪国辉、澎湃、王帅、齐娟娟、刘鸳鸳一、实验目的:了解LL(1)文法分析的基本原理;提高上机实践能力;增强团队协作能力。
二、实验内容:通过LL1文法分析表分析任意一个符号串是否为某文法的句子;显示具体分析过程;打开、新建、保存分析表;保存分析结果三、实验原理:1.C#字符串处理及数组处理,这是本实验最强有力的工具;2.LL(1)文法分析的基本原理,详见教材P80 LL(1)分析器的总控算法;3.C#文件操作,C#常用控件使用。
四、实验步骤:1.构造应用程序框架,利用内置分析表实现分析符号串的最基础功能(1)使用Visual Studio 2005 新建C#语言环境的windows应用程序LL1GAnalysis;(2)将窗体的名称改成From_Main,相应的代码名称会随之更改;(3)添加texbox控件ID为textBox_input,添加listView控件,ID为listView_Result;(4)public partial class Form_Main : Form里面编写相应代码://全局变量const int Max = 100;public string[,] staticmTable ={{"","i","+","*","(",")","#"},{"S","<error>","<error>","<error>","S::=A","S::=A","<error>"},{"A","<error>","<error>","<error>","A::=BA\'","A::=BA\'","<error>"},{"A\'","A\'::=iBA\'","<error>","A\'::=ε","<error>","<error>","A\'::=ε"},{"B","<error>","<error>","<error>","B::=CB\'","B::=CB\'","<error>"},{"B\'","B\'::=ε","B\'::=+CB\'","B\'::=ε","<error>","<error>","B\'::=ε"},{"C","<error>","<error>","<error>","C::=(","C::=)A*","<error>"} };string[] VN = new string[Max]; int VNLength;string[] VT = new string[Max]; int VTLength;//以下是分析过程中要用到的公共函数public void addTolistView_Result(string step, string stack, string input, stringproduction)//分析步骤及结果显示(向listView中添加条目,并保存到string类型变量(analysisResult)作最终保存分析结果时使用{string strResultbuf = "";strResultbuf += step.PadRight(20, ' ');strResultbuf += stack.PadRight(20, ' ');strResultbuf += input.PadRight(20, ' ');strResultbuf += production.PadRight(20, ' ') + "\r\n";analysisResult += strResultbuf;ListViewItem li = new ListViewItem();li.Text = step;ListViewItem.ListViewSubItem ls = new ListViewItem.ListViewSubItem();ls.Text = stack;li.SubItems.Add(ls);ls = new ListViewItem.ListViewSubItem();ls.Text = input;li.SubItems.Add(ls);ls = new ListViewItem.ListViewSubItem();ls.Text = production;li.SubItems.Add(ls);listView_Result.Items.Add(li);}public void GetVN(string[,] table)//从分析表中获取非终结符{int i;for ( i = 1; i < table.GetLength(0);i++ ){VN[i-1] = table[i,0];}VNLength = i;}public void GetVT(string[,] table)//从分析表中获取终结符{int i;for (i = 1; i < table.GetLength(1); i++){VT[i-1] = table[0,i];}VTLength = i;}public int isVT(string str)//判断str是不是VT中的符号{int mark = 0;for (int i = 0; i < VTLength; i++){if (VT[i] == str){mark = 1;}}return mark;}public int isVN(string str)//判断str是不是VN中的符号{int mark = 0;for (int i = 0; i < VNLength; i++){if (VN[i] == str){mark = 1;}}return mark;}public string outStack(string[] Stack, int top)//栈内符号合并输出的时候用 {string str = "";for (int i = 0; i <= top; i++){str += Stack[i];}return str;}public void removeAllItems(ListView list)//清空listview Items{int itemcount = list.Items.Count;for (int i = itemcount; i > 0 ;i-- ){list.Items.RemoveAt(0);}}public string matchInTable(string[,] mt,string stacktop, string nowstr)//查表栈顶与ch 交叉处的标志并返回{int i,j;for (i = 0; i < mt.GetLength(0); i++ ){if (mt[i,0] == stacktop){break;}}for (j = 0; j < mt.GetLength(1);j++ ){if (mt[0,j] == nowstr){break;}}if (i < mt.GetLength(0)&&j<mt.GetLongLength(1)){return mt[i,j];}else{return"error! ";}}//以下是分析过程public void Start_Analysis(string[,] mTable)//开始分析并显示分析过程{tabControl_mTable.SelectTab(tabPage_Show);ShowmTable(mTable);removeAllItems(listView_Result);listView_Result.BeginUpdate();int top = -1; int step = 0;string[] Stack = new string[Max];string str = textBox_input.Text.Trim();//初始化GetVN(mTable); GetVT(mTable);top++; Stack[top] = "#";top++; Stack[top] = VN[0];str += "#";//分析while (true){if (isVT(Stack[top]) == 1)//Stack[top]是终结符,则比较栈顶符与当前符号{if (Stack[top] == str[0].ToString())//匹配当前符号{if (Stack[top] == "#")//ok{step++;addTolistView_Result(step.ToString(), outStack(Stack, top), str, "OK!");step = 0;break;}else//同时退栈{step++;addTolistView_Result(step.ToString(), outStack(Stack, top), str, ""); top--;str = str.Remove(0, 1);}}else//错误{step++;addTolistView_Result(step.ToString(), outStack(Stack, top), str,"Error!");break;}}else if (isVN(Stack[top]) == 1)//Stack[top]是非终结符,则查表{string production = matchInTable(mTable, Stack[top], str[0].ToString());if (production != "<error>"){step++;addTolistView_Result(step.ToString(), outStack(Stack, top), str, production);string probuf = "";if (production[1] == '\''){probuf = production.Remove(0, 5);}else{probuf = production.Remove(0, 4);}char[] chbuf = probuf.ToCharArray();int i = chbuf.Length - 1;string strbuf = "";Stack[top] = null;top--;while (i >= 0){if (chbuf[i] != 'ε'){if (chbuf[i] != '\''){top++;Stack[top] = strbuf.Insert(0, chbuf[i].ToString());strbuf = "";}else if (chbuf[i] == '\''){strbuf += strbuf.Insert(0, chbuf[i].ToString());}}else { break; }i--;}}else//错误production.Length != 0不在分析表中{step++;addTolistView_Result(step.ToString(), outStack(Stack, top), str, "Error!");break;}}else//错误非法字符{step++;addTolistView_Result(step.ToString(), "错误", str, "非法字符:" +str[0].ToString());break;}}//分析结束listView_Result.EndUpdate();}private void button_Start_Click(object sender, EventArgs e)//菜单及按钮开始分析(菜单项及开始按钮公用函数){string[,] mTable;if (radioButton_Staticmt.Checked){mTable = staticmTable;ShowmTable(mTable);Start_Analysis(mTable);}else if (radioButton_Createmt.Checked){if (created == 1){mTable = creamTable;ShowmTable(mTable);Start_Analysis(mTable);}else{MessageBox.Show("你还没有创建分析表,请先创建!", "错误提示",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}else if (radioButton_Openmt.Checked){if (opened == 1){mTable = openmTable;ShowmTable(mTable);Start_Analysis(mTable);}else{MessageBox.Show("你还没有打开分析表,请先打开或创建!", "错误提示",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}}2.实现显示分析表及新建分析表并利用该表分析句子的功能(1)添加tabControl控件ID为tabControl_mTable建立3个页面tabPage_Show显示当前分析表、tabPage_Edit新建分析表、tabPage_Open打开分析表(2)tabPage_Show中添加listView控件ID为listView_mtableshow用于显示分析表(3)tabPage_Edit中添加两个Button 控件ID分别为button_StartAdd开始添加、button_FilishAdd 完成添加;两个textBox控件ID分别为textBox_VT 、textBox_VN、分别用于获取要添加的终结符及非终结符个数;一个tableLayoutPanel控件ID为tableLayoutPanel_mTable用于根据用户输入的VT及VN的个数建立输入表(4)编辑相应代码:private void button_StartAdd_Click(object sender, EventArgs e)//新建分析表并开始输入{try{int conwidth,conheight,col, row;TextBox txb;tableLayoutPanel_mTable.Controls.Clear();conwidth = 50; conheight = 20;col = Convert.ToInt32(textBox_VT.Text)+1;row = Convert.ToInt32(textBox_VN.Text)+1;tableLayoutPanel_mTable.ColumnCount =col;tableLayoutPanel_mTable.RowCount = row;for (int i = 0; i < col;i++ ){for (int j = 0; j < row;j++ ){if (i == 0&&j==0){Label lb = new Label();lb.Text = "VN\\VT";lb.Width = conwidth;lb.ForeColor = Color.Red;tableLayoutPanel_mTable.Controls.Add(lb,i,j);}else{txb = new TextBox();txb.Width = conwidth;txb.Height = conheight;tableLayoutPanel_mTable.Controls.Add(txb,i,j);}}}}catch{MessageBox.Show("终结符或非终结符格式不对!\n请输入数字!","错误提示",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}private void button_FilishAdd_Click(object sender, EventArgs e)//完成添加,更新分析表 {int col = tableLayoutPanel_mTable.ColumnCount;int row = tableLayoutPanel_mTable.RowCount;if (col > 1&&row>1){creamTable = new string[row, col];for (int i = 0; i < row; i++){for (int j = 0; j < row; j++){if (i == 0 && j == 0){creamTable[i, j] = "";}else{creamTable[i, j] =((TextBox)tableLayoutPanel_mTable.GetControlFromPosition(j, i)).Text.Trim();if (creamTable[i,j].Length == 0){creamTable[i, j] = "<error>";}}}}MessageBox.Show("成功更新分析表!");tabControl_mTable.SelectTab(tabPage_Show);radioButton_Createmt.Checked = true;created = 1;ShowmTable(creamTable);}else{MessageBox.Show("请先点击“开始添加”创建表格!","错误提示",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}public void ShowmTable(string[,] mTable)//显示分析表{listView_mtableshow.Clear();ColumnHeader colHeader;ListViewItem lvi;ListViewItem.ListViewSubItem lvsi;for (int i = 1; i <= mTable.GetLength(1); i++){colHeader = new ColumnHeader();colHeader.Text = i.ToString();listView_mtableshow.Columns.Add(colHeader);}for (int i = 0; i < mTable.GetLength(0); i++){lvi = new ListViewItem();lvi.Text = mTable[i, 0];for (int j = 1; j < mTable.GetLength(1); j++){lvsi = new ListViewItem.ListViewSubItem();lvsi.Text = mTable[i, j];lvi.SubItems.Add(lvsi);}listView_mtableshow.Items.Add(lvi);}}private void miFileNew_Click(object sender, EventArgs e)//菜单新建分析表{tabControl_mTable.SelectTab(tabPage_Edit);}3.实现打开、保存分析表、保存分析结果的功能(1)添加主菜单menuStrip_Main两个Item:miFile文件、miGraAnylysis语法分析。
编译原理实验报告(C语言)
编译原理实验报告实验项目1:词法分析程序实验一、实验的目的与任务:编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。
设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现方法,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。
编译原理是一门理论性和实践性都比较强的课程。
进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。
同时培养学生实际动手能力。
编译实验由三个独立实验组成,按照由浅入深进行排列,希望通过本实验使学生更深学习并理解编译的主要过程和相关方法。
词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。
基本符号是与输入的语言定义的词法所规定的终结符。
本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续进行)二、题目分析1.这里采用C语言编写的源程序作为词法分析程序的输入数据,输入数据保存在“in.txt”记事本中,将分析结果存在“out.txt”记事本中。
词法分析器的源代码使用C语言编写。
2.下面就词法分析程序中的主要变量进行说明:主函数main():打开要分析的C语言源程序,若不能正确打开,则报错。
先从源程序中读入一个字符ch,然后进行如下处理:1、cp消耗掉空格,制表符,换行符后,cp数组复位,开始检测cp;2、数字检测,对照符号表输出,若匹配成功,则返回序号;3、字符串检测, 对照符号表输出,若匹配成功,则返回序号;4、基本保留字检测,对照符号表输出,若匹配成功,则返回序号;5、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是否跟着是注释语句。
《编译原理》词法分析实验报告模板-课程上机
实验报告课程名称编译原理实验项目设计与实现一个词法编译器班级姓名学号实验名称设计与实现一个词法实验地点实验时间编译器1.实验目的:结合讲授内容,设计与实现一个简单词法编译器,通过本实验加深对词法分析程序的功能及实现方法的理解。
设计与实现一个简单词法编译器。
具体内容是对输入的语句进行分析,分解出关键字3. 实验要求:(1)掌握和实现词法分析器的功能:输入源程序,输出单词符号(二元式表示)。
输入输出(2)单词符号的分类:关键字:是由程序语言定义的具有固定意义的标识符。
标识符:用来表示各种名字,如变量等。
常数:常数的类型有整型,实型等。
运算符:算术运算符,关系运算符,逻辑运算符。
界限符:逗号,分号等。
(3)实验步骤:1、确定词法分析器的接口关系;2、设计算法参考教材图2.5。
4. 实验准备: 1:pc 机一台; 2:VC++编译器词法分析器 源程序 (字符流)二元式 (单词流)1,分析问题输入源程序,输出单词符号(二元式表示)。
输入 输出2,算法步骤::将文件中每行读入的字符串存入数组buffer[100],不跳过空格; :利用构造函数传递数组,和每行的长度length ;:调用成员函数scan ,i=0, while(i<length)开始检测buffer 的字符;:if(isletter(),接收完成后比较是否为关键字,不是则将其存入标示符id[50][10]中 ; :else if(isdigit()),接收完成后存入cst[50][10]中;:else if 为界符,比较符,运算符,输出对应的二元编码;:接受完毕,输出id[50][10]--标示符,cst[50][10]--常数,列表; 3:程序代码#include<stdio.h> #include<stdlib.h> #include<string.h>#define _KEY_WORD_END "#"//结束标志 typedef struct {int typenum;//种别码 char* word;//单词 }WORD;char input[1001]; char token[100]="";int p_input;//输入缓冲区指针 int p_token;//单词缓冲区指针char *rwtab[]={"begin","if","then","while","do","end",_KEY_WORD_END};//关键字列表,可扩充 char ch;//获取一个字符char m_getchar()//在缓冲区获取一个字符 {ch = input[p_input]; p_input ++; return ch;}void getbc()//去除空白符号 {while(ch ==' '||ch == '\n') {词法分析器 源程序(字符流) 二元式(单词流)ch = input[p_input];p_input ++;}}int letter()//判断字符是不是字母{if(ch >='a'&&ch<='z' || ch>='A'&&ch<='Z')return 1;return 0;}int digit()//判断字符是不是数字{if(ch>='0'&&ch<='9')return 1;return 0;}void concat()//组装单词{token[p_token] = ch;p_token ++;token[p_token] = '\0';}void retract()//缓冲区回退一个字符{p_input --;}int reserve()//与关键字表对比,查看是否是关键字{int i =0;while(strcmp(rwtab[i],_KEY_WORD_END)){if(!strcmp(rwtab[i],token)){return i+1;}i ++;}return 10;}WORD* scaner()//获取一个单词,并判断它的特别码{WORD * myword = new WORD;myword->typenum = 10;p_token = 0;//单词指针初始化m_getchar();//获取一个字符getbc();//去除空白if(letter())//判断是否为字母{while(letter()||digit()){concat();//单词组装m_getchar();//获取字符}retract();myword->word = token;//存入输出结构体myword->typenum = reserve();//判断单词的特别码,并存入结构体return myword;}else if(digit()){while(digit()){concat();m_getchar();}retract();myword->word = token;//存入输出结构体myword->typenum = 11;return myword;}else switch(ch){case ':':m_getchar();if(ch == '='){myword->typenum = 18;myword->word = ":=";}else{retract();myword->typenum = 17;myword->word = ":";}return myword;case '+':myword->word = "+"; return myword;case '-':myword->typenum = 14; myword->word = "-"; return myword;case '*':myword->typenum = 15; myword->word = "*"; return myword;case '/':myword->typenum = 16; myword->word = "/"; return myword;case '<':m_getchar();if(ch == '='){myword->typenum = 22; myword->word ="<="; }else if(ch == '>'){myword->typenum = 21; myword->word ="<>"; }else{retract();myword->typenum = 20; myword->word = "<"; }return myword;case '>':m_getchar();if(ch == '='){myword->typenum = 24; myword->word =">="; }else{retract();myword->word = ">";}return myword;case '=':myword->typenum = 25;myword->word ="=";return myword;case ';':myword->typenum = 26;myword->word =";";return myword;case '(':myword->typenum = 27;myword->word ="(";return myword;case ')':myword->typenum = 28;myword->word =")";return myword;case '\0'://字符串结束标志myword->typenum = 1000;myword->word ="OVER";return myword;default://不符合的词法myword->typenum = -1;myword->word ="ERROR";return myword;}}int main(){WORD* oneword = new WORD;int over = 1;printf("Enter Y our words(end with #):\n");while(scanf("%[^#]s",input),strcmp(input,"end the program"))//读入源程序字符串到缓冲区{getchar();p_input = 0;//输入缓冲区指针初始化while(over !=1000)//单词不是\0{oneword =scaner();if(over<1000)//\0不用输出printf("(%d,%s)",over,oneword->word);}over=1;printf("(0,#)");printf("\nEnter Y our words(end with #):\n"); printf("结束程序,输入 end the program#\n "); }return 0;}5:程序运行结果6:校验试验结果正确。
编译原理上机实验程序
程序源代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<ctype.h>#define LEN sizeof(struct Node)struct Node{char data;struct Node *next;};struct Node *head,*p;char ch;char *key[7]={"main","int","char","if","else","for","while"}; char token[20];void getch(){ch=p->data;p=p->next;}void output(struct Node *head){if(!head){printf("Something wrong with head node!");exit(1);}p=head->next;while(p->next!=NULL){printf("%c",p->data);p=p->next;}printf("\n");}void getbc(){while(ch=='')getch();}void concat(){unsigned int i;i=strlen(token);token[i]=ch;token[i+1]='\0';}int letter(char ch){return isalpha((int)ch);}int digit(char ch){return isdigit((int)ch);}int reserve(){int k;for(k=0;k<7;k++){if(strcmp(key[k],token)==0)return(k+1);}return 10;}void retract(){struct Node *Q;Q=head->next;while(Q->next!=p)Q=Q->next;p=Q;}void back(int a,char *b){printf("(%d,%s)\n",a,b);}void scaner(){int c;token[0]=NULL;getch();getbc();if(letter(ch)){while(letter(ch)||digit(ch)){concat();getch();}retract();c=reserve();if(c!=10)back(c,token);elseback(10,token);}else if(digit(ch)){while(digit(ch)){ concat();getch();}retract();printf("(20,%d)\n",atoi(token)); }elseswitch(ch){case'+':back(22,"+");break;case'-':back(23,"-");break;case'*':back(24,"*");break;case'/':back(25,"/");break;case'(':back(26,"(");break;case')':back(27,")");break;case'{':back(28,"{");break;case'}':back(29,"}");break;case',':back(30,",");break;case';':back(31,":");break;case':':back(32,":");break;case'=':getch();if(ch=='=')back(37,"==");else{retract();back(21,"=");}break;case'>':getch();if(ch=='=')back(35,">=");else{retract();back(33,">");}break;case'<':getch();if(ch=='=')back(36,"<=");else{retract();back(34,"<");}break;case'!':getch();if(ch=='=')back(38,"!=");break;case'`':getch();if(ch=='`')back(39,"``");else{if(ch=='')back(100,"`");}break;case'#':break;default:break;}}int main(void){head=(struct Node *)malloc(LEN);if(!head){printf("Failed to create the head node!");exit(1);}head->next=NULL;head->data='';p=head;printf("Please input your code:\n");while(1){int i=0;char tmp[256];gets(tmp);if(tmp[0]=='#')break;p->next=(struct Node *)malloc(LEN);if(!(head->next)){printf("Failed to create a new node!");exit(1);}p=p->next;while((tmp[i]!='\0')&&(i<256)){p->data=tmp[i];p->next=(struct Node *)malloc(LEN);if(!(p->next)){printf("Failed to create a new node!");exit(1);}p=p->next;i++;}p->data='\n';p->next=NULL;}printf("\nThe code you input is:\n");output(head);printf("\nAfter compiling,the result is:\n");p=head->next;while(p->next!=NULL)scaner();system("Pause");return 0;}。
编译原理语义分析实验报告
实验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#输出结果八、收获(体会)与建议通过此次实验, 让我了解到如何设计、编制并调试语义分析程序, 加深了对语法制导翻译原理的理解, 掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
上海大学 编译原理上机实习
(4) 在题 在题(3)的语法分析器中加入语义处理,对于语法正确的 的语法分析器中加入语义处理, 的语法分析器中加入语义处理 算术表达式,输出其计算值。 算术表达式,输出其计算值。 例:输入 2 + 3 * 5 输出 17 (5) 在题 在题(3)的语法分析器中加入语义处理,对于语法正确的 的语法分析器中加入语义处理, 的语法分析器中加入语义处理 表达式,输出其中间代码(四元式序列)。 表达式,输出其中间代码(四元式序列)。 例:输入 a+b*c ( + a t1 t2 ) 输出 ( * b c t1 )
(number , 15 )
(2)构造 )构造PL/0语言的表达式部分的语法分析器 语言的表达式部分的语法分析器 要求:处理为独立一遍,采用递归子程序法。 要求:处理为独立一遍,采用递归子程序法。 表达式, 输入 PL/0表达式,形式为题(1)的输出。 表达式 形式为题( )的输出。 输出 对于语法正确的表达式,报告“语法正确”; 对于语法正确的表达式,报告“语法正确” 对于语法错误的表达式,报告“语法错误” 对于语法错误的表达式,报告“语法错误”, 指出错误原因。 指出错误原因。
编译原理上机实习报告
1. 每个实习小组交一份报告; 每个实习小组交一份报告; 2.对每一小题: 对每一小题: 对每一小题 1)题目 ) 2)设计思想 ) 3) 算法 ) 4) 调试数据(输入 输出) ) 调试数据(输入/输出 输出) 3. 小结部分: 小结部分: 1)组内成员分工 ) 2)心得体会 ) 3)其它 ) 4. 各题算法的重复部分可省略
词法分析器与题(2)语法分析器之间的 (3)把题 词法分析器与题 语法分析器之间的 )把题(1)词法分析器与题 衔接方式由独立一遍改为独立子程序。 衔接方式由独立一遍改为独立子程序。 表达式, 输入 PL/0表达式,形式为源程序。 表达式 形式为源程序。 对于语法正确的表达式,报告“语法正确” 输出 对于语法正确的表达式,报告“语法正确”; 对于语法错误的表达式,报告“语法错误” 对于语法错误的表达式,报告“语法错误”,并指 出错误原因。 出错时间 第 周至第 周 每周 第 -第 节课 第 地点:行健楼六楼机房 地点 行健楼六楼机房 分组: 每个实习小组3位成员 位成员,自由组 分组 每个实习小组 位成员 自由组 合
编译原理实验报告1
03091337 李璐 03091339 宗婷婷一、上机题目:实现一个简单语言(CPL)的编译器(解释器)二、功能要求:接收以CPL编写的程序,对其进行词法分析、语法分析、语法制导翻译等,然后能够正确的执行程序。
三、试验目的1.加深编译原理基础知识的理解:词法分析、语法分析、语法制导翻译等2.加深相关基础知识的理解:数据结构、操作系统等3.提高编程能力4.锻炼独立思考和解决问题的能力四、题目说明1.数据类型:整型变量(常量),布尔变量(常量)取值范围{…, -2, -1, 0, 1, 2, …}, {true, false}2、运算表达式:简单的代数运算,布尔运算3、程序语句:赋值表达式,顺序语句,if-else语句,while语句五、环境配置1.安装Parser Generator、Visual C++;2.分别配置Parser Generator、Visual C++;3.使用Parser Generator创建一个工程编写l文件mylexer.l;编译mylexer.l,生成mylexer.h与mylexer.c;4.使用VC++创建Win32 Console Application工程并配置该项目;加入mylexer.h与mylexer.c,编译工程;执行标识符数字识别器;注意:每次修改l文件后,需要重新编译l文件,再重新编译VC工程六、设计思路及过程设计流程:词法分析LEX的此法分析部分主要利用有限状态机进行单词的识别,在分析该部分之前,首先应该对YACC的预定义文法进行解释。
在YACC中用%union扩充了yystype的内容,使其可以处理char型,int型,node型,其中Node即为定义的树形结点,其定义如下:typedef enum { TYPE_CONTENT, TYPE_INDEX, TYPE_OP } NodeEnum;/* 操作符 */typedef struct {int name; /* 操作符名称 */int num; /* 操作元个数 */struct NodeTag * node[1]; /* 操作元地址可扩展 */} OpNode;typedef struct NodeTag {NodeEnum type; /* 树结点类型 *//* Union 必须是最后一个成员 */union {int content; /* 内容 */int index; /* 索引 */OpNode op; /* 操作符对象 */};} Node;extern int Var[26];结点可以是三种类型(CONTENT,INDEX,OP)。
编译原理上机报告
编译原理上机报告⼀.实验⽬的通过设计并完成⼀个简单的”函数图形绘制程序”,使同学基本上学会编译技术中的词法分析器,语法分析器的构造⽅法,并初步掌握语法制导翻译技术,使同学对编译器的构造⽅法以及编译过程有清楚的感性认识..⼆.实验任务语⾔的⾮形式描述,语⾔的描述包括语法和语义两个部分,此处采⽤⾮形式化的描述,.上机实验包括词法分析和语法分析以及语义分析,分别实现戏词法分析器,语法分析器和图形绘制的设计编码与调试。
三.模块的划分和模块间关系此部分主要由三部分组成:词法分析,语法分析和语义分析。
1.词法分析词法分析器⾄少完成两个任务:〈1〉滤掉注释和⽆⽤成分。
〈2〉数别记号供语法分析器使⽤(1)与语法分析器的接⼝:名称:InitScanner 功能:初始化词法分析器参数:被分析的输⼊⽂件名返回值:成功/失败(1/0)名称:GetToken 功能:取得⼀个记号参数:⽆返回值:记号的种别名称:CloseScanner 功能:关闭词法分析器参数:⽆其框图如下:(2)记号的设计为了区分记号,把程序中所能出现的记号名,函数名,常量名,参数名,保留字都包含在⼀个数组中,数组中的成员都是CToken的对象。
其定义如下:2(3)与实现有关的问题A.字符输⼊缓冲区在设计的语⾔中,最多只预读⼀个字符,假设输⼊⽂件为InFile,,则Char=getc(InFile) //完成读字符ungetc(Char,InFile) //完成回退字符B.模式识别记号按如下⽅法分类:〈1〉标⽰符⼀个模式,包括保留字,函数名,T及Pi,E〈2〉常数字⾯量⼀个模式〈3〉其它符号每种⼀个模式C.词法分析器的调试词法分析器的主代码如下:#include"scanner.h"void main(int argc,char*argv[]){Token token;if(argc<2){printf("please input Source File!\n");return;}if(!InitScanner(argv[1])) //初始化词法分析器{printf("Open Source File Error!\n"); return;}printf("记号类型字符串常数值函数指针\n");printf("_________________________________________________________\n");while(1){token=GetToken(); //获得记号if(token.type!=NONTOKEN) //打印记号的内容printf("%4d,%12s,%12f,%12x\n",token.type,token.lexeme,token.value,token.FuncPtr);else break;};printf("___________________________________________________________\n");CloseScanner();}如有绘图语句如下:scale is(100, 100);for t from 0 to 2*pi step pi/300经词法分析器编译可得结果如下:2语法分析器词法分析与语法分析的区别之⼀是,词法分析是线性的,⽽语法分析是⾮线性的。
编译原理上机报告 target=blank
编译原理上机报告target=blank编译原理上机报告学号: 9761072姓名:褚瑞一.实习目的:通过上机实习加深对编译原理的理解和熟悉编译程序的构造方法。
二.实习方法:出于熟悉编译原理的目的,我用C语言重写了整个程序,由于工作量的原因,没有设计新的程序结构和虚拟机指令等等,全部编译程序源代码包括下列文件:symbol.cpp 用于词法分析declaration.cpp 用于语法分析的声明部分expression.cpp 用于语法分析的表达式处理部分semantic.cpp 用于语法分析的其它部分objcode.cpp 用于生成代码error.cpp 用于错误处理main.cpp 主程序另外,interpret目录下有interpret.cpp和main.cpp,用于编译成为一个虚拟机的解释程序。
全部源代码在Windows 2000 Professional,Visual C++ 6.0以及Red Hat 7.0下编译调试通过。
使用标准C语言编写,从而能在Linux下运行,是我的程序的一个特色。
三.测试程序为了测试所有可能的代码,我编写了下面的测试PL程序。
这个程序可以编译,但是运行起来是没有意义的,它仅仅是为了包括常量,变量,数组等类型,并且包括比较复杂的表达式处理和几乎所有支持的语句,以便对编译程序进行测试。
program pp;const PI=3 testconst='z' testconst1=TRUEtype testtype=BOOLEAN testarray=array[2..20,0..50] of booleanvar n,p:integer cr:charprocedure p1(n:integer;var p:integer);var in_proc:char cr1:testarraybegincr1(2,3):=cr1(n,cr1(n,p))+ p;in_proc:=2+p*(testconst+1);if n<=1 thenwhile testconst1 do n:=PIelseif p>1 thenbeginp:=n*p;n:=p/n;end;call p1(n,cr1(2,5));end;begincall read(n);call p1(n,p);call write(p)end.为了测试运行的情况,我们编写一个稍稍简单的例子,这是参考教材中求阶乘的源程序:program pp;var n,p:integerprocedure p1(n:integer;var p:integer);var in_proc:charbeginif n<=1 then p:=1elsebegincall p1(n-1,p);p:=n*pendend;begincall read(n);call p1(n,p);call write(p)end.四.编译结果采用编译程序对这两个PL源程序进行编译。
《编译原理上机实验指导》
《编译原理上机实验指导》实验一词法分析1 实验目的设计编制并调试一个词法分析程序,加深对构造词法分析器的原理和技术理解与应用。
2 实验要求选择一种计算机高级程序语言子语言,运用恰当的词法分析技术线路,设计和实现其子语言的词法分析器。
语言选择,建议为《计算机程序设计》课程所采用的语言。
技术线路建议如下两种之一:正则式→NFA→DFA→min DFA→程序设计和正则文法→NFA →DFA→min DFA→程序设计。
分析器输出结果存入到磁盘文件中。
具有出错处理功能。
选择子语言方法举例。
以教材选取的PASCAL语言为例,确定其子语言涉及的单词类如下:(1)关键字begin end if then while do(2)运算符和界符:= +-* /< <= <> > >= = ; ( ) :#(3)标识符正则式:ID=letter(letter|digit)*(4)整型常数正则式:NUM= digit(digit)*3 算法设计(1)单词种别码设计(2)输出形式设计词法分析器的输入是源程序字符串,输出是对应的单词串。
每个单词按照二元组(种别码,单词符号本身)格式输出。
例如:假设源程序为begin x:=9; if x>0 then x:=2*x+1/3;end #,则词法分析器对应输出的结果是:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)(10,x)(23,>)(11,0)(3,then)(10,x)(18,:=)(11,2)(15, *)(10,x)(13, +)(11,1)(16,/)(11,3)(26,;)(6,end)(0,#)(3)算法思想依据建立的识别单词的DFA,设计算法,其框架如下。
其中,①syn存放单词的种别码;②token存放符合标识符规则的单词;③sum存放整型常量的单词。
实现技术细节注意的几个要点:A)标识符和关键字,属于同一构词规则,识别方法是建立一个关键字表,在识别出标识符单词时,查关键字表,以确认或区别是否是关键字,还是标识符。
编译原理第一次上机实验报告软工_李_U2014172xx
编译原理第一次上机实验报告姓名:李x班级:软工140x班学号:U2014172xx实验一设计实现简单语言的词法分析器1、实验目的通过该实验,熟练应用编译原理关于词法分析的基本理论和方法;学会用C/C++高级程序设计语言设计一个词法分析器;加深对编译原理理论的分析理解,提高实际操作和解决具体问题的能力。
2、实验条件计算机上安装C/C++编译处理软件。
3、实验内容及要求对下述单词表定义的语言设计编制一个词法分析器。
单词符号及种别表和词法分析器功能及基本要求如下:(1)单词符号及种别表(2)词法分析器功能及基本要求处理用户提交的符合上述词法的源代码序列,进行词法分析,并输出单词二元组。
(1)总体设计思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字种类,拼出相应的单一符号;(2)详细算法设计当ch!=’$’时,while循环扫描输入的每一个字符;跳过空格、换行、注释;如果是字符,则拼字符串;判断是否为关键字,是则输出对应关键字的单词种别码,否则表明是l(l|d)*即内部字符串;如果是数字,则拼数,整型、浮点型、指数;如果是运算符、界符,输出相应种别码;算符中应该注意+号和-号,做出相应判断是运算符还是表示数字的正负号;如果是表示正负号则调到判断数字的地方;其他则报错;(3) 流程框图(4) 函数相关说明void main()主函数void scanner()扫描判断函数char input[300];//存放输入的字符串char token[20];//存放符合C语言词法规则的单词char ch;//单个字符char previous;//ch的前一个字符char latter;//ch的后一个字符char ch1, ch2;//当处理注释的时候使用int typenum;//表示单词的种别码int p, m, n, cx;double decimal;//记录小数double sum;//存放数字int index;//存放指数int isNum;//是否是数字int isDecimal;//记录是否为小数int isExp;//记录是否为指数int isNegative;//是否带负号(对于指数)int isNegative1;//是否为负数(5)输入与输出(包括出错处理)输入以$结束回车即可运行程序输出以(xxx,typenumber)的形式;出错则会报error!例如:输入:a+b=5$输出:(10, a)(22, +)(10, b)(21, =) (20, 5)(0, $)(6) 程序运行结果(屏幕截图)1.+++-123.456e-127*+45.99e+200++abc+-cnt++49(7) 词法分析器使用说明打开编译器VS或者VC++;文件→新建→项目;将代码复制粘贴,编译运行,按照提示输入即可使用;(8) 心得与体会提高了自己的编程能力,在上机实验中,特别是后期细节的处理很繁琐,需要很多的判断,判断+、-号是否为数字正负号时需要判断前面和后面的字符;又分为好几种情况,每一种情况的判断语句很长容易出错;同时还有指数的处理,e/E后面需要判断正负号以及把字符转换成数字以及识别数字的DFA和运算符加减等融合在一起;(9) 源程序清单// 词法编译器01.cpp : 定义控制台应用程序的入口点。
中南大学《编译原理》上机实习课程实验报告
编译原理课程实验上机实习中南大学计算机0706班方文一、目的加强学生对编译过程的整体认识,而不是个别阶段的实习。
二、实习要求扩充语句部分:for语句、repeat语句、case语句;三、PL语言及其编译程序1.词法分析2.语法分析3.语义分析及中间代码生成4.汇编代码生成四、扩充1.扩充repeat语句扩充文法<循环语句>::=”repeat”<语句>”until”<表达式>扩充函数:详见文件夹Assignment运行示例:示例代码:program pp;var n,p:integer;procedure p2(n:integer);beginrepeatbegincall write(n);n:=n-1enduntil n=0end;begincall p2(5)end.生成中间代码:0 JMP 0 , 15 ------> 无条件跳转1 JMP 0 ,2 ------> 无条件跳转2 ENTP 2 , 4 ------> 进入过程3 LOD 2 , 3 ------> 装入变量值4 WRITE 0 , 0 ------> 写指令5 LODA 2 , 3 ------> 装入变量地址6 LOD 2 , 3 ------> 装入变量值7 LIT 0 , 1 ------> 装入常量8 SUB 0 , 0 ------> 减9 STO 0 , 0 ------> 将栈顶值存入栈顶次值所指单元10 LOD 2 , 3 ------> 装入变量值11 LIT 0 , 0 ------> 装入常量12 EQ 0 , 0 ------> ==13 JPC 0 , 3 ------> 栈顶值为0时跳转14 RETP 0 , 0 ------> 过程返回15 ENTP 1 , 4 ------> 进入过程16 OPAC 0 , 0 ------> 打开活动记录17 LIT 0 , 5 ------> 装入常量18 CALL 1 , 2 ------> 转子19 ENDP 0 , 0 ------> 程序结束解释运行结果:Your Output:5Your Output:4Your Output:3Your Output:2Your Output:12.扩充for语句扩充文法<循环语句>::=“for”“(”<赋值语句> “;”<表达式> “;”<语句> “)”扩充函数详见文件夹Assignment运行示例示例代码:program pp;var n,p:integer;procedure p1(n:integer;var p:integer);beginfor(p:=1;p<=5;p:=p+1)begincall write(p);endend;begincall read(n);call p1(n,p);call read(n);end.生成中间代码:0 JMP 0 , 19 ------> 无条件跳转1 JMP 0 ,2 ------> 无条件跳转2 ENTP 2 , 5 ------> 进入过程3 LOD 2 ,4 ------> 装入变量值4 LIT 0 , 1 ------> 装入常量5 STO 0 , 0 ------> 将栈顶值存入栈顶次值所指单元6 ILOD 2 , 4 ------> 间接装入7 LIT 0 , 5 ------> 装入常量8 LEQ 0 , 0 ------> <=9 JPC 0 , 18 ------> 栈顶值为0时跳转10 LOD 2 , 4 ------> 装入变量值11 ILOD 2 , 4 ------> 间接装入12 LIT 0 , 1 ------> 装入常量13 ADD 0 , 0 ------> 加14 STO 0 , 0 ------> 将栈顶值存入栈顶次值所指单元15 ILOD 2 , 4 ------> 间接装入16 WRITE 0 , 0 ------> 写指令17 JMP 0 , 6 ------> 无条件跳转18 RETP 0 , 0 ------> 过程返回19 ENTP 1 , 5 ------> 进入过程20 LODA 1 , 3 ------> 装入变量地址21 READ 0 , 0 ------> 读指令22 OPAC 0 , 0 ------> 打开活动记录23 LOD 1 , 3 ------> 装入变量值24 LODA 1 , 4 ------> 装入变量地址25 CALL 1 , 2 ------> 转子26 LODA 1 , 3 ------> 装入变量地址27 READ 0 , 0 ------> 读指令28 ENDP 0 , 0 ------> 程序结束解释运行结果:29翻译开始Your Output:2Your Output:3Your Output:4Your Output:5Your Output:6翻译结束。
编译原理上机实验报告
编译原理上机实验报告一、实验目的本次实验旨在通过实践的方式理解和掌握编译原理中的一些重要概念和技术,包括词法分析、语法分析和语义分析等。
通过实验的操作,了解和体验编译器的工作过程,深入理解编译原理的相关理论知识。
二、实验环境本次实验使用了Java语言作为编程语言,使用Eclipse作为开发环境,实验所需的相关工具和库已经提前配置完成。
三、实验内容本次实验主要分为三个部分,分别是词法分析、语法分析和语义分析。
1.词法分析词法分析是编译器的第一个阶段,也是最基础的阶段。
在本次实验中,我们首先需要实现一个词法分析器,该分析器可以将源代码分割成一个个的词法单元,将其存储到一个词法单元表中。
我们首先需要定义一些词法单元的模式,比如关键字、标识符、常量等。
然后,我们使用正则表达式和有限自动机的思想来实现一个可以识别各种模式的词法分析器。
2.语法分析语法分析是编译器的第二个阶段,其目的是将词法单元表中的内容按照语法规则进行分析,生成一个语法树。
在本次实验中,我们需要实现一个递归下降的语法分析器。
我们首先需要定义一些语法规则,然后根据这些规则逐条实现相应的语法分析函数。
最终,我们可以通过递归调用这些函数,将源代码转换成语法树的形式。
3.语义分析语义分析是编译器的第三个阶段,其目的是对语法树进行进一步的检查和处理。
在本次实验中,我们需要实现一个简单的语义分析器。
我们可以在语法分析的基础上,增加一些语义规则,然后对生成的语法树进行检查。
比如,我们可以检查变量的定义和使用是否一致,是否存在未定义的变量等。
最终,我们可以通过语义分析器发现和纠正一些潜在的错误。
四、实验总结通过本次实验,我深入学习了编译原理的相关知识,并通过实践中加深了对这些知识的理解和掌握。
实验中,我了解到了词法分析、语法分析和语义分析在编译器设计中的重要性,也学会了如何使用相关工具和技术来实现这些功能。
通过实验,我发现编译原理是一门非常有趣且实用的课程,它既涉及到理论知识,又需要实践操作。
编译原理上机实验报告
《编译原理》课内实验报告学院计算机学院专业计算机科学与技术年级班别2012级6班学号 3112006028 学生姓名曾主赐辅导教师刘添添成绩2014年12月一.完成内容1. 扩充单词:(1)保留字:for,step, until,char,real,return;(2)双字符:*=,/=;(3)单字符:[,],*,/ ;2. 扩充语句:var a;begina:=1;doa:=a+1while a<5;write(a);end.二.设计思路1. 扩充单词1)修改变量定义:void init(){int i;for(i=0;i<=255;i++){ssym[i]=nul;}ssym['+']=plus;ssym['-']=minus;ssym['*']=times;ssym['/']=slash;ssym['(']=lparen;ssym[')']=rparen;ssym['=']=eql;ssym[',']=comma;ssym['.']=period;ssym['#']=neq;ssym[';']=semicolon;ssym['[']=l1;ssym[']']=r1;/*设置保留字名字,按照字母顺序,便于折半查找*/ strcpy(&(word[0][0]),"begin");strcpy(&(word[1][0]),"call");strcpy(&(word[2][0]),"char");strcpy(&(word[3][0]),"const");strcpy(&(word[4][0]),"do");strcpy(&(word[5][0]),"end");strcpy(&(word[6][0]),"for");strcpy(&(word[7][0]),"if");strcpy(&(word[8][0]),"odd");strcpy(&(word[9][0]),"procedure");strcpy(&(word[10][0]),"read");strcpy(&(word[11][0]),"real");strcpy(&(word[12][0]),"return");strcpy(&(word[13][0]),"step");strcpy(&(word[14][0]),"then");strcpy(&(word[15][0]),"until");strcpy(&(word[16][0]),"var");strcpy(&(word[17][0]),"while");strcpy(&(word[18][0]),"write");/*设置保留字符号*/wsym[0]=beginsym;wsym[1]=callsym;wsym[2]=charsym;wsym[3]=constsym;wsym[4]=dosym;wsym[5]=endsym;wsym[6]=forsym;wsym[7]=ifsym;wsym[8]=oddsym;wsym[9]=procsym;wsym[10]=readsym;wsym[11]=realsym;wsym[12]=returnsym;wsym[13]=stepsym;wsym[14]=thensym;wsym[15]=untilsym;wsym[16]=varsym;wsym[17]=whilesym;wsym[18]=writesym;修改pl0.h头文件里定义的全局数据:# define norw 19 /*关键字个数*/# define txmax 100 /*名字表容量*/# define nmax 14 /*number的最大位数*/# define al 10 /*符号的最大长度*/# define amax 2047 /*地址上界*/# define levmax 3 /*最大允许过程嵌套声明层数[0,lexmax]*/ # define cxmax 200 /*最多的虚拟机代码数*//*符号*/enum symbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq, lparen,rparen, comma, semicolon,period, becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym,forsym,stepsym,untilsym,charsym,realsym,returnsym,p,q,l1,r1};#define symnum 42/*-------------*/2)修改GetSym()方法:/*词法分析,获取一个符号*/int getsym(){int i,j,k;while( ch==' '||ch==10||ch==9){getchdo;}if(ch>='a'&&ch<='z'){k=0;do{if(k<al){a[k]=ch;k++;}getchdo;}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');a[k]=0;strcpy(id,a);i=0;j=norw-1;do{k=(i+j)/2;if(strcmp(id,word[k])<=0){j=k-1;}if(strcmp(id,word[k])>=0){i=k+1;}}while(i<=j);if(i-1>j){sym=wsym[k];printf("保留字\n");}else{sym=ident;printf("标识符\n");}}else{if(ch>='0'&&ch<='9'){k=0;num=0;sym=number;do{num=10*num+ch-'0';k++;getchdo;}while(ch>='0'&&ch<='9'); /*获取数字的值*/k--;if(k>nmax){error(30);}}else{if(ch==':') /*检测赋值符号*/{getchdo;if(ch=='='){sym=becomes;printf(":=\n");getchdo;}else{sym=nul; /*不能识别的符号*/printf("\n");}}elseif(ch=='*') /*xiugai*/{getchdo;if(ch=='='){sym=p;printf("*=\n");getchdo;}else{sym=times;printf("*\n");getchdo;}}elseif(ch=='/'){getchdo;if(ch=='='){sym=q;printf("/=\n");getchdo;}else{sym=slash;printf("/\n");getchdo;}}else{if(ch=='<') /*检测小于或小于等于符号*/{getchdo;if(ch=='='){sym=leq;printf("<=\n");getchdo;}else{sym=lss;printf("<\n");}}else{if(ch=='>') /*检测大于或大于等于符号*/{getchdo;if(ch=='='){sym=geq;printf(">=\n");getchdo;}else{sym=gtr;printf(">\n");}}else{ sym=ssym[ch];/* 当符号不满足上述条件时,全部按照单字符号处理*/printf("单字符\n");//getchdo;//richardif(sym!=period){getchdo;}//end richard}}}}}return 0;}2. 扩充语句1)产生式以及语法描述图:产生式:a:=1 do a:=a+1 while a<5语法描述图:2)递归下降子程序:if(sym==dosym){ getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[whilesym]=true; statementdo(fsys,ptx,lev); do a:=a+1 while a<5 a:=1if(sym==whilesym){getsymdo;conditiondo(nxtlev,ptx,lev);}else{error(18);}3)举例设计语句的pcode代码:var a;begina:=1;doa:=a+1while a<5;write(a);end.1 int 0 42 int 0 13 sto 0 34 lod 0 35 lit 0 16 opr 0 27 sto 0 38 lod 0 39 lit 0 510 opr 0 1011 jpc 0 1312 jmp 0 413 lod 0 314 opr 0 1415 opr 0 1516 opr 0 04)在递归下降子程序中增加语义动作:if(sym==dosym){cx1=cx;getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlev[whilesym]=true;statementdo(fsys,ptx,lev);if(sym==whilesym){getsymdo;conditiondo(nxtlev,ptx,lev);cx2=cx;gendo(jpc,0,0);gendo(jmp,0,cx1);code[cx2].a=cx;}else{error(18);}三.运行测试1. 扩充单词的测试(贴运行结果截图)ps: 测试情况要全!图片大小合适!截图如下所示:2. 语句的测试(贴运行结果截图)截图如下所示:四.心得归纳完成过程的心得:。
编译原理 上机实验报告
本课程是计算机科学与技术专业的重要专业课。主要讲授编译技术的基本原理、编译程序的组成及编译程序的开发,让学生充分认识和了解程序设计语言编译程序的基本结构和各部分的功能,使学生掌握设计和构造程序语言编译系统的基本原理和技术。
二、实验目的与要求
编译原理是一门理论性和实践性都比较强的课程。上机实验的目的使学生掌握文法和语言的形式定义、单词的描述工具和词法单元的识别、理解中间代码的含义和形式、了解各种语句的翻译、了解代码生成的基本方法等内容,完成词法分析程序的设计、语义分析程序的设计和中间代码生成程序的设计。通过培养学生实际动手能力,使学生既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。
4
1
设计
必做
E05200102
语法分析程序设计
设计exl语言的语法分析程序,使用递归下降分析作为编制语法分析程序的依据,输出分析树和3
语义分析程序设计
设计exl语言的语义分析程序,完成类型检查和类型转换。
4
1
设计
必做
E05200104
中间代码生成程序设计
设计exl语言的中间代码生成程序,输出三地址代码序列。
4
1
设计
必做
三、实验方式与注意事项
本课程所有实验均需上机进行,每个实验都有明确的实验目的。具体要求如下:
1.学生按照实验要求,上机前做好上机实验预习,内容包括:实验的目的、内容、实验步骤。
2.上机实验时按实验要求完成每一个实验的内容。
3.课后认真书写实验报告。
四、实验报告
1.实验报告采用统一的实验报告纸。
2.实验报告书写规范,应包括:实验目的和要求、实验内容、实验步骤、实验纪录。
编译原理上机指导
第一部分词法分析实验一、简单的扫描器设计一、实验目的:熟悉并实现一个简单的扫描器二、实验内容:1.设计扫描器的自动机;2.设计翻译、生成Token的算法;3.编写代码并上机调试运行通过。
·要求:输入——源程序文件;输出——(1)相应的Token序列;(2)关键字、界符表,符号表,常数表。
三、扫描器设计:扫描器单词Token1.自动机:空l/d 关键字表和界符表l -1○0①②-单词编码d program 3d -1 procedure 4③④-begin 5+ end 6⑤-while 7* do 8⑥-+ 9:= * 10⑦⑧-:11-1 := 12⑨-= 13……,14,;15⑩--1○11-2.关键字表和界符表:四、程序实现:1.数据结构:char ch; //当前字符char strToken[]; //当前单词char *keywords[]={“program”, “procedure”, “begin”,……}; //关键字表、界符表char ID[][]; //符号表int Cons[]; //常数表struct TokenType{ int code,value; }struct TokenType Token[]; //Token数组2.算法设计:1.初始化;2.滤除空格,读取第一个非空字符到ch;3.if (ch是一个字母)4.处理关键字或标识符;5. else if (ch是一个数字)6. 处理常数;else7. 处理界符或错误处理;3.算法求精:·step2 :ch=GetChar(); //读取当前字符到chwhile (ch==‟ …)ch=GetChar();·step3:int IsLetter(char ch) //判断ch是否为字母{ if (ch是A~Z或a~z)return 1;elsereturn 0;}·step4:4.1 在strToken中拼成一个单词;//拼关键字或标识符4.2 code=Reserve(strToken); //查关键字表;if (!code) //未查到,是一个标识符{4.3 value=InsertID(strToken); //将strToken中的单词插入到符号表中4.4 生成并输出一个标识符Token;}else4.5 生成并输出一个关键字Token;·step5:int IsDigit(char ch) //判断ch是否为数字{ if (ch是0~9)return 1;elsereturn 0;}6.1 在strToken中拼成一个单词;//拼常数6.2 value=InsertConst(strToken); //将strToken中的单词插入到常数表中6.3 生成并输出一个常数Token;·step7:7.1 将ch中的字符拼接到strToken中;if (ch==‟:‟)7.2 处理双界符“:=”;7.3 code:=Bound(strToken); //查界符表if (!code) //未查到ProcError(); //错误处理else7.4 生成并输出一个界符Token;·step4.1:while (IsLetter(ch)||IsDigit(ch)){ Concat(); //将ch中的字符拼接到strToken中ch=GetChar();}·step4.2:int Reserve(char *strToken)//用strToken中的单词去查关键字表。
编译原理语法分析上机实验读书工程汇报(共4页)
编译原理语法分析上机实验读书工程汇报[范文仅供参考,自行编辑使用]编译原理语法分析上机实验读书工程汇报一、开发环境简介此次编译原理课程设计的编译器的实现是基于VC++编译环境下实现的。
对于VC++,它是Microsoft公司推出的开发Win32环境程序,面向对象的可视化集成编程系统。
它不仅具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点。
VC++不仅是一个C++ 编译器,而且是一个基于Windows操作系统的可视化集成开发环境。
Visual C++明显缩短程式xx、编译及连结花费的时间,在大型软件计划上尤其显著。
二、基本理论阐述、当前理论1.什么是编译程序语言翻译程序把一种语言(称作源语言)书写的程序翻译成另一种语言(称作目标语言)的等价程序。
2.高级语言程序的处理过程3.编译过程三、小型编译器系统架构(最重要)1).词法分析:词法分析是编译过程的第一个阶段。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。
这里所谓的单词是指逻辑上紧密相连的一组字符,这些字符具有集体含义。
比如标识符是由字母字符开头,后跟字母、数字字符的字符序列组成的一种单词。
保留字(关键字或基本字)是一种单词,此外还有算符、界符等等。
2).语法分析:语法分析是编译过程的第二过程。
语法分析的任务是在词法分析的基础上将单词序列分解成各类语法短语;如“程序”、“语句”、“表达式”等。
一般这种语法短语,也称语法单位,可表示成语法树。
词法分析和语法分析本质上都是对源程序的结构进行分析。
但词法分析的任务仅对源程序进行线性扫描即可完成,比如识别标识符,因为标识符的结构是字母打头的字母和数字串,这只要顺序扫描输入流,遇到既不是字母又不是数字字符时,将前面所发现的所有字母和数字组合在一起而构成单词标识符。
但这种线性扫描则不能用于识别递归定义的语法成分,比如就不能用此办法去匹配表达式中的括号。
编译原理上机实验程序(LR分析)
编译原理上机实验程序(LR分析)小型编译程序:高级语言到四元式的编译#include "stdio.h" /*如果使用TC的话,需要配置头文件路径*/ #include "string.h" /*如果使用VC的话,可以配置头文件conio.h*/#define ACC -2/************************/#define sy_if 0#define sy_then 1#define sy_else 2#define sy_while 3#define sy_begin 4#define sy_do 5#define sy_end 6#define a 7#define semicolon 8#define e 9#define jinghao 10#define S 11#define L 12#define tempsy 15#define EA 18 /*E and*/#define E0 19 /*E or*/#define plus 34#define times 36#define becomes 38#define op_and 39#define op_or 40#define op_not 41#define rop 42#define lparent 48#define rparent 49#define ident 56#define intconst 57/*********************************/char ch='\0'; /*从字符缓冲区读取当前字符*/int count=0; /*词法分析结果缓冲区计数器*/static char spelling[10]={""}; /*存放识别的单词符号*/static char line[81]={""}; /*一行字符缓冲区,最多80个字符*/ char *pline; /*字符缓冲区指针*/static char ntab1[100][10]; /*变量名表,共100项,每项长度10*/struct ntab{int tc; /*真值*/int fc; /*假值*/}ntab2[200]; /*在布尔表达式E中保存有关布尔变量的真、假值*/ int label=0; /*指向ntab2的指针*/struct rwords{ /*存放临时变量的表的定义*/char sp[10];int sy;};/*(保留字表)匹配表的结构,用来与输入缓冲区中的单词进行匹配*//*匹配表初始化,大小为10*/struct rwords reswords[10]={{"if",sy_if},{"do",sy_do},{"else",sy_else},{"while",sy_while},{"then",sy_then},{"begin",sy_begin},{"end",sy_end},{"and",op_and},{"or",op_or},{"not",op_not}};struct aa{int sy1; /*存放单词符号的种别编码*/int pos; /*存放单词符号自身的值*/}buf[1000], /*词法分析结果缓冲区,保存识别出来的单词符号*/ n, /*读取二元式的当前符号*/n1, /*当前表达式中的符号*/E, /*非终结符*/sstack[100], /*算术或布尔表达式加工处理使用的符号栈*/ibuf[100], /*算术或布尔表达式使用的缓冲区*/stack[1000]; /*语法分析加工处理使用的符号栈*/struct aa oth; /*四元式中空白位置*/struct fourexp{char op[10];struct aa arg1;struct aa arg2;int result;}fexp[200]; /*四元式的结构定义*/int ssp=0; /*指向sstack栈指针*/struct aa *pbuf=buf; /*指向词法分析缓冲区的指针*/int nlength=0; /*词法分析中记录单词的长度*/int lnum=0; /*源程序行数记数,源程序长度*/int tt1=0; /*变量名表指针*/FILE *cfile; /*源程序文件,~为结束符*//*FILE *mfile;*/int newt=0; /*临时变量计数器*/int nxq=100; /*nxq指向下一个形成的四元式的地址*//*每次执行gen()时,地址自动增1*/int lr; /*扫描LR分析表1过程中保存的当前状态值*/int lr1; /*扫描LR分析表2或表3所保存的当前状态值*/ int sp=0; /*查找LR分析表时状态栈的栈顶指针*/int stack1[100]; /*状态栈1的定义*/int sp1=0; /*状态栈1的栈顶指针*/int num=0; /*算术或布尔表达式缓冲区指针*/struct ll{int nxq1; /*记录下一条四元式的地址*/int tc1; /*真值链*/int fc1; /*假值链*/}labelmark[10]; /*记录语句嵌套层次的数组,*//*即记录嵌套中每层的布尔表达式E的首地址*/ int labeltemp[10]; /*记录语句嵌套层次的数组,*//*即记录每层else之前的四元式地址*/int pointmark=-1, /*labelmark数组指针*/pointtemp=-1; /*labeltemp数组指针*/int sign=0; /*sign=1,为赋值语句;sign=2,为布尔表达式。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验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)then
x=2*x+1/3;
else
x=2/x;
#
(# 表示输入结束)经词法分析后输出如下序列:(10,x)
(18,=)
(11,5)
(26,;)
(2,if)
(27,()
…
说明:关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
如能查到匹配的单词,则该单词的关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:char *keyword[6]={”for”,”if”,”then”,”else”,”while”,”do”};
图2-1主程序示意图
图2-2 扫描子程序主要部分流程图
实验3语法分析程序设计
【实验目的】
●理解语法分析在编译程序中的作用
●在词法分析的基础上进行语法检查和结构分析
●掌握语法分析程序的实现方法和技术
【实验内容】
某一高级程序设计语言的部分语法规则用扩充的BNF表示如下:
⑴ <程序>::=begin<语句串>end
⑵ <语句串>::=<语句>{;<语句>}
⑶ <语句>::=<赋值语句>
⑷ <赋值语句>::=ID=<表达式>
⑸ <表达式>::=<项>{+<项> | -<项>}
⑹ <项>::=<因子>{*<因子> | /<因子>}
⑺ <因子>::=ID | NUM | (<表达式>)
要求:输入单词串,以“#”结束,如果是文法正确的句子,则输出“success”,否则输出“error”。
例如:
输入begin a=9; x=2*3; b=a+x end #
输出success!
输入x=a+b*c end #
输出error!
实验4语义分析及中间代码生成程序设计
【实验目的】
●理解语义分析及中间代码生成在编译程序中的作用
●在语法分析的基础上进行语义检查并生成中间代码
●加深对语法制导翻译的理解
●掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法
【实验内容】
某一高级程序设计语言的部分词法、语法规则同以上实验,在实验3语法分析程序基础上,设计和实现该语言的语义分析程序。
要求:输入是一段语句串,输出为三地址指令形式的四元式代码
例如:
对于语句串
Begin a=2+3*4; x=(a+b)/c end #
输出的三地址码为:
t1 = 3*4
t2 = 2+t1
a = t2
t3 = a + b
t4 = t3/c
x = t4。