第一章 引论
考点一:编译过程的概述
源/高级语言 程序--->编译程序--->目标/低级语言 程序
源程序 | FORTRAN,PASCAL,JAVA,C++等高级语言 |
---|---|
词法分析 | 从左到右一个一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词 |
语法分析 | 将单词序列分解成各类语法短语,如“程序”“语句”“表达式”等,可以表示成语法树 |
语义分析 | 审查源程序有无语义错误,为代码生成阶段收集类型信息,比如当某个运算对象类型不在语言规范允许的范围内时,编译程序应报告错误 |
中间代码生成 | 有的编译程序会将源程序变成一种内部表示形式,是一种结构简单,含义明确的记号系统。设计原则是要容易生成和容易翻译成目标代码 |
代码优化 | 对前一阶段代码进行变换或改造,是生成的目标代码更为高效,省时间和省空间 |
目标代码生成 | 把代码变换为特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码 |
目标程序 | 汇编语言/机器语言 |
考点二:编译程序的结构
表格管理和出错处理与六个模块都有关系
一个编译过程可以由一遍、两遍或多遍完成。
遍:也称作“趟”,是对源程序或其等价的中间语言程序从头到尾扫描并完成规定任务的过程。比如,一遍可以完成词法分析的工作,可以完成语法分析和语义分析的工作。
一个多遍的编译程序可以比一遍的编译程序少占内存,遍数多一点,整个编译程序的逻辑结构可能更清晰,但遍数多也意味着增加读写中间代码的次数,势必要消耗较多时间,显然会比一遍的编译程序要慢。
第二章 文法和语言
考点一:文法的类型
乔姆斯基Chomsky 把文法分为4中类型,即0型、1型、2型、3型。这几种文法的差别在于对产生式施加不同的限制。
文法类型 | 介绍 |
---|---|
0型文法 | a→ b , a,b∈(V_N∪V_T)^*且a必须要含有一个非终结符 |
1型/上下文有关 文法 | 在0型文法的基础上,增加一条,除S->ɛ外,a->b 要满足|a|≤ |b| |
2型/上下文无关 文法 | 在1型文法的基础上,对产生式左边进行约束。a是由一个非终结符组成 |
3型/正规 文法 | 产生式形式为A→aB 或者A→a(字母小写表示终结符,大写表示非终结符),在2型文法上的基础对于产生式右部做出约束 |
从表格可以看出,4种文法类型的定义是逐渐增加限制的
考点二:一些名词的介绍
句型:设G[S]是一个文法,如果符号串x 是从识别符号推导出来的,则称x 是G[S]句型
最左(右)推导:在推导的任何一步a=>b,其中a,b是句型,都是对a的最左(右)非终结符进行替换
最右推导常被称为规范推导,由规范推导得来的句型称为右句型或规范句型
例子:
最右推导:S=>aAS=>aAa=>aSbAa=>aSbbaa=>aabbaa
二义性:如果一个文法存在某个句子对应两棵不同的语法树,则说这个文法是二义的。
令G是一个文法,S是文法的开始符号,abc是文法G的一个句型。
短语:可以理解为在abc句型中的某些元素,是一棵语法子树的所有叶子节点
直接短语:对于子树只有两层的,一步推导而来的,表述可能不准,具体可看例图
句柄:一个右句型的直接短语称为该句型的句柄。一个右句型的唯一句柄是其所有直接短语中的最左边的那一个,即最左直接短语 (P31)
补充:相对于T的短语还有:i_3,i_1, 相对于E的短语还有:i_1*i_2
第三章 词法分析
考点一:正规式与正规文法的等价性
正规式也是表达正规集的工具
正规式 | 正规集 |
---|---|
a | {a} |
a|b | {a,b} |
ab | {ab} |
(a|b)(a|b) | {aa,ab,ba,bb} |
a^* | {ɛ,a,aa,...} |
(a|b)^* | {ɛ,a,b,ab,aa,ba,bb...} |
(a|b)^*(aa|bb)(a|b)^* | \sum^*上所有含有两个相继的a或两个相继的b组成的串 |
将正规式转换成正规文法
例子: A→x^*y
A→xB
A→y
B→xB
B->y
B是一个新的非终结符
将正规文法转换成正规式
文法产生式 | 正规式 | |
---|---|---|
rule1 | A→xB B->y | A=xy |
rule2 | A→xA A->y | A=x^*y |
rule3 | A→x A→y | A=x|y |
考点二:有穷自动机
有穷自动机分为两类:确定的有穷自动机DFA 和不确定的有穷自动机NFA
DFA的确定性在于对于任何状态k和输入符号a,f(k,a) 唯一地确定了下一个状态,即k识别a 转向的状态是唯一的,可以确定的
NFA与DFA的不同点:NFA的初态可以有多个,DFA只能是一个,NFA 中的状态k识别 a 转向的状态可以有多个。
DFA是NFA的特例,对于每个NFA M,存在一个DFA M',使得L(M)=L(M')
NFA转为等价的DFA,DFA的化简
通过子集法,分割法来实现,具体看书p51-p53
考点三:正规文法和有穷自动机的等价性
转化函数f(A,t)=B 对应的产生式 A→tB
对于可接受的状态Z ,增加一个产生式:Z→ɛ
掌握正规式转DFA,NFA确定化最小化,正规文法转NFA
第四章 自顶向下的语法分析方法
考点一:LL(1)文法的判定
一个上下文无关文法是LL(1)文法的充分必要条件是,对每个非终结符A的两个不同产生式,A→a,A→b,满足 SELECT(A→a) ∩ SELECT(A→b) = ∅
求一个产生式的SELECT,比如A→a,如果 a 不能推出 ɛ ,则SELECT(A→a) = FIRST(a),如果可以推出 ɛ ,则SELECT(A→a) = (FIRST(a) - {ɛ })∪FOLLOW(A)
个人对于SELECT集的理解:
对于一个输入串abc,LL(1)文法要能够判断它是否属于文法对应的语言中,它的做法每一次都是从左向右看一步的,比如首先看 a ,那么就去产生式右部中找FIRST集中是a 的,FIRST 集是a的表明当前这个产生式可以识别a,FIRST 集代表了该产生式左边可以推出的第一个终结符。
如果当前的FIRST集可以推出空,则就需要FOLLOW集来判断,FOLLOW集表明的是产生式左部后面跟着的第一个终结符,也就是就算当前这个产生式不能识别a,但它可以用空代替它,只要它后面的符号可以识别a也可以。
所以同一个非终结符对应的产生式的SELECT集交集得为空,不然就不知道选择哪个产生式进行下一步。
FIRST 集求法和FOLLOW集求法看P69-75
LL(1)的含义是:第1个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将用最左推导,1 表明只需要向右看一个符号便可决定如何推导,即选择哪个产生式
考点二:非LL(1)文法到LL(1)文法的等价变换
提取左公共因子
形如 A→ aB|aC ,此时不满足LL(1)文法要求
修改为 A→ aA' a'→ B|C 即可
如果对于产生式右部以非终结符开始的,要记得替换为对应的终结符。
当然提取完左公共因子后依旧可以不是LL(1) 文法,没有左公共因子只是LL(1) 文法的必要条件
需要注意的问题:
-
不一定每个文法的左公共因子都能够在有限步内替换成无公共左因子的文法
-
一个文法提取完左公共因子后,只解决了相同左部产生式右部的FIRST集不相交的问题,当改写后的文法不含空产生式,且无左递归时,则改写后的文法是LL(1)文法
消除左递归
两种含左递归的形式
-
A→Ab 直接左递归
-
A→Bb ,B→Aa 间接左递归
把直接左递归改为右递归
A→Ab A→a 转化为 A→aA' A'→bA' | ɛ
其它方式看P83
考点三:构造LL(1)分析表,写出对于输入符号串的分析过程
P93-95
第五章 自底向上优先分析
自底向上分析的关键问题是在分析过程中如何确定句柄或其他可归约串,也就是说如何知道何时在栈顶符号串中已形成某句型的句柄或其他可归约串。能确定句柄或其他可归约串,就可以确定何时就可以进行归约。
两种自底向上分析方式
-
优先分析
-
简单优先分析
-
算符优先分析
-
-
LR分析
简单优先分析和LR分析都是按照句柄进行归约,是规范归约,算符优先分析是按照其他可归约串进行归约,不是规范归约。
考点一:简单优先分析法
基本思想:是对一个文法按照一定原则求出该文法所有符号(包括终结符和非终结符)之间的优先关系,按照这种优先关系确定归约过程中的句柄,是一个规范归约。
优先关系定义:
有 = < >三种优先关系(符号中间都有 · ,不方便打出,所以在这里都省略,原本应该为<· 类似形式)
-
x = y , 当且仅当A→...xy...'
-
x < y , 当且仅当A→...xB...,B=^+>y...
-
x > y , 当且仅当A→...BD...,且B=^+>...x, D=^+>y...
注意:x>y 不意味着 y<x,x=y不意味着y=x,要注意条件中符号的位置
优先级越高越先处理
简单优先文法的定义
-
在文法符号集V中,任意两个符号之间最多只有一种优先关系成立
-
在文法中,任意两个产生式没有相同的右边(不满足则会出现归约不唯一)
简单优先文法的操作步骤
先构造优先关系矩阵(记得加上#,#的优先性最小(对于与#号符号相邻的符号而言)),再设置符号栈,算法步骤如下:
-
将输入符号串a_1,a_2,...a_n #依次逐个存入符号栈S中,直到遇到栈顶符号a_i的优先性>下一个待输入符号a_j为止
-
栈顶当前符号a_i为句柄尾,由此向左在栈中找句柄的头符号a_k,即找到a_{k-1}<a_k 为止,也就是找到一个a_1..a_{k-1}<a_k...a_i>a_{i+1}...
-
由句柄a_k..ai在文法产生式中查找右部为a_k..ai 的产生式,若找到,则用相应的左部代替句柄,否则为出错
-
重复123步骤,直到归约完输入符号串,栈中只剩文法的开始符号为止
例子:
对应关系矩阵
对于 ) > a 的说:根据 B→Aa) ,看Aa, A可以推出 (B | a,B是在产生式右部最后,同理 a 也是,而 B 又可以推出 Aa) ,)是在产生式右部最后,所以B,a,) 的优先级大于a
对输入串b(aa)b#的简单优先分析过程
考点二:算法优先分析法
只规定算符(终结符)之间的优先关系,在归约过程中只要找到可归约串就归约,并不考虑归约到哪个非终结符,所以不是规范归约
简单优先分析方法准确、规范,但分析效率较低,实际使用价值不大,而算符优先分析法则相反,它虽有不规范问题,但它分析快,特别适用于表达式的分析,在实际应用中还有一些应用。
算法文法定义
文法G 中没有形如A→...BC... 的产生式,其中BC 表示的是非终结符,则称G为算符文法,也称OG文法
算法优先关系定义
-
x = y , 当且仅当A→...xy... 或A→...xBy...
-
x < y , 当且仅当A→...xB...,B=^+>y...或B=^+>Cy...
-
x > y , 当且仅当A→...By...,且B=^+>...x或B=^+>...xC
与简单优先文法不同的点在于它可以忽略非终结符
算符优先文法的定义
-
在算法文法中,任一终结符之间最多只有一种优先关系成立,则称之为算符优先文法,OPG文法。
算符优先关系表的构造
要会求FIRSTVT集和 LASTVT集
FIRSTVT(B)={b | B=^+>b...或 B=^+>Cb...}
LASTVT(B)={a | B=^+>...a或B=^+>...aC}
可以看出FIRSTVT 是为了<优先关系,LASTVT是为了>优先关系
算符优先分析算法
为了解决在算符优先分析过程中如何寻找句柄的问题,引入最左素短语概念
最左素短语
设有文法G[S] ,其句型的素短语是一个短语,它至少包含一个终结符,并除自身外不包含其他素短语,最左边的素短语称最左素短语
素短语可以看作是包含有终结符的直接短语(错误的说法)
最左素短语N_ia_iN_{i+1}a_{i+1}...a_jN_{j+1}满足
a_{j-1}<a_j
a_i=a_{i+1}=..=a_j
a_j>a_{j+1}
算法优先分析的局限性
-
一般语言的文法很难满足算符优先文法的条件;
-
很难避免把错误的句子得到正确的归约;
-
算符优先分析法仅适用于表达式的语法分析。
第六章 LR分析
自底向上分析方法是一种移进-归约过程,当分析的栈顶符号串形成句柄或可归约串时就采取归约动作。
LR分析法正是给出一种可能根据当前分析栈中的符号串和向右顺序查看输入串的k个符号就可唯一确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就唯一地确定句柄。LR分析法的归约过程是规范推导的逆过程,所以LR分析过程是一种规范过程。
LR(k)的优点
-
比起自顶向下的的LL(k) 分析方法和自底向上的优先分析方法对文法的限制要少得多
-
分析速度快,能准确,即使地指出出错位置的特点
缺点是对于一个实用语言文法的分析器的构造工作量相当大,k愈大,构造愈复杂,实现比较困难。
LR(0) 分析器在分析过程中不需要向右查看输入符号,因而它对文法的限制较大,对大多数高级语言的语法分析器是不能适用的,但它是构造其他LR分析器的基础。 LR(1) 已能满足当前绝大多数高级语言编译程序的基础。
重点知识:LR(0),LR(1),SLR(1)(LR(0)的一种改进),LALR(1)(LR(1)的一种改进)
LR分析器的组成:
-
总控程序。对所有的LR分析器,总控程序都相同
-
分析表,可以分为ACTION和GOTO
-
分析栈,文法符号栈和相应的状态栈,他们都是先进后出栈
考点一:LR(0)分析
与之前简单优先分析和算法优先分析不同的是:
第一个点:要对文法进行扩充,在原文法G中增加S' →S,S为G的开始符号,S'为拓广文法G' 的开始符号,G’ 和G 是等价的。这样拓广的目的在于S可能在产生式的右部出现,为了在归约过程中分清是否已归约到文法的最初开始符号,增加S',而S’是只在产生式左部出现
第二个点:可归前缀和活前缀
活前缀定义:
S’ =^+> abw是文法G中的一个规范推导,如果符号串 γ 是ab的前缀,则称γ是G的一个活前缀。
文法G[S]: (1) S →aAcBe[1] (2) A → b[2] (3) A → Ab[3] (4) B → d[4]
每次归约句型的前部分依次为: ab[2]
aAb[3]
aAcd[4]
aAcBe[1] 规范句型的这种前部分符号串称为可归前缀
我们把形成可归前缀之前包括可归前缀在内的所有规范句型的前缀都称为活前缀
在LR分析过程中,实际上是把ab 的前缀列出,放在符号栈中。一旦在栈中出现ab,即句柄已经形成,则用产生式A→b 进行归约
引入一个新的状态栈来表示符号栈中的符号目前状态,用LR分析表来表示不同状态下对于各输入符号应采取的动作。
我们把文法的终结符和非终结符都看成有穷自动机的输入符号,每次把一个符号进栈看成已识别过了该符号,同时状态进行转换,当识别到可归前缀时,相当于在栈中形成句柄,认为达到了识别句柄的终态。
如何构造识别文法活前缀的有限自动机?
1、根据文法算出其可归前缀; 2、根据可归前缀,构造识别文法活前缀的不确定有限自动机; 3、确定化,从而构造出识别文法活前缀的确定的有限自动机。
这种方法构造识别可归前缀的有限自动机从理论的角度讲是比较严格的,但实现起来却很复杂。
另一种方式:LR(0)项目集规范族
由文法的产生式直接构造识别活前缀和可归前缀的有限自动机
根据圆点所在的位置和圆点后是终结符还是非终结符把项目分为以下几种:
移进项目,形如 A →a • ab
待约项目,形如 A →a• Bb
归约项目,形如 A →a •
接受项目,形如 S’ →S •
构成识别一个文法活前缀的DFA项目集(状态)的全体称为这个文法的LR(0)项目集规范族.
NFA确定化为DFA的工作量较大,我们考虑直接构造出项目集作为DFA的状态,就可直接构造DFA
一般采用第三种方式
LR(0)文法:若其LR(0)项目集规范族不存在移进-归约,或归约-归约冲突,称为LR(0)文法。
Si:移进,并将状态i进栈
ri:用第i个产生式归约,同时状态栈与符号栈退出相应个符号,根据GOTO表将相应状态入栈
文法G[S]: (1) S →aAcBe[1] (2) A → b[2] (3) A → Ab[3] (4) B → d[4]
对输入串abbcde#的LR分析过程
I_0 项目集规范族的构建
L(0)分析表的构建
考点二:SLR(1)分析
基本思想:基于容许 LR(0) 规范族有冲突的项目集,用向前查看一个符号的方式来进行处理,以解决冲突(移进-归约冲突,归约-归约冲突),这是一个中简单的LR(1)分析法,用SLR(1)表示。
一个状态中含有移进-归约冲突
S → rD· 为归约项目
D →D·a 为移进项目 也就是说对于此时的D,当下一个符号是a 时,不知道选择归约还是移进。
在这种情况下,只需要查看S后面的符号是不是a ,不是a的话,则采取移进操作,也就是对于归约操作,需要往后看一个符号,只有在对应符号下的ACTION 表才填入r_i 。SLR(1) 就是基于此的改进
SLR(1)分析
SLR(1) 与LR(0) 分析表不同点在于 r 的不同
考点三:LR(1) 分析
SLR(1)不能解决的情况:
P144
LR(1) 项目集族的构造
若项目集[A→a•Bb]属于I时,则[B→•g]也属于I
把FIRST(b)作为用产生式归约的搜索符(称为向前搜索符),作为用产生式B→g归约时查看的符号集合(用以代替SLR(1)分析中的FOLLOW集),并把此搜索符号的集合也放在相应项目的后面,这种处理方法即为LR(1)方法
-
针对初始项目[S’→•S , #]求闭包
-
再用转换函数逐步求出整个文法的LR(1)项目集族。
LR(1)存在的问题:
LR(1)项目集的构造对某些同心集的分裂可能使状态数目剧烈的增长
考点四:LALR(1) 分析
对LR(1) 项目集规范族进行合并同心集的方法,若合并同心集后不产生新的冲突,则为LALR(1) 项目集,它的状态数与LR(0),SLR(1) 相同
若文法是LR(1)文法,合并同心集后,若有冲突也只可能是归约-归约冲突,而不可能产生移进-归约冲突
总结:
-
一个文法是LR(0)文法,一定也是SLR(1)文法,也是LR(1)文法。反之不一定成立。
-
LR(1)分析法强于LALR(1)分析法,LALR(1)分析法强于SLR(1)分析法, SLR(1)分析法强于LR(0)分析法。
-
LALR(1)文法一定是LR(1)文法,反之不一定成立。
-
任何一个二义性文法都不是LR类文法,也不是一个算符优先文法或LL(k)文法。
第七章 语法制导的语义计算
属性文法
通过在G[S]的基础上,为文法符号关联有特定意义的属性,并为产生式关联相应的语法动作或条件谓词,称之为属性文法,并称G[S] 是这一属性文法的基础文法。
考点一:综合属性和继承属性
在分析树中,如果一个结点的某一个属性由其子结点的属性确定,则称这种属性为该结点的综合属性。
如果一个语法制导定义仅仅使用综合属性,则称这种语法制导定义为S属性定义。通常采用自底向上的方法对其分析树加注释,即从树叶到树根,按照语义规则计算每个节点的属性值。
在分析树中,一个结点的继承属性值是由此结点的父结点和/或兄弟结点的某些属性来决定的。
考点二:基于属性文法的语义计算
计算方法分两类:
- 树遍历方法
通过遍历分析树进行属性计算
- 单遍的方法
语法分析遍的同时进行属性计算
填空题
-
编译程序的前端包括的阶段有:词法分析、语法分析、语义分析和中间代码生成、某些优化工作等(P6)
-
设文法G_{1}[s]:S→ xSy | ɛ,是属于Chomsky文法层次中的 2型文法
-
\sum={a,b},包含 aa 的字符串的正则表达式为: (a|b)^*aa(a|b)^*
-
LR分析法中,每次归约的是 句 柄
-
如果某个文法存在一个句子对应有两个不同的语法树,则称该文法是 二义性 的 p28
-
算法优先文法中有规定:S→aAb,则从此产生式可以得到如下关系 a=·b,a<· x∈FIRSTVT(A),x∈LASTVT(A) ·> b
-
LR分析过程中,符号栈中符号构成的是 活前缀,其与输入串的剩余部分串在一起构成的是规范句型
-
编译方式与解释方式的根本区别在于是否产生目标代码,对于解释程序而言,输入数据是源程序,输出结果是 执行结果。P7
-
当文法规则中包含有左公因子时,在进行语法分析时会产生局部二义性 问题。
-
由文法开始符号S经过零步或多步推导产生的符号序列称为句型。p23
-
有LR(1)项目:[S->a. BD, b],求B->.d的搜索符号时需要计算 D 的FIRST集合。
-
活前缀是指规范句型的一个前缀,这种前缀不含句柄之后的任何符号。
-
局部优化是指基本块内的优化。
-
将编译程序分成若干个“遍”的目的是为了使程序的逻辑结构更加清晰,编译程序的输出结果是目标程序 。P7
-
S={0,1},至少含有2个1的字符串的正规式可以表示为:(0|1)^*11(0|1)^*
-
一个句型的语法树代表了该句型的推导过程。p28
-
LR分析采用的是最左归约。
-
有LR(1)项目:[S->a. BD, b],其中b称为向前搜索字符串。
-
编译过程通常可分为5个阶段,分别是词法分析、语法分析、语义分析、代码优化和目标代码生成。
-
编译程序工作过程中,第一段输入的是 源程序,最后阶段的输出为 目标 程序。P1
-
在C语言中,m 是一个整型变量,程序编译时遇到表达式m+" test", 出现错误,此错误是编译各阶段中的 语义分析 阶段发现的错误。
-
设有字母表 A={a,b} ,与 A^* 等价的正则表达式是 (a|b)^*
-
自底向上的语法分析方法中产生的冲突有 移进-归约冲突 和归约-归约冲突
-
LALR(1) 项目是对LP(1)项目集中的 同心集进行合并
-
语法制导翻译能同时进行 语法 分析 和语义分析
-
编译各阶段的工作都要涉及到的工作是表格管理和 出错处理 P5
-
设有字母表A={a,b,c),与 等价的正则表达式是 (a|b|c)^*
-
规范归约是指 最右推导的逆过程
-
一个LR分析器的逻辑结构一般会包含 LR分析表、控制器、分析栈等三个部分。
-
继承属性依赖于父结点和兄弟结点的属性。
-
词法分析是基于 正则(或3型) 文法进行,即识别的单词是该文法的句子。
-
一般高级语言的翻译程序有 编译程序 和 解释程序两种
-
有穷自动机接受的语言是 正规语言
-
令\sum ={a,b},则所有以b为首的字符串构成的正规集的正规式为 b(a|b)*
-
下面的语义规则是某L属性文法中的一个语义规则,从中可看出 A.s是 综合 属性,B.x是 继承 属性。A->BCD{A.s=B.x+C.y; D.z=B.i;}
-
活前缀是指 规范句型的一个前缀,这种前缀不含 句柄 之后的任何符号。
-
Chomsy 定义的四种形式文法中,被证明在程序设计语言中最有用的文法是:上下文无关文法或 2 型文法,它代表目前程序设计语言结构的标准
-
\sum ={0,1},代表所有二进制偶数的正规式可以表示为: (0|1)*0
-
如果说一个 NFA 与一个 DFA 等价,则说明它们能识别的语言集合相等
-
确定的自顶向下分析要求文法满足:没有左递归 (无二义性也算对 )和没有左公因子。
-
规范归约是指最右推导的逆或最左规约
-
在程序流图中,循环是强连通且只有唯一的入口结点。
-
根据与目标机器的依赖性将编译程序的五个阶段分为 前端 和 后端
-
与语言{x |x∈{0,1}+且x中至少含有两个1}等价的正规式可表示为 (0|1)^*11(0|1)^*
-
S-属性定义中只含有 综合 属性,综合属性是自底向上传递信息,继承属性是自顶向下传递信息。终结符(没有子节点)只有综合属性
-
由文法开始符号推导得到符号串称为 句型
-
规范句型 :由规范推导或规范规约得到的句型
-
LL(1)分析法,其中第一个L表示自顶向下分析是从左向右扫描输入串,第二个L表示分析过程中将用最左推导
-
S属性定义是只含有 综合 属性的语法制导定义,L属性定义中规则:A→X1X2…Xn ,X1的属性只能依赖于A的继承属性。
-
例举几种中间表达形式:AST(抽象语法树)、TAC(三地址码) P-code
判断题
-
编译过程可以一遍完成,也可以分为多遍完成。(√)
-
一个DFA即可认为是一个词法分析器。(√)
-
对于任一给定的正规式,一定存在一个能识别该正规集的DFA M。(√)
-
若存在算符优先关系a>b,优先关系b<a一定也存在。(× )
-
合并同心集可能产生新的归约与归约冲突。(√ )
-
二义文法不可能是LL(1)文法,但可能是LR(1)方法。(× )
-
循环不变量都可以外提。(× )
-
Chomsky的形式文法分类的依据是产生式的形式。( √)
-
最左素短语首先一定是短语,也肯定是句柄。( ×)
-
文法中的右递归不影响进行确定地自顶向下语法分析。(√)
-
词法分析器的输出是单词自身的值。(
输出的是单词的种别编码和自身值
)(×) -
一个NFA一定存在与之等价的DFA。(√)
-
电梯的运行方式可以模拟成一个有限自动机。 ( √)
-
最左素短语与句柄的作用一样的,它至少要包括一个非终极符。 (× )
-
所有产生式A→Aa | b,消除左递归后的产生式如下:A→ aA’| A’ A’→b | ɛ。
正确写法:A→bA' A'→aA'|ɛ
(× ) -
二义文法不是LR文法,但可能可以使用LR法进行分析。(√)
-
对于产生式A→Ba, B→b,在判断是否是OPG时,计算FIRSTVT(A)={b}(×)
-
LR(0)文法分析表中如果某一状态对应的输入字符是归约的动作,则整行均是同样的归约动作。( √)
-
语法制导翻译中,语义规则的是生成中间代码的依据。(√ )
-
将目标程序装配成可执行程序是编译程序的任务。(×)
-
一棵语法树反映了其叶子结点从左到右连接成句型的任意推导情况。(×)
-
DFA中识别一个符号串的路径是唯一的。(√)
-
任何算符优先文法的句型中不会有两个相邻的非终结符(√)
-
程序流图反映了基本块间的关系。(√)
-
自顶向下语法分析的“下”是指分析树的叶结点(√)
-
SLR(1)文法消除冲突的依据是计算归约项目左部符号的FOLLOW集合 (√)
-
没有左递归和左公因子的文法就是 LL(I)文法(×)
-
文法开始符既可有综合属性,也可以有继承属性。(×)
-
语法制导翻译方法既可用于生成中间代码,也可用于生成目标代码 (×)
-
一个文法G的文法符号不属于 V就属于VT。(√)
-
一棵语法树反映了其叶子结点从左到右连接成句型的一种推导情况(√)
-
(a|b)^*与 (ab)^*是等价的正规式。(×)
-
{a^nb^nc^n|n>0}和{a^nb^n|n>0}都能用上下文无关文法产生(×)
-
依赖图是用于描述分析树中节点的属性及属性间依赖关系的有向图.(√)
-
自上而下语法分析的“下”是指分析树的根结点或文法的开始符号(×)
-
SLR(1)与LR(1)中的“1”含义无区别。(×)
-
最左素短语一定是短语。(√)
-
对于任何一个编译程序,产生中间代码是不可缺少的(×)
-
逆波兰表示法用于表示表达式时不需要括号。(√)
-
用正规表达式和上下文无关文法描述语言时识别方法是不同的(√)
-
文法 G[S]: S→aS|Sb|b。此文法是正规文法(×)
-
文法某一规则的右部符号个数为 n,则其 LR(0)项目个数为 n+1.(√)
-
有规则 A→aGb,则存在关系 a<·x,其中 x∈FIRSTVT(G)(√)
-
同一文法中,FIRST(A)-{ɛ}∈FIRSTVT(A)(√)
-
一个 DFA,识别一个字符串的路径是唯一的。(√)
-
若有 A→aB,则有 FOLLOW(B)∈FOLLOW(A) (×)
-
LR(0)文法分析过程中,每一次规约的一定是真正的句柄。(√)
-
中间代码生成的依据是语法规则(×)
-
基本块内的优化包括代码外提、公共子表达式删除(×)
-
每个SLR(1)文法一定是LALR(1)文法 (√)
-
LR项目集中的待约项目不会引起冲突(√)
-
终结符既可有综合属性,也可以有继承属性 (×)
-
自上而下语法分析的“上”是指分析树的根结点或文法的开始符号(√)
-
在C语言中语句int int1;经过词法分析后识别出int、int、1和 ;四个单词。(√)
-
任何正则语言均可用上下文无关文法来描述。(√)
-
NFA和DFA的区别之一是映射函数是否唯一。(√)
-
一个语言的文法是不唯一的。 (√ )
-
设有r和s都是非ε的正规式,则有L(rs)=L(sr) ( ×)
-
一个有限自动机识别的语言是无穷集合,则该有限自动机的状态转换图中一定含有回路。 ( ×)
-
自上而下语法分析实施的是最左推导。 (√ )
-
最左素短语一定是短语。 (√ )
-
LR分析中的活前缀一定包含某句型的句柄的一部分或全部 ( √)
-
二义文法一定不是LR文法 (√ )
-
使用语法制导翻译方法的编译程序能同时进行语法分析和语义分析 ( √)
-
DISPLAY表用来记录每层过程的最新活动记录地址,因此它的大小在运行时确定 (× )
-
程序控制流图的一个结点一定是一个基本块。(√)
-
确定的有限自动机和非确定的有限自动机均能正确识别正则语言(√)
-
若r1和r2是Σ上的正则表达式,则r1|r2也是。(√)
-
所有文法规则的左部只能有非终极符号,不能有终结符号。(× )
-
若r1和r2是Σ上的正则表达式,则(r1|r2)* 与(r1 * |r2 * )* 是等价的。 ( √)
-
算符优先分析法在进行归约时,“句柄”要与某个产生式的右部完全一致。 (× )
-
规范句型的前缀称为活前缀。 (× )
-
在LR(0) 项目中,存在的冲突有移进-归约冲突、归约-归约冲突。 (√ )
-
一个有穷状态自动机中有且只有一个结束状态。 (× )
-
若文法的一个句子二义,则此文法也是二义的。 ( √)
-
只有DFA能正确识别正则语言,而NFA则不能。(× )
-
中间代码生成的依据是语法规则。
是语义规则
(×) -
基本块内的优化包括代码外提、公共子表达式删除。(×)
简答题
-
请说明什么是算符优先文法?
-
在上下文无关文法中无空产生式,且右部无相邻的非终结符(首先得是算符文法)
-
任意两个相邻的终结符之间最多只有一种优先关系成立
-
算法优先文法的缺点:难免把错误的句子也得到正确的归约,仅适用于表达式的语法分析
-
-
文法G[S]:S→S(S)S| ɛ,请判断G[S] 是否是二义文法,说明理由
-
是二义文法,比如对于()() ,有不同的语法树
-
-
简述DFA 与NFA 有何不同?
-
转移函数的不同,NFA的转移函数是不确定的,可以转移到多个状态,同样的输入可以得到不同的结果,DFA的转移函数是确定的,只能转移到唯一的一个状态,输入相同,输出结果也相同
-
NFA可以有多个初始状态,而DFA只有一个开始状态
-
-
设有如下文法G[S]: S→a|^|(T) T → T,S|S 给出句型:((^,a),(T)) 的最左推导,并画出相应语法树,给出句型的短语、句柄、素短语和最左素短语。
-
文法G [S]: S-->aSbS | bSaS | ab,请判断G[S]是否是二义文法,说明理由,如果是二义文法,可采用何种方式处理其二义性
-
有文法 G[S]: S→aAcB|Bd A→AaB|c B→bScA| b (1)试求句型 aAaBcbbdcc 的句柄;(2)写出句子 acabcbbdcc 的最左推导过程 (3)给出句型aAcbBdcc的语法树,并写出其所有短语、素短语与句柄
-
文法G3[S]:S → a S b S | b S a S | ε 是否为算符优先文法,说明理由
-
设计文法,其产生的语言L={a^nb^mc^k | n<m+k,k≤n以及m,n,k≥1}
-
文法G1[S]:S→(A) A→a |Bb B→Aab,请消除其中的左递归,改写后的文法是LL(1) 文法吗?为什么?
-
G1[S]: S→(A) A→aA' A'→abbA' | ε
-
是LL(1)文法
-
-
什么是自底向上语法分析?什么是自顶向下语法分析?简述LR(0)项目中“•”在LR分析中的含义。
-
自底向上的语法分析:从输入串开始,逐步进行归约,直至归约到文法的开始符号
-
自顶向下的语法分析:从文法的开始符号出发,反复使用各种产生式,寻找匹配于输入符号的推导
-
圆点的左部表示分析过程的某时刻欲用该产生式归约时已识别过的句柄部分,圆点右部表示期待的后缀部分
-
-
中间代码的作用
-
用于源语言和目标语言之间的桥梁,避开二者之间较大的语义跨度,是编译结构更加简单明确
-
利于编译程序的重定向
-
利于进行与目标机无关的优化
-
-
能被4整除的二进制整数的正规式,并构造有限自动机
-
设有如下文法G2[S]: S→bTc|a T→R R→R/S|s 给出句型:bR/bTc/bSc/ac,写出该句型的所有短语、句柄、素短语。
-
语法制导翻译结果:请将下列语句翻译成三地址码 while (A<B)do if (C>D) then X:=Y+Z
-
构造一个有限自动机,能识别被5整除余数为3二进制无符号整数
分析求解题
-
属性文法G4[S]如下: S → ABCD { x = 11 * x + 1; } D → d { x = 7 * x + 1; } C → cc { x = 5 * x + 1; } B → Bb { x = 3 * x + 1; } B → b { x = x + 1; } A → gBa { x = 2 * x + 1; } 根据语义规则,对句子gbbabbccd进行语法制导翻译,最终结果是什么?要求写出分析过程,否则不得分
-
给定文法G5[S]: S → Xa X→ a | aXb (1)构造识别该文法所产生的活前缀的DFA。 (2)构造其SLR分析表,给出该文法是SLR(1)文法的理由。 (3)根据所构造的SLR分析表,给出句子aaba的分析过程。
-
设计产生如下语言集的上下文无关文法:L={a^nb^{2n}c^m|m,n >0}
-
G[S]: S→AC A→aAbb | abb C→cC|c
-
-
设计产生如下语言集的上下文无关文法:L={a^{2n+1} b^{2m} c^{2p+1}|p,n≥0, m≥1}
-
G[S]: S→ABC A→a|aaA B→bbB|bb C→c|ccC
-
-
试构造接受下列语言的一个 DFA及相应的正规式: L = { w | w∈{a, b}*,w 中 a 的数目可 被 2 整除、b 的数目至少为1 }
判定求解题
-
给定文法G5[S]: S→aA|a A→cAd | ε (1)给出G的LR(1)项目集规范族(包括项目集和有穷状态自动机) (2) 说明文法是否为LR(1)文法,为什么?如果文法是LR(1)文法,构造其LR(1)分析表
-
文法G[S]: S→BB B→aB|b (1)构造出文法识别文法活前缀的有穷状态自动机,并构造LR分析表 (2) 说明文法是否为SLR(1)文法,为什么? (3)构造一个正规文法G,使得L(G)=L(G)
-
、设有如下文法G5 [S] :S → Db|B D → d|ε B → Ba|ε (1)构造出文法G5[S]识别文法活前缀的有限自动机。 (2)确定文法是否是SLR(1)文法,如果是,则构造出其SLR(1)分析表。
-
设有如下文法G4 [S]: S → SaA|B A → BbA|B B → cSd|ε (1)消除文法中左递归, 提取左因子。 (2)求改造后文法中文法符号的FIRST集合和FOLLOW集合 (3)判断改造后的文法是否是LL(1)文法,如果是,请构造其预测分析表
-
设有如下文法G3 [E]: E → E+T | T T → T*F | F F→(E) | i (1)计算文法G3 [E]中各非终极符的FIRSTVT,LASTVT集合。 (2)给出算符优先关系表并判断文法是否是算符优先文法