[编译原理]如何判断某文法的二义性以及找到文法对应的语言

article/2025/10/14 19:09:58

随便说说

这学期开编译原理课了,觉得还挺有意思的,写点博客记录记录。

如何根据文法找到其对应生成的语言

如图所示,假设我们现在有文法如下:

�(�):�−>���|��

根据文法产生语言的定义,语言是文法产生的句子的全体,用集合表示如下:

�(�)={�|�⇒+�&�∈��∗}

而句子的定义则是由文法的开始符S出发,经过1步或有限步推导出来的符号串并且该符号串全部由终结符组成

在上述白板题目中,由文法可知,开始符为G,有两个产生式,分别是Z->aZb和Z->ab

采用递归的方式,任意组合两种产生式,进行一步或有限步的推导,使得声称式的右侧不含有非终结符。

终结符就是语言中不可再分的基本符号,例如一个语言的字母表

而非终结符也叫语法变量,代表语法实体或语法范畴,是一个一定的语法概念,可以是一个类、一个集合。

过程也就很简单了,如上图中白板所示即可,但最终需要归纳,因为有一种推导的右侧时刻会存在非终结符Z,所以可以无限添加a和b的数量。

如何判断某文法的二义性

判断二义性的前提是需要知道最左推导和最右推导。

最左推导的定义是,在我们每次使用产生式推导的过程中,肯定会遇到右侧存在非终结符的情况,非终结符会存在任意位置,其中如果我们每次推导都替换掉从右往左的第一个非终结符,那么本次推导就是一次最右推导,反之则为最左推导。

而判断文法的二义性则是在此基础上进行推导:

如果文法G[S]的一个句子能够找到两种不同的最左推导或最右推导,也就是说存在两棵不同的语法树,那么这个句子就是二义性的,而文法若存在一个有二义性的句子,那么这个文法也是二义性的。

假设有文法如下:

�[�]:�−>�� � �

�−>�� � � ���� �

�−>�

根据白板上书写的两种最右推导,可以知道句子if b if b a else a是个二义性的句子,因为有两种最右推导都可以最终得到这个句子,那么对应的这个文法也就是二义性的了。


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

相关文章

证明文法的二义性

例题 证明下面的文法是二义性的: S→ S A S | ( S ) | i A→ | * 证明步骤如下图 (是我自己做的所以不是很严谨) 证明文法二义性的过程 可以自己定义一个句型,我定义的是SS*S,偷了个小懒没有用到(S&…

C++ 多继承的二义性问题

多继承中的二义性问题 在一个表达式中,对函数或变量的引用必须是明确的,无二义性的。对于一个独立的类而言,其成员的标识是唯一的,对其访问不会有二义性问题。但是当类之间具有继承关系时,子类成员可能与父类成员重名&…

C++多继承中的二义性问题

在C中,派生类继承基类,对基类成员的访问应该是确定的、唯一的,但是常常会有以下情况导致访问不一致,产生二义性。 1.在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——…

二义性文法和无二义性文法

二义性文法是指一种产生式规则可以被解释成两种或更多种不同的语法结构的文法。这种文法会导致语言的歧义和不确定性,使得相同的语句可以有不同的解释。 以下是三个例子: S → aSb | ε 这个文法可以生成字符串"aaabbb",但是它有两…

如何消除文法的二义性

文法举例 显然,对于not p and q有两种推导方式 默认not优先级高于and,即(not p) and q 默认and优先级高于 not,即not(p and q) 先and再not先not再and 两种消除二义性的方法 简单来说,就是人为规定not\and\or的优先级即可 重写的文法相当于默…

C++多继承中二义性的解决方案

出现二义性的原因: 派生类在访问基类成员函数时,由于基类存在同名的成员函数,导致无法确定访问的是哪个基类的成员函数,因此出现了二义性错误。 1. 什么是多重继承的二义性 class A{ public:void f(); }class B{ public:void f(…

编译原理——证明文法的二义性(1)

目录 推导和语法树推导语法树 文法二义性 在证明文法的二义性之前,我们需要熟悉几个基本的概念。 推导和语法树 推导 这里的推导,简单的来说就是指根据给出的句型(句子),对文法进行推理变化最终得到句型&#xff08…

二义性

自然语言的二义性什么意思 面这个问题.很清楚的说明了自然语言的二义性.. 用红墨水写一个“蓝”字,请问,这个字是红字还是蓝字? 可能很少有人意识到,像红字和蓝字这样的词语都存在着二义性。可能是红色的字,也可能是“…

2.5.2 文法的二义性

2.5.2 文法的二义性 设有文法 G [ E ]: E → E E | E * E | ( E ) | i句子 i * i i 有两个不同的最左推导,对应两棵不同的语法树,见图 2.6 和图 2.7 。 最左推导 1 E ⇒ E E ⇒ E * E E ⇒ i * E E⇒ i * i E⇒ i * i i 最左推导 2 E ⇒ E * E ⇒ i * E⇒ i * E E⇒…

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

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

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

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

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

一、什么是二义性 在多继承的场景里,当父类中存在同名变量时,子类访问父类的同名变量,将出现二义性,因为编译器不知道你将要访问的是哪个父类中的变量。 举个例子: class A { public:int a; // B1,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数组去重这个问题,经常出现在面试题中,以前也写过一篇数组去重的文章,(JavaScript 数组去重的多种方法原理详解)但感觉代码还是有点不够简单,今天和大家再说两种方法,代码可是足…

ES6 Set() 数组去重

ES6 Set()去重 Set。它类似于数组,但是成员的值都是唯一的 通过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方法 贴上相关代码 打印后的结果 通过打印我们发现,确实实现了我们想要的效果。那么下面简单来解释一下。 1.Map对象是ES6提供的一个新的数据结构&…

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

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

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

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

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

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