自上而下语法分析器设计习题1
- 格式:doc
- 大小:34.50 KB
- 文档页数:2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.对文法G[S]G: S →a | ∧| (T)T →T , S | S(1) 给出(a,(a,a))和(((a,a), ∧,(a)),a)的最左推导。
(2) 对文法G,进行改写,然后对每个非终结符写出不带回溯的递归子程序。
(3) 经改写后的文法是否是LL(1)的?给出它的预测分析表。
(4) 给出输入串(a,a)#的分析过程,并说明该串是否为G的句子。
1. [解答](1)①S ②S(T )( T )T , S T , S ②S=>(T) =>(T,S)=>(S,S) S ( T ) S a =>((T),S)=>((T,S),S)a T , S ( T ) =>((T,S,S),S)=>((S,S,S),S) S a T , S =>(((T),S,S),S)=>(((T,S),S,S),S)a T , S ( T ) =>(((S,S),S,S),S)=>(((a,S),S,S),S) ①S=>(T) =>(T,S) S ^ S =>(((a,a),S,S),S)=>(S,S) =>(a,S) =>(((a,a),^,S),S) =>(a,(T)) ( T ) a =>(((a,a),^,(T)),S) =>(a,(T,S)) =>(((a,a),^,(S)),S)=>(a,(S,S)) T , S =>(((a,a),^,(a)),S)=>(a,(a,S)) =>(((a,a),^,(a)),a)=>(a,(a,a)) S aa(2) 消除左递归G': S→a | ∧| (T)T→ST'T'→,ST' |ε递归子程序:program parser proceduce T;begin begingetsym; if sym in [a,^,() thenS beginend; S;proceduce S; T;begin end;if sym=’a’ or sym=’^’ then elsegetsym error;elseif sym=’(‘ end;begin getsym; proceduce T’;T; beginIf sym=’)’ then if sym=’,’ thenGetsym; beginElse getsym;Error; S;End; T;Else end;Error; elseEnd; if sym=’)’ thenelseerror;end;预测分析表不含多重定义入口, 所以该文法是LL(1)文法!(4) 分析栈余留串所用产生式或动作1 #S (a,a)# S—>(T)2 #)T( (a,a)# (匹配3 #)T a,a)# T—>ST’4 #)T’S a,a)# S—>a5 #)T’a a,a)# a匹配6 #)T’ ,a)# T’ —>,ST’7 #)T’S, ,a)# ,匹配8 #)T’S a)# S—>a9 #)T’a a)# a匹配10 #)T’ )# T’—>ε11 #) )# )匹配12 # # 接受因为(a,a)#分析成功所以(a,a)为文法的句子步骤分析栈余留串所用产生式或动作1 #S (a,a# S→(T)2 #)T( (a,a# ( 匹配3 #)T a,a# T→ST’4 #)T’S a,a# S→a5 #)T’a a,a# a 匹配6 #)T’,a# T’→,ST’7 #)T’S, ,a# , 匹配8 #)T’S a# S→a9 #)T’a a# a 匹配10 #)T’# 出错^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2. G: E →TE'E' →+E |εT →FT'T' →T |εF →PF'F' →*F' |εP →(E) | a | b |∧预测分析表^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 3.已知文法G: S →MH | aH →LSo |εK →dML |εL →eHfM →K | bLM判断G是否是LL(1)文法,如果时,构造LL(1)分析表。
实验5---语法分析器(自下而上):LR(1)分析法一、实验目的构造LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。
二、实验内容程序输入/输出示例(以下仅供参考):对下列文法,用LR(1)分析法对任意输入的符号串进行分析:(1)E->E+T(2)E->E—T(3)T->T*F(4)T->T/F(5)F-> (E)(6)F->i输出的格式如下:(1)LR(1)分析程序,编制人:姓名,学号,班级(2)输入一个以#结束的符号串(包括+—*/()i#):在此位置输入符号串(3)输出过程如下:3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照。
三、实验方法1.实验采用C++程序语言进行设计,文法写入程序中,用户可以自定义输入语句;2.实验开发工具为DEV C++。
四、实验步骤1.定义LR(1)分析法实验设计思想及算法①若ACTION[sm , ai] = s则将s移进状态栈,并把输入符号加入符号栈,则三元式变成为:(s0s1…sm s , #X1X2…Xm ai , ai+1…an#);②若ACTION[sm , ai] = rj则将第j个产生式A->β进行归约。
此时三元式变为(s0s1…sm-r s , #X1X2…Xm-rA , aiai+1…an#);③若ACTION[sm , ai]为“接收”,则三元式不再变化,变化过程终止,宣布分析成功;④若ACTION[sm , ai]为“报错”,则三元式的变化过程终止,报告错误。
2.定义语法构造的代码,与主代码分离,写为头文件LR.h。
3.编写主程序利用上文描述算法实现本实验要求。
五、实验结果1. 实验文法为程序既定的文法,写在头文件LR.h中,运行程序,用户可以自由输入测试语句。
1.课程设计目的:1.1 设计目的:通过编程实现语法分析(自上而下,自下而上)的可视化过程,加深对两法分析原理思想的理解。
[目的要求]通过设计编制调试一个具体的语法分析程序,加深对语法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其进行语法分析的方法。
[题目分析]递归下降分析方法是一种确定的自上而下分析方法。
它的基本思想是给文法的每一个非终结符均设计一个相应的子程序。
由于文法的产生式往往是递归的,因为这些子程序往往也是递归的。
1.2 开发环境:操作系统:Windows XP辅助工具:Visual Studio 2008编程语言:C#2. 课程设计要求(1)选定一文法,选定一种分析方法(自上而下、自下而上)(2)允许用户输入语句并对该语句进行相应的语法分析(3)要求显示语法树的建立过程以及跟踪分析表和分析栈的状态(4)要提供单步运行,让用户跟踪分析器工作的每一个步骤。
3. 总体设计3.1 设计框架:3.2 程序流程图:4. 设计功能描述:(1)该课程设计对语法分析指定了固定的文法,运行界面为:“开始”,会出现提示:。
(3)用户输入字符串,可以点击“”,软件根据该输入字符串做好初始化工作,再点击“”,开始分析,每一次点击“下一次”,就做分析的一个步骤,并且此时分析栈和输入栈做相应的出栈、入栈的的动作,同时在“分析栈”,“输入栈”,“输出栈”会显示出相应的状态。
(4)分析结果显示在中(5)如果在分析完后,还需要继续输入字符串分析的画,点击“”,可以再次作上述的操作。
(6)如果想退出程序,点击““,此时会弹出提示窗口:,点击“确定”,便退出程序。
分析实例:输入分析的字符串为i*(i+i)结果如下:5. 源程序代码:#region相关初始量(都是全局的)public string[] mystring = { "TC", "FALSE", "FALSE", "TC", "FALSE", "FALSE", "FALSE", "+TC", "FALSE", "FALSE", "ε", "ε", "FD", "FALSE", "FALSE", "FD", "FALSE", "FALSE", "FALSE", "ε", "*FD", "FALSE", "ε", "ε", "i", "FALSE", "FALSE", "(E)", "FALSE", "FALSE" };//分析表数组bool con = true;//控制显示的布尔量private Stack MyStack = new Stack(); //申请一个分析栈private Stack MyInputstack = new Stack();//申请一个输入栈public string[] Term = { "i", "+", "*", "(", ")", "&" }; //终结符数组public string[] unTerm = { "E", "C", "T", "D", "F" };//非终结符数组private int line, row; //定义行,列的全局变量string MyNowString;#endregion“开始”按钮实现的函数private void开始_Click(object sender, EventArgs e){if (Input_richTextBox1.Text == ""){MessageBox.Show("请输入要分析的字符串!");}else{this.MyOutput_listBox3.Items.Add("");MyStack.Push("&");MyStack.Push("E");MyStack_listBox1.Items.Add("&E");MyInput_listBox2.Items.Add(Input_richTextBox1.Text + "&");MyInputstack.Push("&");for (int i = Input_richTextBox1.Text.Length - 1; i >= 0; i--){MyInputstack.Push(Input_richTextBox1.Text[i]);}begin.Enabled = false;}}#region“下一步”按钮实现的函数private void下一步_Click(object sender, EventArgs e){int loc;string MyStackTop, MyStackInputTop;MyStackTop = MyStack.Peek().ToString();MyStackInputTop = MyInputstack.Peek().ToString();MyStackTopOne(MyStackTop);if (MyStackTopOne(MyStackTop)){MyStackTopTwo(MyStackTop, MyStackInputTop);}else if (MyStackTopThree(MyStackTop) &&MyInputStackTopOne(MyStackInputTop)){loc = line * 6 + row;MyNowString = mystring[loc];this.MyOutput_listBox3.Items.Add(MyStack.Peek().ToString() + "-->" + mystring[loc]);Analyse();}else{Rezult_richTextBox2.Text = "分析出错!";nextStep.Enabled = false;con = false;}if (con){ShowMyStack();ShowMyInpuStack();}}#endregion#region显示分析栈里的字符private void ShowMyStack(){string ch = "";int len = MyStack.Count;string display = "";for (int i = 0; i < len; i++){string t;t = MyStack.Pop().ToString();display = display + t;}for (int i = len - 1; i >= 0; i--){ch = ch + display[i];MyStack.Push(display[i]);this.MyStack_listBox1.Items.Add(ch);}#endregion#region显示输入栈里的字符private void ShowMyInpuStack(){int len = MyInputstack.Count;string display = "";for (int i = 0; i < len; i++){string t;t = MyInputstack.Pop().ToString();display = display + t;}for (int i = len - 1; i >= 0; i--){MyInputstack.Push(display[i]);}this.MyInput_listBox2.Items.Add(display);}#endregion#region判断状态栈栈顶元素是否为终结符public bool MyStackTopOne(string stack){bool symbol = false;for (int i = 0; i < Term.Length; i++){if (stack == Term[i]){symbol = true;break;}}return symbol;}#endregion#region状态栈栈顶元素是终结符的处理方法private void MyStackTopTwo(string stack, string input) {if (stack == input)if (stack == "&"){Rezult_richTextBox2.Text = "分析成功!"; nextStep.Enabled = false;con = false;}else{MyStack.Pop();MyInputstack.Pop();this.MyOutput_listBox3.Items.Add(""); }}}#endregion#region返回状态栈栈顶元素在非终结符数组里的下标public bool MyStackTopThree(string stack){bool symbol = false;for (int i = 0; i < unTerm.Length; i++){if (unTerm[i] == stack){line = i;symbol = true;break;}}return symbol;}#endregion#region返回输入栈栈顶元素在终结符数组里的下标private bool MyInputStackTopOne(string myinput){bool symbol = false;for (int i = 0; i < Term.Length; i++){if (Term[i] == myinput){row = i;symbol = true;break;}return symbol;}#endregion#region分析表字符入栈private void Analyse(){if (MyNowString == "FALSE"){Rezult_richTextBox2.Text = "分析出错!";nextStep.Enabled = false;con = false;}else if (MyNowString == "ε"){MyStack.Pop();}else{MyStack.Pop();for (int i = MyNowString.Length - 1; i >= 0; i--) {MyStack.Push(MyNowString[i]);}}}#endregion#region“退出”按钮实现的函数private void exit_button2_Click(object sender, EventArgs e) {DialogResult ret;ret = MessageBox.Show("确定要退出吗?","退出",MessageBoxButtons.OKCancel,MessageBoxIcon.Question,MessageBoxDefaultButton.Button2);if (ret == DialogResult.OK){this.Close();}}#endregion#region“重置”按钮实现的功能private void clear_Button_Click(object sender, EventArgs e){Input_richTextBox1.Clear();Rezult_richTextBox2.Clear();this.MyStack_listBox1.Items.Clear();this.MyInput_listBox2.Items.Clear();this.MyOutput_listBox3.Items.Clear();MyStack.Clear();MyInputstack.Clear();begin.Enabled = true;nextStep.Enabled = true;con = true;}#endregionprivate void button1_Click(object sender, EventArgs e){pictureBox1.Visible = true;}}6. 总结:通过本次课程设计,对于语法分析的原理与方法有了进一步的体会,在通过使用visual studio 2008的同时让我们对c#和语法分析有了更深的理解。
自上而下的语法分析器设计
1. 读取文法
/*输入:含一个文法的文本文件*/
/*输出:将文法存放到一个结构体数组中,并逐行显现在屏幕上。
*/
/*文件中文法的格式:
1)第一行:大写英文非终极符号序列,每个非终极符号都是字母,以换行符号'\n'作为结束标志;两个符号之间可以出现空格;
2)第二行:终极符号序列,每个终极符号可以字符是除了大写英文字母、空格、和控制符之外的任意一个可见的ASCII码。
3)对于空产生式,可暂用一个空格表示空串。
4)产生式每行一个。
*/
/*存放文法的结构体包括三项纪录:
1)非终极符号数组,2)终极符号数组,3)存放各产生式的结构体数组。
所存放的产生式只能含有文法符号,不能含有空格、换行符号等非文法符号,但是空产生式可以用非文法符号表示。
*/
示例:
G6.txt
SABC
abc
S-->AB
A-->aC
A-->
B-->Ab
B--> c
B-->
C-->c
2. 计算首字符集
输入:(1)一个文法的文本文件,(2)键盘输入一个文法符号串。
输出:生成该文法符号串的首字符集,并输出到显示器。
算法:
C语言程序:
#include<stdio.h>
#include<ctype.h>
void main()
{
}
3. 计算非终极符号的后字符集。