编译原理-消除左递归的方法

yizhihongxing

下面是关于“编译原理-消除左递归的方法”的完整攻略:

1. 什么是左递归

在编译原理中,左递归是指文法中存在形如 $ \rightarrow A\alpha$ 的产生式,其中 $A$ 是非终结符,$\alpha$ 是由终结符和非终结符组成的字符串。左递归会导致递归下降分析法无法正常工作,因此需要消除左递归。

2.除左递归的方法

消除左递归的方法有两种:直接左递归消除法和间接左递归消除法。

直接左递归消除法

直接左递归消除法是指将文法中的左递归产生式换为等价的右递归产生式。具体步如下:

  1. 对于形如 $A \rightarrow A\alpha_1|\cdots|A\alpha_n|\beta_1|\cdots|\beta_m$产生式,将其拆分为两个产生式 $A \rightarrow \beta_1A'|\cdots|\beta_mA'$ 和 $A' \rightarrow \alpha_1A'|\cdots|\alpha_nA'|\epsilon$。
  2. 对于新产生的 $A'$ 非终结符,将其加入到原有的非结符集合中。

下面是一个示例说明:

假设有以下文法:

E -> E + T | T
T -> T * F | F
F -> ( E ) | id

其中,产生式 $E \rightarrow E + T$ 是左递归产生式。可以使用直接左递归除法将其转换为等价的右递归产生式:

E -> TE'
E' -> +TE' | ε
T -> FT'
T' -> *FT' | ε
F -> ( E ) | id

示例1:直接左递归消除法

假设有以下文法:

``S -> S a | b


该文法中存在左递归产生式 $S \rightarrow Sa$,需要使用直接左递归消除法进行消除。

1. 将 $S \rightarrow Sa$ 拆分为 $S \rightarrow bS'$ 和 $S' \rightarrow aS'| \epsilon$。
2. 将新产生的 $S'$ 非终结符加入原有的非终结符集合中。
3. 将原有的产生式 $S \rightarrow Sa$ 替换为 $S \rightarrow bS'$ 和 $S' \rightarrow aS'| \epsilon$。

最终得到的文法为:

S -> bS'
S' -> aS' |


### 间接左递归消除法

间接左递归消除法是指将法中的间接左递归转换为直左递归,然后再使用直接左递归消除法进行消除。具体步骤如下:

1. 对于形如 $A \rightarrow B\alpha_1|\cdots|B\alpha_n|\beta_|\cdots|\beta_m$ 的产生式,其中 $B$ 是非终结符,将其分为两个产生式 $A \rightarrow \beta1B'|\cdots|\beta_mB'$ 和 $B' \rightarrow \alpha_1|\cdots|\alpha_n$。
2. 对于新产生的 $B'$ 非终结符,检查其是否存在左递归如果存在,则使用直接左递归消除法进行消除。

下面一个示例说明:

假设有以下文法:

S -> Aa | b
A -> | Sd | ε


其中,产生式A \rightarrow Ac$ 是间接左递归产生式。可以使用间接左递归消除法将其转换为等的直接左递归产生式:

S -> Aa | b
-> SdA' | ε
A' -> cA' ε


后再使用直接左递归消除法进行消除,得到:

-> Aa | b
A -> SdA | ε
A' -> cA' | ε
S -> bS' | aA'
S' -> dA' | ε
```

3. 结论

消左递归是编译原理中的一个重要概念,可以使用直接左递归消除法和间接左递归消除法进行除。以上是关于“编译原理-消除左递归的方法”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:编译原理-消除左递归的方法 - Python技术站

(2)
上一篇 2023年5月7日
下一篇 2023年5月7日

相关文章

  • MySQL中使用去重distinct方法的示例详解

    MySQL中使用去重distinct方法的示例详解 在MySQL中,distinct方法可以用来去重,即只显示不重复的数据。本文将详细介绍在MySQL中使用distinct方法的方法和示例。 语法格式 SELECT DISTINCT column_name, column_name FROM table_name; 参数说明 column_name: 数据库…

    other 2023年6月25日
    00
  • Java单例模式的讲解

    Java单例模式的讲解 单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供全局访问点。在Java中,实现单例模式有多种方式,下面将详细讲解其中两种常见的实现方法。 1. 饿汉式单例模式 饿汉式单例模式是指在类加载时就创建实例对象,并且保持全局唯一。以下是一个示例代码: public class Singleton { private stati…

    other 2023年8月6日
    00
  • 什么是人机交互?

    人机交互(HCI,Human-Computer Interaction)是指人类和计算机之间进行交互和通信的过程。这个领域涉及到许多不同的学科,包括计算机科学、心理学、人类学和设计。本文将详细讲解人机交互的完整攻略,包括设计过程、实现细节和测试方法。 1. 设计过程 设计过程是人机交互的核心,它涉及到理解用户需求、设计用户界面、实现系统功能和评估用户满意度。…

    其他 2023年4月19日
    00
  • js插件dropload上拉下滑加载数据实例解析

    JS插件Dropload上拉下滑加载数据实例解析 什么是Dropload插件? Dropload是一款基于jQuery开发的下拉和上拉刷新的插件。该插件可以实现在列表或弹出层中,通过上拉或下拉手势来加载更多的数据。 如何使用Dropload插件? 首先,需要在页面中引入jquery和dropload的js文件,然后在页面中初始化dropload,如下所示: …

    other 2023年6月25日
    00
  • Java线程和操作系统线程的关系解读

    Java线程和操作系统线程的关系解读 Java语言的线程概念是建立在操作系统线程概念之上的,因此Java线程和操作系统线程之间存在着紧密的联系和依赖关系。 Java线程 Java中线程是由Java虚拟机(JVM)进行管理和调度的。每个Java线程都是由JVM虚拟机中一个线程对象(Thread)来描述的,线程对象需要包含下述属性: 线程状态:Java线程在JV…

    other 2023年6月27日
    00
  • 获取控件大小和设置调整控件的位置XY示例

    获取控件大小和设置调整控件位置XY是页面布局中非常重要的操作。下面提供两个示例,分别介绍如何获取控件大小以及如何调整控件的位置。 示例1:获取控件大小 获取控件大小的方法可以通过JavaScript中的offsetWidth和offsetHeight属性来实现。下面是一个示例代码,可以获取DIV控件的宽度和高度: <div id="myDiv…

    other 2023年6月27日
    00
  • Shopee在React Native 架构方面的探索及发展历程

    Shopee在React Native 架构方面的探索及发展历程 背景 React Native是由Facebook推出的一种移动应用开发框架,旨在使用JavaScript和React来构建跨平台的移动应用程序。目前React Native在全球范围内拥有众多的支持者和使用者,其在移动开发领域十分流行。Shopee作为一家知名的电商公司,也深入研究和探索了R…

    other 2023年6月27日
    00
  • Kotlin协程概念原理与使用万字梳理

    Kotlin协程概念原理与使用 什么是协程 协程是一种轻量级的线程,它可以在一个线程中同时执行多个任务,但是并不会阻塞线程。协程可以在代码中看起来像是普通的顺序执行的代码,但是可以在其中插入暂停和唤醒其他协程的代码。 协程与线程的区别 协程和线程都是并发执行的工具,但是它们之间有几个关键的区别: 协程是在应用程序内部实现的,而线程是由操作系统实现的。 协程更…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部