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

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

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. 结论

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

阅读剩余 54%

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

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

相关文章

  • 详解Centos/Linux下调整分区大小(以home和根分区为例)

    下面我将详细讲解如何在CentOS/Linux系统下调整分区大小(以home和根分区为例)。 确认分区信息 首先,在调整分区大小前,我们需要确认已有的分区基本信息。在终端中输入以下命令: lsblk 该命令将列出当前系统中所有的块设备及其分区信息。 卸载挂载分区 接着,我们需要卸载将要进行操作的分区。在本例中,我们将调整/home和/根分区的大小。在终端中输…

    other 2023年6月28日
    00
  • SpringBoot如何读取配置文件中的数据到map和list

    首先,我们需要在SpringBoot项目中引入配置文件。SpringBoot提供了一个默认的application.yml或application.properties文件来存储配置信息。 在application.yml文件中,我们可以使用如下形式定义一个Map: map-config: key1: value1 key2: value2 key3: va…

    other 2023年6月25日
    00
  • Xcode中Info.plist字段详解

    下面是详细的讲解: Xcode中Info.plist字段详解 什么是Info.plist文件 Info.plist 是苹果开发者必须添加到其应用程序捆绑包中的一个文件。这个文件是应用程序的“属性清单”,列出了应用程序所需的所有信息。 Info.plist文件的常用字段 Info.plist 中常用的字段有很多,下面分别介绍一下其中比较常用的几个: CFBun…

    other 2023年6月25日
    00
  • Linux终端命令行的常用快捷键详解

    标题:Linux终端命令行的常用快捷键详解 正文: 快捷键是Linux终端命令行的一项非常重要的功能,能够提高命令行操作的效率。下面将对常用的Linux终端命令行快捷键进行详细讲解。 常用快捷键 控制命令输入 Ctrl + a:将光标移动到命令行的开头。 Ctrl + e:将光标移动到命令行的末尾。 Ctrl + u:删除从光标位置到行首的所有内容。 Ctr…

    other 2023年6月26日
    00
  • macbrew卸载

    Macbrew卸载 Macbrew是一款Mac上常用的软件包管理器,用户可以通过它安装各种应用程序。在一些情况下,用户想要卸载Macbrew,本文将介绍如何卸载Macbrew。 步骤一:打开终端 点击Dock栏上的应用程序,找到“终端”,并打开。终端是Mac OS X中的命令行控制台,用户可以在其中执行许多操作。 步骤二:卸载Macbrew 在终端中输入以下…

    其他 2023年3月29日
    00
  • react脚手架如何配置less和ant按需加载的方法步骤

    当我们使用React构建应用程序时,经常需要使用Less来实现样式和Ant Design来使用React组件。为了提高项目的性能,我们需要将Ant Design的组件进行按需加载,这样可以避免打包生成体积较大的文件。以下是配置步骤: 安装依赖 首先需要安装React、React-DOM、Ant Design、Less、Less-loader: npm ins…

    other 2023年6月26日
    00
  • MyBatis 如何获取子类的属性

    要获取子类的属性,最简单的做法就是使用反射机制。MyBatis也提供了相应的API来支持反射获取子类的属性。具体步骤如下: 添加MyBatis的反射依赖包。 在Maven项目中添加依赖: <!– MyBatis –> <dependency> <groupId>org.mybatis</groupId> &…

    other 2023年6月26日
    00
  • linuxos

    以下是详细讲解“Linux操作系统的完整攻略”的标准Markdown格式文本,包含两个示例说明: Linux操作系统的完整攻略 Linux是一款开源的操作系统,广泛应用于服务器、嵌入式设备和个人电脑等领域。本攻略将介绍Linux操作系统基本概念、常用命令和示例说明等内容。 基本概念 Linux操作系统是一款基于Unix的操作系统,具有开源、免费、稳定、安全等…

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