编译原理 四

1. 梳理第二章的内容,写一篇理解与总结。

当我们要描述一种语言时,需要给出这种语言的所有句子,当句子的数目是有限可数时,就要都列出来;当句子
是一个无穷集,也就是无限不可数时,就要给出可以表示它们的结构的描述方法或者说,句子的组成规则。这种
规则就是文法。

从形式上用于描述和规定结构的称为文法(或者说语法)

一、文法的定义:

文法G定义为一个四元组(VN,VT,P,S),其中,
VN为非终结符集合,VT终结符集合;P是产生式结合;S称为识别符或开始符号,也是一个非终结符,至少要在一
条产生式的左边出现。

出现了几个名词,终结符、非终结符、产生式、识别符/开始符号等。下面具体聊聊这些名词和文法的定义。

VN是非终结符集合,非终结符N指的是可以被拆分的字符或串,它采取递归定义:一个非终结符是由终结符和至少
一个非终结符组成的串,相对应的,终结符就是不可拆分的,语言中要用到的字符。所以VN中所存储的是所有的
非终结符,VT中存储的是所有的终结符。

简单点讲:终结符就是推导到终结符时,不可再推导下去;而非终结符可以继续推导下去。

集合P存储的是所有的产生式。那什么是产生式呢?产生式就是推导规则。比方说 a→b 就是一条规则,即一条产
生式,可以通过 a 推导出 b。

对照前面说的非终结符和终结符,就应该可以理解,在产生式左边的只能是非终结符,因为终结符不能再推导下
去。而右边可以有终结符和非终结符。用数学的集合知识表示就是:

产生式的形式是α → β,α称为产生式左部,β称为产生式右部,α属于VN,β∈(VN∪VT)*,α∉ε

最后是S,S是开始符号,也就是最开始的那条产生式左边的非终结符,一切的推导从它开始。比方说

a → b
b → c|d
c → e
其中,a → b就是最开始的产生式,a就是最开始的非终结符,就是S。S是非终结符,所以S∈VN。
二、文法与语言的推导

举个例子:
G(E):

E=> E + T | T

T=>T * F | F

F=>(E)| i
求i*i+i的推导式:
E=>E+T
=>T+T
=>T*F+T
=>F*F+T
=>i*F+T
=>i*i+T
=>i*i+F
=>i*i+i
同理从右往左一个个元素的换算就是右推导了。
三、句型、句子
对于文法G[S]:
如果: S=>a,则a称为G的一个句型,
开始符号是最简单的句型。
如果:a是G[S]的一个句型,且a属于VT,
则a称被称为G[S]的一个句子,
也就是说句子是全部有终结符组成的句型。
四.语法分析树与二义性
我们发现从一个句型到另一个句型的推导过程不是唯一的。例如从E+E->i+i,存在两个推导过程:

E+E->E+i->i+i 最右推导,每个推导过程都是从最右边的非终结符号的替换开始
E+E->i+E->i+i 最左推导,每个推导过程都是从最左边的非终结符号的替换开始
当然为了对句子的结构进行一个确定性的分析,我们一般只考虑最左推导或者最右推导。

前面我们提到过用一种树形的图示来表示这个句型的推导过程,这棵树就被称为”语法分析树“,简称”语法树“。
对于一个文法,如果它的某些句子对应两棵不同的语法树,这个文法就属于“二义性文法”。
注意,文法的二义性和我们通常所说的语言的二义性不同,我们可能有两个不同的文法G1,G2,一个是二义性,
一个是非二义性,但是可能L(G1) = L(G2)。对于程序语言来说,我们常常希望它的文法是非二义性的,但
是,只要我们能够控制和驾驭文法的二义性,文法二义性的存在也不一定是坏事。

现在已经证明了,文法二义性是不可判定的。也就是说不存在一个算法,在有限步骤内算出一个文法是不是二义
性的。我们能做的事儿,就是找一组充分条件来说明非二义性。比如,规定运算符号的优先级和结合性。

2. 尝试写出PL/0 语言的文法。(或者你认为比较好的语言规则)

整数n

标识符i

表达式e

条件语句

赋值语句

复合语句

函数

程序

...
答:
整数n <整数n>::=int <标识符n>=<无符号整数>|<有符号整数>;
标识符i <标识符i>::= <字符类型> <字母|数字>;
表达式e <表达式> ::= [+ | -] <项> { <加法运算符><项>}
条件语句 <表达式>{语句} ;|<表达式>{句子}
赋值语句 <标识符>=<无符号整数>|<有符号整数>;
<复合语句> ::= BEGIN <语句> {;<语句>} END
函数 <数据类型> <标识符>(形式参数...){句子;...}
<程序> ::= <分程序>.
<分程序> ::= [<常量说明部分>] [<变量说明部分>]
[<过程说明部分>] <语句>
...

原文地址:https://www.cnblogs.com/huangwenshuo/p/11588342.html

时间: 2024-11-01 21:27:06

编译原理 四的相关文章

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(四)结语

