编译原理上机报告
编译原理上机实验

实验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,()…说明:关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
--表达式编译程序上机报告

《编译原理》上机实验报告计算机科学与技术班---上机一成员:00813035—吴庆周00813003—祝金辉00813015—闫海滨00718100—特日格乐00813023—王仕华一、题目编写编译程序实现多行表达式的<表达式序列>的文法语言的编译执行二、设计和主要结构1词法分析词法分析子程序分析:词法分析子程序名为getsym,功能是从源程序中读出一个单词符号,把它的信息放入全局变量sym、id和num中,语法分析器需要单词时,直接从这三个变量中获得。
(注意!语法分析器每次用完这三个变量的值就立即调用getsym子程序获取新的单词供下一次使用。
而不是在需要新单词时才调用getsym过程。
)getsym过程通过反复调用getch子过程从源程序过获取字符,并把它们拼成单词。
getch过程中使用了行缓冲区技术以提高程序运行效率。
词法分析器的分析过程:调用getsym时,它通过getch过程从源程序中获得一个字符。
如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把sym变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym置为SYM_IDENTIFIER,把这个单词存入id变量。
查保留字表时使用了二分法查找以提高效率。
如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。
如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把sym赋成相应的类型。
如果遇到不合法的字符,把sym置成SYM_NULL。
词法分析子程序要完成的工作有:1. 识别一般标识符,此标识符值(字符序列)赋给全局量id,而全局量sym赋值为SYM_IDENTIFIER。
2. 识别数字序列,当前值赋给全局量NUM,sym则置为SYM_NUMBER;3. 识别=,回车之类的特殊符号,全局量sym则分别被赋值为SYM_BECOMES,SYM_CONTINUE等。
编译原理实验报告

