编译原理(三)语法分析:3.二义性与二义性的消除

article/2025/10/14 20:36:58

文章目录

  • 一、二义性
    • 1.定义
    • 2.原因
  • 二、二义性的消除
    • 1.改写二义文法为非二义文法
      • (1)步骤
      • (2)例子
      • (3)缺点
    • 2.为文法符号规定优先级和结合性
    • 3.修改语言的语法(表现形式被改变)


【编译原理博客列表】》》》》》》


一、二义性

1.定义

定义3.7
若文法G对同一句子产生不止一棵分析树,则称G是二义的。

例3.7 句子id+id*id和id+id+id可能的分析树
E→E+E | E*E |(E)| -E | id

深度越深,越远离开始节点,优先级越高。
非终结符在终结符(如+)的左边是左结合,右边是右结合。
在这里插入图片描述

“悬空(dangling)else”问题
例3.8 条件语句 if x<3 then if x>0 then x:=5 else x:=-5
S → if C then S (1)
| if C then S else S (2)
| id := E (3)
C → E = E | E < E | E > E (4)…(6)
E → E + E | - E | id | n (7)…(10)

在这里插入图片描述
在这里插入图片描述

2.原因

原因:在产生句子的过程中某些直接推导有多于一种选择

注意:
明确 最 终 分 析 树 的 形 状 , 仅 与 文 法 有 关 , 而 与 推 导 方 法 无 关 \textcolor{red}{最终分析树的形状,仅与文法有关,而与推导方法无关}
一个句子有多于一棵分析树,是因为文法中缺少对文法符号优先级和结合性的规定

二、二义性的消除

消除文法二义的两种方法:
① 改写二义文法为非二义文法;
② 规定二义文法中符号的优先级和结合性,使仅产生一棵分析树。

左结合性:
对于A→αAβ,若A(左右都有的非终结符)在终结符(即终结符在β中)左边出现,则A产生式具有左结合性质。
如:

  • E → E + T是左结合(EA+是终结符)。
  • F → (E) | -F是右结合(FA-是终结符)

1.改写二义文法为非二义文法

(1)步骤

改写二义文法的关键步骤:

  • 划分优先级和结合性
  • 引入一个新的非终结符,增加一个子结构并提高一级优先级(优先级的判断);
  • 递归非终结符在终结符左边,运算具有左结合性,否则具有右结合性。

(2)例子

例3.10 改写二义文法
E→E+E | E*E |(E)| -E | id

  1. 优先级从低到高: [+][*][( ), -, id]
  2. 结合性:
    左结合[+, *]
    右结合[-]
    无结合[id]
  3. 非终结符与运算:
    E:+ (E产生式,左递归)
    T:* (T产生式,左递归)
    F:-,( ),id (F产生式,右递归)
E → E + T | T
T → T * F | F
F → (E) | -F | id

解决“悬空(dangling)else”问题
例3.8 条件语句 if x<3 then if x>0 then x:=5 else x:=-5
S → if C then S (1)
| if C then S else S (2)
| id := E (3)
C → E = E | E < E | E > E (4)…(6)
E → E + E | - E | id | n (7)…(10)

分析原因:if-then-else和if-then:在一个复合if语句中,可能then多于else,使得else不知与哪个then结合

一般原则是右结合,即else与其左边最靠近的then结合。
改写文法的根据是将S分为 完全匹配(MS)不完全匹配(UMS) 两类,并且在UMS中规定 else右结合

S  → MS 			   (1)| UMS			   (2)
MS → if C then MS else MS   (3)| id := E			   (4)
UMS→ if C then S		   (5)    (G3.5)| if C then MS else UMS  (6)	
C  → E = E | E < E | E > E  (7)...(9)
E  → E + T | T		   (10)...(11) 
T  → (E) | -T | id | n	   (12)...(15)

在这里插入图片描述

(3)缺点

  • 非终结符的引入,增加了推导步骤(分析树增高)
  • 更不容易理解

2.为文法符号规定优先级和结合性

YACC(生成 词法分析器 和 语法分析器 的工具)就是采用这种方法:

%left '+'
%left '*'
%right '-'
E  :  E '+' E | E '*' E | '-' E | '(' E ')' | id

简单

