递归下降生成Tiny语法树

本文介绍了递归下降法在自顶向下语法分析中的应用,特别是处理Tiny语言的文法。递归下降法包括处理左递归的方法,如通过扩展巴克斯范式(EBNF)改写文法。LL(1)预测分析是递归下降的一个特例,通过first集和follow集计算预测分析表,避免显式递归。在Tiny语法分析中,语句和表达式通过不同类型的语法树节点表示,利用match函数进行符号匹配。文章还详细阐述了语句和表达式的解析过程,以及如何构建和遍历语法树。
摘要由CSDN通过智能技术生成

自顶向下的语法分析:
递归下降法是自顶向下分析方法的通用形式。递归下降可能需要回溯。
而预测分析属于递归下降的一个特例,不需要回溯。预测分析程序试图利用一个或多个先行记号来预测出输入串中的下一个构造。LL(1)是一类最常用的预测分析程序,python的parser就是用LL(1)写的,LL(1)是自底向上算法的前奏。

自己创建一门语言,首先是要写出它的文法,然后是把文法转换成parse程序。个人感觉第一步写出文法的步骤比较重要(当然也可以从书上抄一些),转换程序是有固定的规则的,比较简单。

表达式(expression)和语句(statment)是两个概念:基本程序步骤由语句组成,而大多数语句都由表达式构成。
考虑如下Tiny的文法:
在这里插入图片描述

语法树可以采用树的孩子兄弟表示法,
一、递归下降法
用递归下降法写parser程序的过程,就是把图中的文法用程序翻译出来。每个文法都对应一个处理该文法的子例程。

比如 factor -> ( exp ) | number 这个文法规则,可以用如下伪代码来表示:
def factor():
  switch(token):
  case ( : 
    match( ( );
    exp;
    match( ) );
  case number:
    match(number);
  else error;
  end switch; 
end

比较麻烦的是对左递归的处理,递归下降和LL(1)使用不同的方法来处理左递归的问题。

递归下降使用拓展巴克斯范式(EBNF)把左递归写成其他形式,
类似exp->exp addop term | term这样的表达式是左递归的,并不好直接用递归下降程序来翻译
所以通过改写成 exp->term { addop term } 可以方便表示(大括号( { } )内包含的为可重复0至无数次的项。)

exp -> exp + num|num   #这里就是递归,我们在定义“exp”这个概念,而它的定义里面又用到了自己本身!
exp -> term { addop term }
#都是匹配形如  num (+ num) (+ num) ...  的串 。在数学上,这两个表达式是等价的。

对应的exp匹配程序如下:

def exp():
  term();  
  while token = '+' or token = '-':
    match(token);
    term();
  end while
end

程序运行到term()的时候,还无法判断token是否匹配,但是随着term()进一步递归、下降,直到factor表达式调用match的时候,才知道token和整个文法匹不匹配。
递归下降的实质是经历了一个对语法树的前序遍历,因为语法树的叶子节点必定是非终结符,也就一定能用match函数进行比对,比对上了就进行下一步,如果没比对上,就退回并选择另一个产生式。

二、
LL(1)是将直接左递归改写成非直接左递归形式,通过first集和follow集的计算求出预测分析表,这样就可以根据读入的token选择对应的产生式。
在LL(1)中,显示维护一个栈结构,就不用产生显示递归,而是用循环(尾递归)来编写程序。

三、实际Tiny语法分析
语法分析部分。
树的结点种类NodeKind分为StmtK和ExpK两类,两类又有各自的子类。
在语法树中标明种类有利于代码生成,当遍历语法树检测到特定类型时就可以进行特定的处理。
treeNode结构为指向孩子和兄弟的节点。
语句通过同属域而不是子域来排序,即由父亲到他的孩子的唯一物理连接是到最左孩子的。孩子则在一个标准连接表中自左向右连接到一起,这种连接称作同属连接(网上查了查,没有这个概念。。),用于区别父子连接。

typedef enum {
   StmtK,ExpK} NodeKind;
typedef enum {
   IfK,RepeatK,AssignK,ReadK,WriteK} StmtKind;
typedef enum {
   OpK,ConstK,IdK} ExpKind;

/* ExpType is used for type checking */
typedef enum 
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
递归下降分析法 一、实验目的: 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验说明 1、递归下降分析法的功能 词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G的每个非终结符号U构造一个递归过程,不妨命名为U。 U的产生式的右边指出这个过程的代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 三、实验要求 (一)准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dc 输出的格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束的符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 2.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。 (四)程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值