四则运算编译器,虽然说功能很简单,只能编译四则运算表达式.但是编译原理前端部分几乎都有涉及,词法分析,语法分析,还有代码生成. 再复杂的编译器.再简单的编译器,功能上是差不多的,只是复杂的编译器实现上会更困难. 这个系列的文章是为了帮助你入门,在这个基础上再去看编译原理相关书籍,不至于打瞌睡. 如果你对编译原理很有兴趣,并且想更深一步的学习,在这里强烈推荐你看一本书--我心目中的神书--<计算机系统要素-从零开始构建现代计算机>. 这本书神在哪? 神在它通俗易懂,对小白足够友好,但又不过分肤浅

编译原理(四)语法分析之自顶向下分析

语法分析之自顶向下分析 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本过程分析 1. 一般方法:对任一字符串,试图用一切可能的方法,从树根节点(开始符号)出发,根据文法自上而下地为输入符号串建立一棵语法树.直观理解为从开始符号出发,依据规则建立推导序列,最后推至目标字符串. 2. 特点:分析过程是带有预测的,是一种试探过程.试探失败就会出现回溯问题,降低了分析的效率. 3. 存在问题:左递归问题.回溯问题. 问题一:左递归问题 1. 左递归文法:文法规则中有形如 \(

python实现算术表达式的词法语法语义分析(编译原理应用)

本学期编译原理的一个大作业,我的选题是算术表达式的词法语法语义分析,当时由于学得比较渣,只用了递归下降的方法进行了分析. 首先,用户输入算术表达式,其中算术表达式可以包含基本运算符,括号,数字,以及用户自定义变量. 词法分析,检查单词变量是否正确:语法分析,检查算术表达式语法是否正确并输出生成语法树:语义分析,输出四元表达式. 最终效果图: 例如输入: 词法分析结果: 语法分析结果: 语义分析结果: 算术表达式的组成语法如下: 无符号整数 = 〈数字〉{〈数字〉} 〈标识符〉= 〈字母〉{〈字母

编译原理的实验报告一

实验一 词法分析程序实验 专业 商软2班   姓名 黄仲浩  学号 201506110166 一. 实验目的      编制一个词法分析程序. 二. 实验内容和要求 输入:源程序字符串 输出:二元组(种别,单词符号本身). 三. 实验方法.步骤及结果测试 源程序名:bianyiyuanli.c 可执行程序名:bianyiyuanli.exe 原理分析及流程图 通过一些for循环和while循环进行一个个的翻译. 源程序如下: #include<stdio.h> #include<stri

用antlr4来实现《按编译原理的思路设计的一个计算器》中的计算器

上次在公司内部讲<词法分析--使用正则文法>是一次失败的尝试--上午有十几个人在场,下午就只来了四个听众. 本来我还在构思如何来讲"语法分析"的知识呢,但现在看来已不太可能. 这个课程没有预想中的受欢迎,其原因可能是: 1.课程内容相对复杂,听众知识背景与基础差异比较大. 2.授课技巧不够,不能把复杂的知识简单化的呈现给基础稍差一点的人. 针对这两个可能的原因,我要尝试做出以下调整: 1.使用antlr来实现词法和语法的部分. 2.暂时把"编译"过程改为

编译原理 (预处理&gt;编译&gt;汇编&gt;链接)(转)

一般高级语言程序编译的过程:预处理.编译.汇编.链接.gcc在后台实际上也经历了这几个过程,我们可以通过-v参数查看它的编译细节,如果想看某个具体的编译过程,则可以分别使用-E,-S,-c和 -O,对应的后台工具则分别为cpp,cc1,as,ld.下面我们将逐步分析这几个过程以及相关的内容,诸如语法检查.代码调试.汇编语言等. 1.预处理 预处理是C语言程序从源代码变成可执行程序的第一步,主要是C语言编译器对各种预处理命令进行处理,包括头文件的包含.宏定义的扩展.条件编译的选择等.打印出预处理之

wex5 教程 前端UI编译原理与记事本编辑

一 前言 wex5页面,与html页面有何差异?两者之前的关系是什么?是如何完成转译的? 能否像编辑html那样用记事本来修改w页面? wex5前端UI在云部署后能否在云端进行二次编辑,而不需要在wex5编辑器里修改后再次上传?? 带着这些问题,重新认识wex5的UI设计与编译原理,有助于我们分离前端开发. 二 页面结构分析: wex5页面由w.js,css三个页面构成,具体功能与对应关系如下: 三 编译后页面结构 1 在公有云部署时,要将wex5页面进行编译,得到部署需要的Native下的ww

[编译原理学习]词法分析

此前一直没能系统完整地学过编译原理,只有很粗浅的理解,虽然其实对工作里的任务也没啥影响,但总觉得缺了一大块知识,加上对所谓程序员三大浪漫(编译器,操作系统,图形学)的向往,所以最近跟着网易云课堂推出的计算机专业课程来学习编译原理.无奈生性懒惰,常常下班之后觉得累了,打打游戏啊看看视频啊,拖延症就犯了.......所以在这里打算将学习的过程,心得记录下来,也算是对自己的一个督促.课程传送门http://mooc.study.163.com/learn/USTC-1000002001#/learn/

Android7.0 Ninja编译原理

############################################# 本文为极度寒冰原创,转载请注明出处 ############################################# 引言 使在Android N的系统上,初次使用了Ninja的编译系统.对于Ninja,最初的印象是用在了Chromium open source code的编译中,在chromium的编译环境中,使用ninja -C out/Default chrome命令,就可以利用源码编译出