算符优先分析及其简单代码实现

本文介绍算符优先分析方法,通过构建FIRSTVT和LASTVT集,构造算符优先关系表,并以C#代码展示算符优先分析过程,以表达式i+i*i为例。
摘要由CSDN通过智能技术生成

我们可以以下面的文法为例子进行算符优先分析:

E→E+T|T

T→T*F|F

F→(E)|i

FIRSTVT和LASTVT的构建

首先我们要通过文法规则来产生相应的FIRSTVT和LASTVT集,具体的构建规则如下:

FIRSTVT:

 若出现 E→a... 或 E→Aa 的情况,则 a∈FIRSTVT【E】,即产生式右部的第一个终结符属于左部非终结符的FIRSTVT集

 若出现 E→A... 的情况,则 FIRSTVT【A】∈FIRSTVT【E】,即产生式右部开头若是非终结符的情况下,该终结符的FIRSTVT属于左部非终结符的FIRSTVT集

LASTVT:

 若出现 E→...a 或 E→...aA 的情况,则 a∈LASTVT【E】,即产生式右部倒数第一个终结符属于左部非终结符的FIRSTVT集

 若出现 E→...A 的情况,则 LASTVT【A】∈LASTVT【E】,集产生式右部尾部若是非终结符的情况下,该终结符的LASTVT属于左部非终结符的LASTVT集

通过以上方法得到的FIRSTVT和LASTVT集如下:

FIRSTVT:

  FIRSTVT【E】={ ( , i , + , * }

  FIRSTVT【T】 = { ( , i , * }

  FIRSTVT【F】 = { ( , i }

LASTVT:

  LASTVT【E】 = { ) , i , + , * }

  LASTVT【T】 = { ) , i , * }

  LASTVT【F】 = { ) , i }

算符优先关系表的构造

得到了文法的FIRSTVT和LASTVT集以后,我们需要通过它来得到算符优先关系表,具体构造方法如下:

  若出现 E→...ab... 或者 E→....aAb... 的情况:a = b

  若出现 E→...aA.. 且 b∈FIRSTVT【A】的情况:a < b

  若出现 E→...Ab...且 a∈LASTVT【A】的情况:a > b

用此方法构造的算符优先分析表如下所示:

  

  i + * ( ) #
i   > >   > >
+ < > < < > >
* < > > < > >
( < < < < =  
)   > >   > >
# < < < <   =

注:在讨论#与其他终结符的优先级时,可以添加E→#E#来完成

算符优先分析

算符优先分析采用的是移进-归约法,取符号栈中最左素短语的终结符,并将其与输入串头的元素进行优先级比较,若优先关系为 ">" ,则进行归约,若为 "<" 或 "=" 则将输入串头元素压入符号栈。

我们以i+i*i为例来进行算符优先分析: 

  

符号栈 输入串 动作#
# i+i*i# 移进
#i +i*i# 归约
#E +i*i# 移进
#E+ i*i# 移进
#E+i *i# 归约
#E+E *i# 移进
#E+E* i# 移进
#E+E*i # 归约
#E+E*E # 归约
#E+E # 归约
#E # 结束

  

注:算符优先分析中不关心非终结符的优先关系,因此我们在归约的时候可以不用考虑字符串被归约到了哪个非终结符。

 

参考代码

用c#进行实现,代码冗余极多,效率很低,泛用性不足,各种考虑不全面的情况也很多,大家权当做个参考。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 namespace 算符优先分析
  8 {
  9 
 10     class Program
 11     {
 12         /*-------------------------------变量声明---------------------------------------------------------------------------------------*/
 13         static string effectValue = "i+*()#";   //有效的字符集合
 14         static List<string> grammarList = new List<string>();   //文法列表
 15         static Dictionary<string, List<string>> grammarDic = new Dictionary<string, List<string>>();    //文法字典
 16         static Dictionary<string, List<string>>.KeyCollection vertex;   //非终结符集合
 17         static Dictionary<string, string> firstVT = new Dictionary<string, string>();   //firstVT集
 18         static Dictionary<string, string> lastVT = new Dictionary<string, string>();    //lastVT集
 19         static char[,] priorityTable = new char[7,7];   //算符优先关系表
 20         static string message;      //要分析的字符串
 21         static MyStack stack = new MyStack();
 22 
 23 
 24         /*----------------------------主函数--------------------------------------------------------------------------------------------*/
 25         static void Main(string[] args)
 26         {
 27             inputGrammar();    //获得文法字符串
 28             getVT();           //获得firstVT和lastVT
 29             printVT();         //输出firstVT和lastVT
 30             getPriorityTable();//得到优先关系表
 31             printPriorityTable();//打印优先关系表
 32             inputMessage();     //获得要分析的字符串
 33 
 34             //判断字符串是否符合要求
 35             if (judgeMessage())
 36                 //进行算符优先分析
 37                 if (analyze())
 38                     Console.WriteLine("分析成功!该句子符合算符优先。");
 39                 else Console.WriteLine("分析失败!该句子不符合算符优先。");
 40         }
 41 
 42         /*---------------------------------------输入数据---------------------------------------------------------------------*/
 43         static void inputGrammar()
 44         {
 45             Console.WriteLine("该系统支持的终结符有:i,+,*,(,),请勿输入其他终结符!");
 46             Console.WriteLine("请输入要分析的文法:(在单独一行输入#结束输入)");
 47             Console.WriteLine("如:E→E+T|T\nT→T*F|F\nF→(E)|i\n#\n");
 48             while (true)
 49             {
 50                 string str = Console.ReadLine();
 51                 if (str.Equals("#"))
 52                     break;
算符优先分析文法是一种工具,在编译的过程中,隶属于语法分析环节,却又与中间代码的生成息息相关,编译可以分为五个阶段:词法分析、语法分析、语义分析(中间代码的生成)、代码优化、目标代码生成。语法分析是指:在词法分析基础上,将单词符号串转化为语法单位(语法范畴)(短语、子句、句子、程序段、程序),并确定整个输入串是否构成语法上正确的程序。也就是说语法分析是检验输入串的语法是否正确,注意这里的语法正确,只是简单地符合自己定义的规范,而不能检测出运行时错误,比如"X/0",空指针错误,对象未初始化等错误。在这一个实验中,我将通过算符优先分析文法这一个工具,在语法分析的时候,顺便进行语义分析,也就是识别出语法单位,同时简要的将识别出的中间代码进行计算(目标代码的生成+运行),得到相应的结果,来检验自己设计的正确性。可以说题目虽然叫做算符优先分析文法,其实却是一个贯穿了“词法分析+语法分析+语义分析+中间代码优化+目标代码生成+运行”全过程的一个极具概括性的程序。如果能将这个程序得心应手的完成出来,我相信诸位对编译原理的掌握也算是炉火纯青了。时隔将近两年再来整理自己以前写过的实验报告,还是挺有感慨的,对一件东西感兴趣,原来影响还会如此深远,还记得自己当时连续六个小时全神贯注写出的实验报告,现在看看竟然写了五六十页,核心内容也有三四十页,不觉的感慨当年充满热情的时代慢慢的竟走出许久
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值