编译原理实验报告实验⼀词法分析⼀、实验⽬的设计、编制并调试⼀个词法分析程序,加深对词法分析原理的理解。
⼆、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是⼩写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空⽩、制表符和换⾏符组成。
空格⼀般⽤来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码单词符号种别码单词符号种别码bgin 1 :17If 2 := 18Then 3 < 20wile 4 <> 21do 5 <= 22end 6 > 23lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26—14 ( 27* 15 ) 28/ 16 # 02.3 词法分析程序的功能:输⼊:所给⽂法的源程序字符串。
输出:⼆元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词⾃⾝字符串;(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表⽰的源程序中识别出具有独⽴意义的单词符号,其基本思想是根据扫描到单词符号的第⼀个字符的种类,拼出相应的单词符号。
3.1 主程序⽰意图:主程序⽰意图如图3-1所⽰。
其中初始包括以下两个⽅⾯:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在⼀张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
编译原理实验报告

编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理上机实验-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、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是否跟着是注释语句。
编译原理实验报告

编译原理实验报告《编译原理》实验教学⼤纲课程编号:课程名称:编译原理/Compiler Principles实验总学时数:8学时适应专业:计算机科学与技术、软件⼯程承担实验室:计算机科学与技术学院实验中⼼⼀、实验教学的⽬的和任务1.上机实习是对学⽣的⼀种全⾯综合训练,是与课堂听讲、⾃学和练习相辅相成的必不可少的⼀个教学环节。
通常,实习题中的问题⽐平时的练习题要复杂,也更接近实际。
编译原理这门课程安排的2次上机实验都属于⼀种设计类型的实验,每个实验的训练重点在于基本的编译技术和⽅法,⽽不强调⾯⾯俱到;实验的⽬的是旨在使学⽣进⼀步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容;培养学⽣编制算法的能⼒和编程解决实际问题的动⼿能⼒。
2.要求学⽣在上机前应认真做好各种准备⼯作,熟悉机器的操作系统和语⾔的集成环境,独⽴完成算法编制和程序代码的编写;上机时应随带有关的编译原理教材或参考书;要学会程序调试与纠错;每次实验后要交实验报告。
实验报告的内容应包括:(1)封⾯:实验题⽬、班级、学号、姓名、完成⽇期;(2)简要的需求分析与概要设计;(3)详细的算法描述;(4)程序清单与运⾏结果;(5)收获与体会。
实验成绩占编译原理课程结业成绩的10-20%。
⼆、实验项⽬及学时分配三、每项实验的内容和要求要求每个实验保证每个学⽣⼀台微机。
实验⼀(4学时):单词的词法分析程序设计。
1.问题描述:对于常⽤⾼级语⾔(如Pascal、C语⾔)的各类单词进⾏词法分析。
2.实验内容:完成对某⼀种常⽤⾼级语⾔(如Pascal、C语⾔、PL/0语⾔)的各类单词进⾏词法分析,即对源程序从左到右进⾏扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。
3.实验要求:(1)选择常⽤⾼级程序设计语⾔(如 Pascal、C语⾔、PL/0语⾔)的源程序作为词法分析对象。
(2)根据教学要求和学⽣具体情况,从上列语⾔之⼀中选取它的⼀个适当⼤⼩的⼦集,可以选取⼀类典型单词,也可以尽可能使各种类型的单词都能兼顾到。
编译原理上机报告

编译原理上机报告编译原理基础上机报告册班级: XXXXXX 学号: XXXXXXXX 姓名:XXXXXX目录第一次上机题目:词法分析器的构造............................................................................ . (3)一、任务与目的 ........................................................................... (3)1. 任务............................................................................ .. (3)2. 目的............................................................................ ................................ 3 二、软件设计 ........................................................................... . (3)1. 软件的总体结构与模块划分 (3)2. Java软件包的设计 ....................................................................................... 7 3. 软件中关键的算法............................................................................ ........... 7 三、测试例程设计与测试结果分析 (10)1. 例程1 ............................................................................ ........................... 10 2. 例程2 ............................................................................ ............................11 四、总结、体会及其他............................................................................ ................ 12 第二次上机题目:语法分析器的构造............................................................................ .. 13一、任务与目的 ........................................................................... (13)1. 任务............................................................................ .............................. 13 2. 目的............................................................................ .............................. 13 二、软件设计............................................................................ (13)1. Java软件包的设计 ........................................................................... .......... 13 2. 适合编写递归下降子程序的文法................................................................ 13 3. 表达式的语法树 ........................................................................... ............. 16 4. 语法分析器主程序流程图 ..........................................................................19 5. 语法分析器的递归下降子程序 ................................................................... 19 三、测试例程设计与测试结果分析 (20)1. 例程1 ............................................................................ ........................... 20 2. 例程2 ............................................................................ (21)3. 例程3 ............................................................................ ........................... 22 四、总结、体会及其他............................................................................ ................ 24 附录:源代码............................................................................ . (25)一、 analyser中的代码 ........................................................................... .. (25)1. Token_Type中的代码 ........................................................................... (25)2. Token中的代码 ........................................................................... .............. 25 3. mytokentab中的代码............................................................................ ..... 26 4. scanner2中的代码 ........................................................................... .......... 27 5. viewer中代码............................................................................ ................ 36 二、parser中的代码 ........................................................................... .............. 38 1. ExprNode中的代码 ........................................................................... ......... 38 2. parser中的代码 ........................................................................... .............. 40 3. parsermain中的代码............................................................................ (52)第一次上机题目:词法分析器的构造一、任务与目的1. 任务词法分析器的构造一般有以下几大步骤:(1)用正规式对模式进行描述(2)由正规式构造NFA(3)由NFA转化为DFA且最小化(4)根据最小DFA编写程序并进行测试为函数绘图语言编写一个解释器解释器接受用绘图语言编写的源程序,经语法和语义分析之后,将源程序所规定的图形显示在显示屏(或窗口)中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理上机报告组员:班级:一、上机题目:实现一个简单的语言(Core Programming Language,CPL)的编译器(解释器)(或者其他自己想完成的编译器)二、上机目的加深编译原理基础知识的理解:词法分析、语法分析、语法制导翻译等加深相关基础知识的理解:数据结构、操作系统等提高编程能力锻炼独立思考和解决问题的能力三、上机要求1、功能要求接收以CPL编写的程序,对其进行词法分析、语法分析、语法制导翻译等,然后能够正确的执行程序2、验收要求条件:1.完成CPL词法分析器;2.完成CPL语法分析器;3.完成CPL语法制导翻译;方法:1.演示程序的功能;2.解释程序的源代码;四,基本步骤1.分别配置Parser Generator、Visual C++;2.使用Parser Generator创建一个工程number编写l文件mylexer.l;编译mylexer.l,生成mylexer.h与mylexer.c;3.安装Parser Generator、Visual C++;4.使用VC++创建Win32 Console Application工程number配置该项目;加入mylexer.h与mylexer.c,编译工程;执行标识符数字识别器;注意:每次修改l文件后,需要重新编译l文件,再重新编译VC工程五、工具:编译器:Visual C++,EclipseLex与Yacc:Parser Generator(支持C/C++/Java,带实例)或者其他自己擅长的语言和环境六、相关介绍1、Core Programming Language(CPL)数据类型:整型变量(常量),布尔变量(常量)取值范围{…, -2, -1, 0, 1, 2, …}, {true, false}运算表达式:简单的代数运算,布尔运算程序语句:赋值表达式,顺序语句,if-else语句,while语句语言特点:简单、易处理如果加入浮点数及相应的除操作,那么该语言的表达能力相当于C, C++,JAVA 等便于关注语言实现的本质,而不受繁冗细节的干扰基本框架:CPL 程序CPLComplier执行结果词法分析器 语法分析器 语义子程序C/C++/Java 编译器CPL Compiler(1) 手工编写(2)工具生成词法l 文件C/C++编译器CPL C语法y 文件2、词法分析器生成器LexLex 是一个词法分析器生成器,接受正规式表示的词法规则,生成识别正规式所描述语言的源程序,不同版本的Lex 支持不同的高级语言,如C 、C++、Java 等。
利用Lex 构造词法分析器:实质为如何设计正规式和语义动作 Lex 源程序*.l(三段式): [定义C 声明辅助定义正规式*.l]%%lex.yy.cEXE规则词法规则正规式输入字符序列记号流词法分析器人工编写Lex 转化语义动作(C 代码)[%%用户子程序 C 源程序 ]Lex 源程序*.l(三段式): [定义 C 声明辅助定义正规式] %% 规则语义动作(C [%%用户子程序C 源程序]mylexer.l 源代码: //声明部分 %{#define ID 0 #define NUMBER 1 %} char [a-zA-Z] digit [0-9] digits {digit}+optional_fraction (.{digits})?optional_exponent (E[+-]?{digits})?%% {char}({char}|{digit})*{ printf("识别标识符%s :长度为%d\n", yytext, yyleng); return ID;}{digits}{optional_fraction}{optional_exponent} {printf(“识别数字%s :长度为%d\n", yytext, yyleng);return NUMBER;注意:不同版本的Lex 生成的文件不同lex.yy.c 结构:(1)声明的C 语言部分(2)词法分析表(3)词法分析驱动器(yylex())(4)用户定义子程序//C 声明:记号类别将来在Y acc 中使用下列语句代替:%Token ID NUMBER//辅助定义正规式//词法规则正规式 //语义动作:C 代码} %%int main(void) { printf("词法分析成功,返回记号类别为%d\n", yylex());}实验结果:每次输入一个字符串,输出识别结果注意:将来Y acc 自动调用yylex()返回一个记号3、语法分析器生成器Y accY acc 是一个语法分析器生成器,接受产生式表示的语法规则,生成识别产生式所描述语言的源程序,不同版本的Y acc 支持不同的高级语言,如C 、C++、Java 等。
yytext ,yyleng :全局变量,用来存放识别出的输入序列,由词法分析器自动填写//C 源程序yylex():词法分析驱动器,根据语法规则返回记号的类别,如ID 、NUMBER 等。
语法分析器输入记号流人工编写Y acc 转化利用Y acc 构造语法分析器:实质为如何设计产生式和语义动作 Y acc 源程序*.y(三段式): [定义C 声明*.y符号定义]%%y.*EXE规则 语法规则产生式语义动作(C 代码)[%%用户子程序 C 源程序 ]Y acc 源程序*.y(三段式): [定义 C 声明符号定义] %% 规则 语法规则产生式语义动作(C 代码[%%用户子程序C 源程序]实例2:算术运算表达式识别器—仅使用Y acc 基本步骤:1、使用Parser Generator 创建一个工程calc 编写y 文件myparser.y ;注意:不同版本的Y acc 生成的文件不同y.tab.c 结构:(1)声明的C 语言部分(2)语法分析表(3)语法分析驱动器(yyparser())(4)用户定义子程序编译myparser.y ,生成myparser.h 与myparser.c ; 2、使用VC++创建Win32 Console Application 工程calc 配置该项目;加入myparser.h 与myparser.c ,编译工程; 执行算术运算表达式识别器;注意:每次修改y 文件后,需要重新编译y 文件,再重新编译VC 工程 myparser.y 源代码: %{ #include <ctype.h>%}%token NUMBER // 无优先级与结合性 %left '+', '-'// 低优先级与左结合%left '*', '/' // 高优先级与左结合 %%expr : expr '+' expr { printf("识别加法!\n"); } | expr '-' expr { printf("识别减法!\n"); } | expr '*' expr { printf("识别乘法!\n"); } | expr '/' expr { printf("识别除法!\n"); } | '(' expr ')' { printf("识别括号!\n"); }| NUMBER{ printf("识别数字!\n"); };%%int main(void){ return yyparse();}int yylex(void){ int c; while ((c = getchar()) == ' ');//过滤空格 if (isdigit(c)) {//判断是否是数字 ungetc(c, stdin); scanf("%d", &yylval);return NUMBER;}if (c == '\n') return 0;//回车返回0,代表词法分析器读取完毕 return c;}执行结果:每次输入一个算术运算表达式,出分析结果//C 声明//符号定义%token,%left 说明对应 实例1中的define//语法规则产生式//语义动作*//C 源程序yyparse():yacc 自动生成的语法分析驱动器,根据语法规则进行自下而上分析(调用yylex 进行词法分析),同时执行语义动作。
yylex():用户自定义的词法分析驱动器。
yylval :全局变量,用来存放识别出的输入序列。
注意:Y acc 自动调用yylex()返回一个记号实例3:算术运算表达式识别器—同时使用Lex 与Y acc 基本步骤:使用Parser Generator 创建一个工程calc2 编写l 文件mylexer.l; 编写y 文件myparser.y ;编译mylexer.l ,生成mylexer.h 与mylexer.c ; 编译myparser.y ,生成myparser.h 与myparser.c ; 使用VC++创建Win32 Console Application 工程calc2 配置该项目;加入mylexer.h 与mylexer.c ,myparser.h 与myparser.c ,编译工程;执行算术运算表达式识别器;注意:每次修改l 、y 文件后,需要重新编译l 、y 文件,再重新编译VC 工程 mylexer.l 主要源代码: digit [0-9]digits {digit}+optional_fraction ("."{digits})? optional_exponent (E[+-]?{digits})? %%[]+ ; //过滤空格{digits}{optional_fraction}{optional_exponent} { return NUMBER; } "+" { return '+'; } "-" { return '-'; } "*" { return '*'; } "/" { return '/'; } "(" { return '('; }")" { return ')'; }"\n" { return 0; //回车返回0,代表词法分析器读取完毕} mylexer.y 主要源代码:%token NUMBER // 无优先级与结合性 %left "+", "-" // 低优先级与左结合%left "*", "/" // 高优先级与左结合 %%expr : expr "+" expr { printf("识别加法!\n"); } | expr "-" expr { printf("识别减法!\n"); } | expr "*" expr { printf("识别乘法!\n"); } | expr "/" expr { printf("识别除法!\n"); } | "(" expr ")" { printf("识别括号!\n"); } | NUMBER{ printf("识别数字!\n"); };%%int main(void){ return yyparse(); }//符号定义%token,%left 说明对应执行结果:每次输入一个算术运算表达式,输出分析结果注意:Y acc自动调用Lex返回一个记号七、实验总结扛天身运盛,畏死意气折。