编译原理基本概念和术语
一、字母表(有穷符号集合)
1.1 字母表定义
字母表也即符号集,用∑
表示,它是一个包含各种符号的有穷非空集合。
以汉语为例,汉语字母表就是各种汉字、数字、标点符号的集合;以英语为例,英语字母表就是各种字母、数字、标点符号的集合…那么到了编程,字母表就可能是字母、数字、各种专用符号和保留字了。
1.2 字母表上的运算:
- 乘积
- n次幂
- 正闭包
- 克林闭包
二、符号串/串
2.1 符号串相关定义:
符号串是对于字母表来说的一个概念,字母表的符号串指的就是由字母表中各个字符组成的一个有穷序列。
注意这里的“有穷”,指的是符号串本身是由有穷个符号组成,但是符号串的个数是无穷多的(组合方式不同)。
以字母表 ∑={0,1} 为例,它的符号串就有:0,1,00,01,10,11,000 等等。
符号串的长度指的是符号串符号的个数,以 m = 000 为例,|m|= 3。
空符号串 ε 长度为 0,表示不包含任何符号,类似于编程中的空字符串 “”。所以有 εm = mε= m。
以 m = abc 为例,它的头是 ε,a,ab,abc;它的尾是 ε,c,bc,abc。而它的固有头不考虑末尾符号 c,固有尾不考虑首部符号 a。
2.2 符号串的运算:连接、方幂
- 符号串的连接:连接就是两个字符串顺序拼接,比如 x = abc,y = def,那么 xy = abcdef。
- 符号串的方幂:如果一个符号串由多个重复符号构成,如何方便地表示它呢?
比如 y = xxxx…xxxx(n 个 x),那么就可以写成 y = x^n,此时 y 就是 x 的方幂。这点和数学是一样的。不过要注意,x^0 ≠ 1 = ε。
串s的n次幂:将n个s连接起来
三、闭包
以字母表 ∑ = {a,b} 为例,任何由它的符号串作为构成元素的集合,都可以称作字母表的符号串集合。比如说 {ab},{abab,ababab} 等。
两个符号串集合的乘积定义为 AB = {xy| x∈A且y∈b},其实就是笛卡尔积。
一般的字符串集合可能并不能囊括一个字母表的所有符号串,但是有一种集合却能包含所有的符号串,这种特殊的集合称为闭包,记作 ∑*。
*其实就是全选的意思(联想 CSS 中的通配选择符就好理解了)。
∑* = {ε,a,b,ab,ab,ba,aba,aab......} = ∑^0 ∪ ∑^1 ∪ ∑^2 ∪......∪ ∑^n
要注意的是,闭包也包含了空符号串。
将闭包中的空符号串去掉,就成为了正闭包,也即 ∑+。
显然:∑*= ∑^0 ∪ ∑+,∑+ = ∑∑* = ∑*∑。
四、文法
4.1 文法在语言体系中的位置
语言包括语法和语义两个方面,但是语法和语义都是比较抽象的东西,所以我们需要借助一些工具来阐述它们。以语法来说,文法就是阐述它的一个工具。
4.2 文法的形式定义
文法是描述语言语法结构的形式规则。它的形式化定义是一个四元组,即 :
下面我们先给出一个自然语言的例子,然后借此来解释四元组的各个成分都是什么。
<句子> → <主语> <谓语><主语> → <代词> | <名词><谓语> → <动词><代词> → 你 | 我 | 他<名词> → 张三 | 教师 | 大学生<动词> → 教书 | 学习
(1)VT:
VT 指的是终结符集合。终结符即 terminal symbol,它是文法所定义的语言的最基本符号,这意味着一个终结符不可再细分(注意“终结”这个词)。在编程语言中,终结符其实就是之前提到的 token,比如保留字、运算符、界符等这些最最基本的符号。
以上面为例,VT ={ 你,我,他,张三,教师,大学生,教书,学习 }。
终结符一般用小写字母表示。
终结符符号约定:
- 字母表中排在前面的小写字母:如a,b,c
- 运算符
- 标点符号
- 数字
- 粗体字符串:如id,if
(2)VN:
VN 指的是非终结符集合。非终结符即 nonterminal symbol,它是用来表示语法成分的符号,有时候也称为“语法变量”。在编程语言中,我们可以说表达式或者赋值语句就是一个非终结符,因为它可以继续细分为多个 token。
以上面为例,VN ={ <句子>,<主语>,<谓语>,<代词>,<名词>,<动词> }。
非终结符的“非终结”,就是说“还没有到尽头”,还可以继续拆分,一般用 <> 括起来。
非终结符一般用大写字母表示。
终结符和非终结符统称为文法符号
VT∪VN :文法符号集
非终结符符号约定:
- 字母表中排在前面的大写字母:如A,B,C等
- 字母S
- 小写,斜体的名字:如expr,stmt等
- 代表程序构造的大写字母:如E(表达式),T(项),F(因子)等
(3)P:
P 即 production,指的是产生式集合。终结符和非终结符的转换依靠的就是产生式(或者说生成式,推导规则)。产生式形如 a → β (或者 a : : = β ,这种表示方法即巴科斯范式 ),意思是将 a 定义为 β。a 称为产生式左部,它是非终结符集合的一个元素;而 β 称为产生式右部,它是终结符和非终结符并集的一个元素。
(4)S:
S 即 start symbol,指的是开始符号(识别符号)。它是最开始的那条产生式的左部,一切的推导都是从它这里开始进行的,可以认为它就是最大的那个成分。所以也注定了 S 必须在 P 中至少作为某一条产生式的左部(不然无从推导)。
以上面为例,S = <句子>。
4.3 文法更简洁的形式化定义
假如现在有文法 G =({S,A,B},{0,1},P,S),
其中,P = { S → 0A,S → 1B,A → 1B,B → 1 }。
是否有更简便的方法来表示它呢?事实上,这里仅从产生式集合 P 来看,完全可以在不引起歧义的情况下推断出终结符号集,非终结符号集以及开始符号。这意味着我们可以将这三者省略,仅用产生式集合表达文法本身,也即:
G:
S → 0A
S → 1B
A → 1B
B → 1
B → 0
更进一步地,我们发现部分产生式的左部都是一样的,所以可以继续简写为:
G:
S → 0A | 1B
A → 1B
B → 1 | 0
此时,0A 或者 1B 称为 S 的候选式(candidate),1 或者 0 称为 B 的候选式。
4.4 推导
(1)直接推导/替换/重写:
用产生式的右部替换产生式的左部。
所有的产生式实际上都是一个直接推导。
(2)推导:
推导指的是从文法的开始符号出发,反复连续地使用产生式,对非终结符施行替换和展开,最终得到一个仅由终结符构成的符号串,推导过程的每一步都是一个直接推导。
还是以上面的文法为例,那么就有 S ⇒ 0A ⇒ 01B ⇒ 011,这个序列就是从 S 到 011 的一个推导,或者说 S 可以推导出 011。
序列可以简写为 S +⇒ 011,表示经过一步或者多步推导,
而 S *⇒ 011 表示经过 0 步或者多步推导。
所以,S *⇒ 011 要么是 S = 011,要么是 S +⇒ 011。
(3)最左/最右推导:
推导的过程并不是唯一的。对于任何一步 α ⇒ β,如果都是对 α 中的最左非终结符进行替换,那么就说最左推导,反之就是最右推导。
4.5 句型、句子、语言
- 句型:如果 S *⇒ a,开始符号 S 可以推导得到某个符号串,那么这个符号串 a 就称为句型。
一个句型中既可包含终结符,又可包含非终结符,也可是空串。
以上面文法为例,0A ,01B,011 … 都是句型
句型的短语和直接短语:
2. 句子:在推导之初,句型可能既包含终结符也包含非终结符,但最终肯定只剩下终结符构成的符号串,此时这个符号串就称为句子。
句子是不包含非终结符的句型
以上面文法为例,011 就是句子。
- 语言:文法产生的句子的全体就构成了语言,记作L(G)。
以上面文法为例,L(G) = { 011,11 }。
五、语法分析树与文法的二义性
我们可以借助语法分析树(这里的语法分析树是具体语法树,即 parse tree,不是抽象语法树)这个结构来描述句型的推导。
比如给定文法 G:G = ( {S,A},{a,b},P,S ),其中 P ={ S → aAS,A → SbA,A → SS,S → a,A → ba }
可以这样推导出句子 aabbaa:S ⇒ aAS ⇒ aSbAS ⇒ aabAS ⇒ aabbaS ⇒ aabbaa
那么如何用分析树表达这个句子呢?如图所示:
用根节点代表开始符号,随着推导的进行,当某个非终结符被它的候选式所替换时,这个非终结符的相应结点就会产生下一代子结点,以此类推。
有时候,对于某个句子,由于它的推导过程不唯一,所以会导致它的分析树也不唯一。
之前的例子中,我们给定了文法 G:E → E + E | E * E | (E) | i,由这个文法推导出句子 (i * i + i),实际上有两种方式:
E ⇒ (E) ⇒ ( E + E ) ⇒ ( E + i ) ⇒ ( E * E + i ) ⇒ ( E * i + i ) ⇒ ( i * i + i )
E ⇒ (E) ⇒ (E * E ) ⇒ ( i * E ) ⇒ ( i * E + E) ⇒ ( i * i + E) ⇒ ( i * i + i )
对应地有两种分析树:
由于这个文法存在着某个句子对应着两棵不同的分析树,所以这个文法是二义(歧义的。
显然,程序语言不能出现歧义。消除歧义的方法之一是改写语法,但这种改写非常困难;另一种方法就是引入优先级 ,利用符号的优先级来选择需要的推导方式。
作为描述程序语言的上下文无关文法,我们对它还有一些限制:
- 文法中不包含形如 P → P 的产生式
- 每个非终结符一定可以被用到,或者本身被 S 推导得到,或者本身推导得到其它终结符串。
六、文法类型
乔姆斯基把文法划分为四种类型,这四种类型层层增强,越到后面限制越大。
(1) 0 型文法(短语文法/无限制文法)
0 型文法也叫短语文法。设 G = { VN, VT , P , S },如果它的每个产生式 α→β 都满足:
“α∈(VN∪VT)* 且至少含有一个非终结符,而 β∈(VN∪VT)*
其中,VN∪VT 代表的是终结符合集和非终结符号集的并集,注意这同样是一个字母集,所以外面加上星号,就成为我们开篇所说的字母集的闭包。也就是说,产生式的左部或者右部,必须是由终结符和非终结符构成的符号串。
(2) 1 型文法(上下文有关文法)
1 型文法也叫上下文有关文法。在 0 型文法的基础上加以限制,规定对于每一个 α→β,都必须满足 |α| <= |β|。也就是说,产生式左部符号串长度必须小于等于右部符号串长度。
这里要注意一个特例就是:α → ε,虽然左部长度一定大于右部长度,但它仍然符合 1 型文法。
(3) 2 型文法(上下文无关文法)
2 型文法也叫上下文无关文法。在 1 型文法的基础上加以限制,规定对于每一个 α→β,都必须满足 α 是一个非终结符。也就是说,产生式左部必须得是一个非终结符。
(4) 3 型文法(正则文法)
3 型文法也叫正规文法。在 2 型文法的基础上加以限制,规定对于每一个 α→β,要么必须满足 A→ α | αB(右线性),要么必须满足 A→ α | Bα(左线性)。这里的 AB 代表非终极符号。
参考文章:
- 一篇微信公众号的文章
- 哈工大编译原理课的PPT
编译原理基本概念和术语相关推荐
- 编译原理 --- 语法分析概念,自上而下分析面临的问题以及如何消除左递归问题
第一部分 --- 语法分析基本概念 1.上面这个箭头 --> 符号表示的意思是P被 α 定义 A是一个非终止符,γ是一个和α,β属于同一个集合的元素 1.一个双箭头符号表示的是直接推出,而一个双 ...
- 句型与句子,编译原理基本概念
字母表:符号的有限集合. 记作: Σ 例如:{a, b, - , x, m} 字符串(符号串): 通常我们用到建立在 Σ 上的字符串:有穷的符号序 列. 例如:对于 Σ={a, b, c}, &quo ...
- Scons环境搭建和编译原理概述及嵌入式开发常用模板
Scons环境搭建和编译原理概述及嵌入式开发常用模板 Scons是用python实现的一个类似makefile的软件构建工具.其官网是SCons: A software construction to ...
- 前端零基础编译原理科普
本文是 @神说要有光 对编译小白 ssh 的一次答疑解惑,很适合零基础的新手第一次了解编译原理的概念,故分享出来. 近些年,编译原理在前端领域的应用越来越多,大家比较熟悉的有工程化领域各种转译器:ba ...
- python编译原理_编译原理实战课 带你吃透编译技术核心概念与算法
编译原理实战课,我们到底要学些什么? 在这门课程里,宫老师精选出了Java.Java JIT.Python.JavaScript.Julia.Go.MySQL这7种真实编程语言的编译器,带你阅读它们的 ...
- 计算机编译原理 张,计算机编译原理概念总结
<计算机编译原理概念总结>由会员分享,可在线阅读,更多相关<计算机编译原理概念总结(11页珍藏版)>请在人人文库网上搜索. 1.第一章 引论?为什么要用编译器? 与编译器相关的 ...
- 【编译原理】期末 龙书概念梳理+做题方法(混子保过指南+学霸提分秘籍)
编译原理期末总结 龙书概念梳理+做题方法 目录 编译原理期末总结 龙书概念梳理+做题方法 编译概述 1 编译过程 2 编译&解释 3 GCC的处理过程 词法分析 1 词法分析的任务 2 词法分 ...
- 编译原理学习笔记一(待续)
这几天忙着学英语,同时在学习编译原理,对这门课很感兴趣,已经制作了词法分析器,同时还在补充这个分析器的功能,也准备着手开始写语法分析器,看到最后能不能连在一起,我想如果能够将整套编译器的流程跑下来真的 ...
- 深入剖析ASP.NET的编译原理之二:预编译(Precompilation)
(转载)在本篇文章的第一部分:[原创]深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation),详细讨论了ASP.NET如何进行动态编译的,现在我们来谈谈另外一种重 ...
- 编译原理_P1004
龙书相关知识点总结 //*************************引论***********************************// 1. 编译器(compiler):从一中语言( ...
最新文章
- C++模板:模板简述,函数模板详细说明【C++模板】(56)
- webservice框架_聊聊从RPC到服务治理框架
- 服务器物理内存总是九十几,Solr总是使用超过90%的物理内存(Solr always use more than 90% of physical memory)...
- python八角图形绘制_(Python)从零开始,简单快速学机器仿人视觉Opencv—第四节:OpenCV处理鼠标事件...
- 听说你想进玩TikTok?
- 【Oracle】查询当前SCN
- 学习第四章与第五章的感悟
- springboot - 应用实践(2)第一个springboot应用
- atitit.为什么笔记本跟个手机不能组装而pc可以
- Java 分页工具类
- web test performance tools / linux performance tools / windows performance tools
- http解析库http-parser
- win7音量图标不见了 点显示它图标和通知 提示但前未处于活动
- android 通话录音
- html5视频制作,iH5最专业的H5制作工具
- Zrlog开源博客网站 安装教程
- VMware Workstation 12 Pro虚拟机下载(含序列号)
- pandas 数据查询实例
- mark mark mark
- Java随机生成验证码