3.修改语言的语法(表现形式被改变)

① 明确给出结束标志,如Ada中用end if,于是有:

if x<3 then if x>0 then x:=5; end if; else x:=-5; end if;
if x<3 then if x>0 then x:=5; else x:=-5; end if; end if;

在这里插入图片描述
② 给表达式加括号,如Pascal中逻辑和算术运算:(a+b)>(c*d)


http://chatgpt.dhexx.cn/article/e0FxsDSd.shtml

相关文章

二义性和C++消除二义性

1.二义性 二义性的定义是&#xff1a;“如果文法G中的某个句子存在不只一棵语法树&#xff0c;则称该句子是二义性的。如果文法含有二义性的句子&#xff0c;则称该文法是二义性的。”&#xff08;该定义来自于百度百科&#xff09;用通俗的话讲&#xff0c;如果一句话或者一个…

C++ 二义性是什么?怎么解决?

一、什么是二义性 在多继承的场景里&#xff0c;当父类中存在同名变量时&#xff0c;子类访问父类的同名变量&#xff0c;将出现二义性&#xff0c;因为编译器不知道你将要访问的是哪个父类中的变量。 举个例子&#xff1a; class A { public:int a; // B1&#xff0c;B2 都…

ES6一维数组去重,合并去重方法分享

ES6去重的几个小方法 1.使用set方法 2.setArray.from() 3.filtermap 4、Array.fromsetflatsort 排序去重 flat:对数组进行扁平化处理 sort:排序 b-a:倒序 a-b:正序 5.数组合并去重

[记录]es6常用去重方法(数组、字符串)

数组去重 ES6 ES6以下方法除了代码简洁外,对于undefined和NaN也同样可以达到去重的效果 new Set()是ES6新增的数据结构,类似于数组,但它的一大特性就是所有元素都是唯一的,没有重复的值,我们一般称为集合,Set本身是一个构造函数,用来生成 Set 数据结构。 Set搭配扩展运算符 ……

JavaScript数组去重—ES6的两种方式

说明 JavaScript数组去重这个问题&#xff0c;经常出现在面试题中&#xff0c;以前也写过一篇数组去重的文章&#xff0c;&#xff08;JavaScript 数组去重的多种方法原理详解&#xff09;但感觉代码还是有点不够简单&#xff0c;今天和大家再说两种方法&#xff0c;代码可是足…

ES6 Set() 数组去重

ES6 Set()去重 Set。它类似于数组&#xff0c;但是成员的值都是唯一的 通过add()方法向 Set 结构加入成员 let arr [1,2,3,4,1,5,2,3]; var set2 new Set(); arr.forEach(item>{set2.add(item) }) console.log(set2); console.log(Array.from(set2));let str [测试1,测试…

ES6数组去重的三个简单办法

ES6数组去重的三个简单办法 简单说一下利用ES6实现数组去重的三个办法。 第一种: 利用Map对象和数组的filter方法 贴上相关代码 打印后的结果 通过打印我们发现&#xff0c;确实实现了我们想要的效果。那么下面简单来解释一下。 1.Map对象是ES6提供的一个新的数据结构&…

一文弄懂Python中的*args 和 **kwargs

1. 引言 在本文中&#xff0c;我们将讨论 Python 中的 *args 和 **kwargs 及其用法和示例。 闲话少说&#xff0c;我们直接开始吧。 2. 问题引入 在Python中写函数的时候&#xff0c;我们经常需要给函数传值&#xff0c;这些值被称为函数参数。 我们不妨来举个栗子&#xff…

**kwargs python_python中**kwargs怎么用?

1、使用两个星号是收集关键字参数&#xff0c;可以将参数收集到一个字典中&#xff0c;参数的名字是字典的 “键”&#xff0c;对应的参数的值是字典的 “值”。请看下面的例子&#xff1a;>>> def print_kwargs(**kwargs): ... print(kwargs) ... >>> pr…

Python技巧:​args 和 kwargs 原来这么强大

大家好&#xff0c;今天我给大家分享Python技巧&#xff1a;​args 和 kwargs的相关技巧。喜欢记得收藏、关注、点赞。 注&#xff1a;完整代码、资料、技术交流文末获取 现在args和 kwargs参数仍然是 Python 中非常有用的特性&#xff0c;而且理解它们的威力将使您成为更有效…

