手把手教你使用递归下降法实现语法分析器
文章目录
- 前言
- 一、实验内容
- 二、实验要求
- 三、设计
- 1、首符集(FIRST)
- 1、定义
- 2、算法
- 3、计算上述语法的首符集
- 2、尾符集(FOLLOW)
- 1、定义
- 2、算法
- 3、计算上述语法的尾符集
- 3、可选集(SELECT)
- 1、定义
- 2、算法
- 3、计算上述语法的可选集
- 4、语法分析器类(Parser)设计
- 5、语法分析器的界面实现
- 1、界面设计
- 2、结合Parser类实现语法分析器
- 四、测试方案及测试结果
- 结语
- 附录
前言
经过这段时间对编译原理中语法分析的学习,掌握了一定语法分析器设计的理论知识,下面就利用这些理论知识,使用递归下降分析实现一个简单的语法分析器。
一、实验内容
对下列算术表达式的文法编写递归下降分析程序,要求对输入的任意符号串进行语法分析:
(1)E->TE’
(2)E’->+TE’ | —TE’ |ε
(3)T->FT’
(4)T’->*FT’ | /FT’ |ε
(5)F->(E) | id | num
注:文法中id表示标识符(此处标识符的定义与实验一中标识符的定义相同),num表示数字(简单处理可以认为是整数)
二、实验要求
1、 输入/输出格式
输入一个字符串,输出该字符串是否为正确的句子。
例如:输入a+xyz*10+(c/d),输出“正确的表达式”
输入a+*xyz,输出“错误的表达式”
2、上述要求仅为基本要求,可以在此基础上扩充
例如数字可以允许是浮点数,增加错误处理,输出错误信息等。
例:输入a+*xyz,输出“表达式错误:缺少运算数”
进一步可以指出出错的位置。
三、设计
1、首符集(FIRST)
1、定义
2、算法
3、计算上述语法的首符集
2、尾符集(FOLLOW)
1、定义
2、算法
3、计算上述语法的尾符集
3、可选集(SELECT)
1、定义
2、算法
3、计算上述语法的可选集
4、语法分析器类(Parser)设计
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ReDescentAnaly
{/// <summary>/// 该类用来描述递归下降法设计的语法分析器/// </summary>class Parser{char elem; //记录逐个获取的表达式字符int i = 0; //记录获取的位置bool err = false; //false正确 true错误//记录要进行判断的表达式String express;public String Express{get { return express; }set { express = value; }}//记录错误原因String errReson;public String ErrReson{get { return errReson; }}//记录错误位置int errLie;public int ErrLie{get { return errLie; }}//逐个获取表达式中的字符public void GetElem(){elem = express.ToCharArray()[i];if (elem != '$'){i++;}}//(1)E->TE'public void E(){T();E1();}//(2)E'->+TE' | —TE' |εpublic void E1(){if ((elem == '+')||(elem == '-')){GetElem();T();E1();}}//(3)T->FT'public void T(){F();T1();}//(4)T'->*FT' | /FT' |εpublic void T1(){if ((elem == '*') || (elem == '/')){GetElem();F();T1();}}//(5)F->(E) | id | num public void F(){if(elem=='(') //左括号{GetElem();E();if(elem==')') //判断完'('后,要判断之后之后的串中是否存在')'{GetElem();}else{Error("缺少‘)’");}}else if(elem>='0'&&elem<='9') //数字{int flag=0;for(;(elem>='0'&&elem<='9')||elem=='.';){if(elem>='0'&&elem<='9'){GetElem();}if(elem=='.'){GetElem();flag++;}if(flag>=2){Error("小数点过多");break;}if(elem>='a'&&elem<='z'){Error("运算数后不能带有字母");break;}if (elem == '('){Error("运算数后不能直接带上左括号");break;}}}else if(elem>='a'&&elem<='z') //字母{for(;(elem>='a'&&elem<='z');){GetElem();}if (elem == '('){Error("标识符后不能直接带有左括号");}}else{Error("缺少运算数");}}///错误处理public void Error(string reson){ if (err == false){err = true;errReson = reson;errLie = i;}}//判断语法检验结果是否正确public bool IsError(){return err;}//判断表达式是否为空public bool IsEmpty(){return express.ToCharArray()[0]=='$';}}
}
5、语法分析器的界面实现
1、界面设计
1、表达式输入框:这是一个TextBox控件,可读可写,然后将其取名为textBox1
2、分析结果输出框:这是一个TextBox控件,设置ReadOnly属性为true,使其成为只读不可写,然后将其取名为textBox2
3、分析按钮:这是一个Button控件,为其绑定点击事件Analy,然后将其取名为AnalyBtn
2、结合Parser类实现语法分析器
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;namespace ReDescentAnaly
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Analy(object sender, EventArgs e){string s = textBox1.Text + "$";Parser parser = new Parser();parser.Express = s;parser.GetElem(); //获取表达式的首个字符if (parser.IsEmpty()) //如果表达式为空{textBox2.Text = "表达式不能为空";}else //表达式不为空{parser.E(); //进行语法分析if (!parser.IsError())//正确{textBox2.Text = "正确的表达式";}else //错误{textBox2.Text = "表达式错误:" + parser.ErrReson + ",错误位置在第" + parser.ErrLie + "个字符处。";}} }}
}
四、测试方案及测试结果
1、 测试表达式:a+xyz*10+(c/d)
2、 测试表达式:a+*xyz
3、 测试表达式:3.14*5+(10/b)
结语
本次内容的介绍就到这里,希望这篇文章能够给努力学习的你一些帮助,感谢各位人才的:点赞、收藏和评论,我们下次见。
附录
1、基础知识讲解视频
2、源码下载链接
手把手教你使用递归下降法实现语法分析器
文章目录
- 前言
- 一、实验内容
- 二、实验要求
- 三、设计
- 1、首符集(FIRST)
- 1、定义
- 2、算法
- 3、计算上述语法的首符集
- 2、尾符集(FOLLOW)
- 1、定义
- 2、算法
- 3、计算上述语法的尾符集
- 3、可选集(SELECT)
- 1、定义
- 2、算法
- 3、计算上述语法的可选集
- 4、语法分析器类(Parser)设计
- 5、语法分析器的界面实现
- 1、界面设计
- 2、结合Parser类实现语法分析器
- 四、测试方案及测试结果
- 结语
- 附录
前言
经过这段时间对编译原理中语法分析的学习,掌握了一定语法分析器设计的理论知识,下面就利用这些理论知识,使用递归下降分析实现一个简单的语法分析器。
一、实验内容
对下列算术表达式的文法编写递归下降分析程序,要求对输入的任意符号串进行语法分析:
(1)E->TE’
(2)E’->+TE’ | —TE’ |ε
(3)T->FT’
(4)T’->*FT’ | /FT’ |ε
(5)F->(E) | id | num
注:文法中id表示标识符(此处标识符的定义与实验一中标识符的定义相同),num表示数字(简单处理可以认为是整数)
二、实验要求
1、 输入/输出格式
输入一个字符串,输出该字符串是否为正确的句子。
例如:输入a+xyz*10+(c/d),输出“正确的表达式”
输入a+*xyz,输出“错误的表达式”
2、上述要求仅为基本要求,可以在此基础上扩充
例如数字可以允许是浮点数,增加错误处理,输出错误信息等。
例:输入a+*xyz,输出“表达式错误:缺少运算数”
进一步可以指出出错的位置。
三、设计
1、首符集(FIRST)
1、定义
2、算法
3、计算上述语法的首符集
2、尾符集(FOLLOW)
1、定义
2、算法
3、计算上述语法的尾符集
3、可选集(SELECT)
1、定义
2、算法
3、计算上述语法的可选集
4、语法分析器类(Parser)设计
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ReDescentAnaly
{/// <summary>/// 该类用来描述递归下降法设计的语法分析器/// </summary>class Parser{char elem; //记录逐个获取的表达式字符int i = 0; //记录获取的位置bool err = false; //false正确 true错误//记录要进行判断的表达式String express;public String Express{get { return express; }set { express = value; }}//记录错误原因String errReson;public String ErrReson{get { return errReson; }}//记录错误位置int errLie;public int ErrLie{get { return errLie; }}//逐个获取表达式中的字符public void GetElem(){elem = express.ToCharArray()[i];if (elem != '$'){i++;}}//(1)E->TE'public void E(){T();E1();}//(2)E'->+TE' | —TE' |εpublic void E1(){if ((elem == '+')||(elem == '-')){GetElem();T();E1();}}//(3)T->FT'public void T(){F();T1();}//(4)T'->*FT' | /FT' |εpublic void T1(){if ((elem == '*') || (elem == '/')){GetElem();F();T1();}}//(5)F->(E) | id | num public void F(){if(elem=='(') //左括号{GetElem();E();if(elem==')') //判断完'('后,要判断之后之后的串中是否存在')'{GetElem();}else{Error("缺少‘)’");}}else if(elem>='0'&&elem<='9') //数字{int flag=0;for(;(elem>='0'&&elem<='9')||elem=='.';){if(elem>='0'&&elem<='9'){GetElem();}if(elem=='.'){GetElem();flag++;}if(flag>=2){Error("小数点过多");break;}if(elem>='a'&&elem<='z'){Error("运算数后不能带有字母");break;}if (elem == '('){Error("运算数后不能直接带上左括号");break;}}}else if(elem>='a'&&elem<='z') //字母{for(;(elem>='a'&&elem<='z');){GetElem();}if (elem == '('){Error("标识符后不能直接带有左括号");}}else{Error("缺少运算数");}}///错误处理public void Error(string reson){ if (err == false){err = true;errReson = reson;errLie = i;}}//判断语法检验结果是否正确public bool IsError(){return err;}//判断表达式是否为空public bool IsEmpty(){return express.ToCharArray()[0]=='$';}}
}
5、语法分析器的界面实现
1、界面设计
1、表达式输入框:这是一个TextBox控件,可读可写,然后将其取名为textBox1
2、分析结果输出框:这是一个TextBox控件,设置ReadOnly属性为true,使其成为只读不可写,然后将其取名为textBox2
3、分析按钮:这是一个Button控件,为其绑定点击事件Analy,然后将其取名为AnalyBtn
2、结合Parser类实现语法分析器
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;namespace ReDescentAnaly
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Analy(object sender, EventArgs e){string s = textBox1.Text + "$";Parser parser = new Parser();parser.Express = s;parser.GetElem(); //获取表达式的首个字符if (parser.IsEmpty()) //如果表达式为空{textBox2.Text = "表达式不能为空";}else //表达式不为空{parser.E(); //进行语法分析if (!parser.IsError())//正确{textBox2.Text = "正确的表达式";}else //错误{textBox2.Text = "表达式错误:" + parser.ErrReson + ",错误位置在第" + parser.ErrLie + "个字符处。";}} }}
}
四、测试方案及测试结果
1、 测试表达式:a+xyz*10+(c/d)
2、 测试表达式:a+*xyz
3、 测试表达式:3.14*5+(10/b)
结语
本次内容的介绍就到这里,希望这篇文章能够给努力学习的你一些帮助,感谢各位人才的:点赞、收藏和评论,我们下次见。
附录
1、基础知识讲解视频
2、源码下载链接
发布评论