*args和**kwargs是什么意思

去面试的时候&#xff0c;做了一道笔试题——什么是*args和**kwargs&#xff0c;区别在哪里&#xff1f; 有点蒙&#xff0c;好像见过&#xff0c;但是不知道具体的意思。所以回来查了一下资料&#xff0c;做一下笔记。 总的来说&#xff0c;*args代表任何多个无名参数&#x…

埃及分数c语言设计,埃及分数(四)

最优分解 源程序 下面就是求埃及分数最优分解的 C 语言源程序 EgyptianFraction.c&#xff1a; 1: #include 2: #include 3: #include 4: 5: const int SIZE 64; 6: static int wp -1, bp -1; 7: static mpz_t z, w, work[SIZE], best[SIZE]; 8: static mpq_t q1, q2; 9:…

埃及分数问题

问题描述: 古埃及人喜欢用最少的分子为 1 的真分数来表示一个真分数&#xff0c;比如7 / 8 1 / 2 1 / 3 1 / 24 。设计程序把一个真分数表示为最少的埃及分数之和的形式。 思路&#xff1a; 首先要知道什么是真分数&#xff1a;真分数是指大于0小于1的所有分数。这些分数的特…

贪心算法之埃及分数问题

1.问题&#xff1a;给定一个分数&#xff0c;如7/8&#xff0c;我们可以把它表示为1/2 1/3 1/24&#xff0c;埃及分数问题即把一个真分数表示为最少的埃及分数之和的形式&#xff0c;输入一个真分数把其分解为埃及分数之和。 2.设计思路&#xff1a;设分数为a/b,则cb/a,db%a,…

【数模】相关性分析

相关性&#xff1a;如果一个变量的变化引起了另一个变量的变化 目录 一、四种基本变量 二、 相关性分析方法 1.Pearson相关系数 2.Spearman 等级相关系数 3.Kendall tua-b 等级相关系数 4.卡方检测 5.Eta系数 *SPSS操作 三、偏相关 1.SPSS操作 2.偏相关系数和检验&…

数学建模-相关性分析及热力图

目录 一、相关性分析 二、相关性分析实例 三、三种相关系数 3.1 Pearson线性相关系数 3.2 Kendall tau系数 3.3 Spearman相关系数 4、Matlab代码 4.1 Pearson 显著性检验 4.2 Pearson 相关系数矩阵 4.3 Kendalltau相关系数矩阵 4.4 Spearman相关系数矩阵 5、代码…

R语言基础——简单相关性分析(1)

简单相关性分析&#xff08;1&#xff09; 简介1. 协方差和相关系数1.1 协方差1.2 相关系数 2. 相关性分析参考 简介 初次接触相关性分析&#xff0c;在摸索中前进&#xff0c;也顺便将笔记记录下来&#xff0c;未雨绸缪嘛&#xff01; 简单来说&#xff0c;相关性分析就是衡量…

分类变量、有序变量与数值变量相关性分析方法总结及 R 语言应用

文章目录 一、分类 & 分类相关性分析二、有序 & 有序相关性分析三、数值 & 数值相关性分析四、分类 & 有序相关性分析五、分类 & 数值相关性分析六、有序 & 数值相关性分析 本文全部假设显著性水平为0.05&#xff0c;特殊说明的除外。 一、分类 & …

数据分析方法和思维—相关性分析法

01 写在前面 在数据分析的问题中, 经常会遇见的一种问题就是相关的问题, 比如抖音短视频的产品经理经常要来问留存&#xff08;是否留下来&#xff09;和观看时长, 收藏的次数, 转发的次数, 关注的抖音博主数等等是否有相关性, 相关性有多大。 因为只有知道了哪些因素和留存比较…

python相关性分析_python实践统计学中的三大相关性系数,并绘制相关性分析的热力图...

本文首发地址&#xff1a; https://yishuihancheng.blog.csdn.net/article/details/83547648 欢迎关注我的博客【Together_CZ】&#xff0c;我是沂水寒城&#xff01; 今天我简单地使用了scipy模块进行了统计学中三大相关性分析方法&#xff08;皮尔森相关性系数、斯皮尔曼相…