编译原理递归下降子程序
编译原理-第4章 语法分析--习题答案
第4章语法分析习题答案1.判断(1)由于递归下降分析法比较简单,因此它要求文法不必是LL(1)文法。
(× )LL(1)文法。
(× )(3)任何LL(1)文法都是无二义性的。
(√)(4)存在一种算法,能判定任何上下文无关文法是否是LL(1) 文法。
(√)(× )(6)每一个SLR(1)文法都是LR(1)文法。
(√)(7)任何一个LR(1)文法,反之亦然。
(× )(8)由于LALR是在LR(1)基础上的改进方法,所以LALR(× )(9)所有LR分析器的总控程序都是一样的,只是分析表各有不同。
(√)(10)算符优先分析法很难完全避免将错误的句子得到正确的归约。
(√)2.文法G[E]:E→E+T|TT→T*F|FF→(E)|i试给出句型(E+F)*i的短语、简单短语、句柄和最左素短语。
答案:画出语法树,得到:短语: (E+F)*i ,(E+F) ,E+F ,F ,i简单短语: F ,i句柄: F最左素短语: E+F3.文法G[S]:S→SdT | TT→T<G | GG→(S) | a试给出句型(SdG)<a的短语、简单短语、句柄和最左素短语。
答案:画出语法树,得到:短语:(SdG)<a 、(SdG) 、SdG 、G 、a简单(直接)短语:G 、a句柄:G最左素短语:SdG4.对文法G[S]提取公共左因子进行改写,判断改写后的文法是否为LL(1)文法。
S→if E then S else SS→if E then SS→otherE→b答案:提取公共左因子;文法改写为:S→if E then S S'|otherS'→else S|E→bLL(1)文法判定:① 文法无左递归② First(S)={if,other}, First(S')={else, }First(E)={b}Follow(S)= Follow(S')={else,#}Follow(E)={then}First(if E then S S')∩First(other)=First(else S)∩First( )=③First(S')∩Follow(S')={else}不为空集故此文法不是LL(1)文法。
编译原理 递归下降词法分析
编译原理实验报告—递归下降分析法程序实验2.1 递归下降分析法一、实验目的1. 根据某一文法编制递归下降分析程序,以便对任意输入的符号串进行分析。
2. 本次实验的目的是加深对递归下降分析法的理解。
二、实验平台Windows + VC++6.0范例程序: “递归下降分析法.cpp ”三、实验内容对下列文法,用递归下降分析法对任意输入的符号串进行分析:(1)E→TG(2)G→+TG|-TG(3)G→ε(4)T→FS(5)S→*FS|/FS(6)S→ε(7)F→(E)(8)F→i1.程序功能:输入: 一个以# 结束的符号串(包括+ - * / ()i # ):例如:i+i*i-i/i#输出:(1) 详细的分析步骤,每一步使用的产生式、已分析过的串、当前分析字符、剩余串,第一步, 产生式E->TG的第一个为非终结字符,所以不输出分析串,此时分析字符为i,剩余字符i+i*i-i/i#;第二步,由第一步的E->TG的第一个为非终结字符T,可进行对产生式T->FS 分析,此时第一个仍为非终结字符F,所以不输出分析串,分析字符仍为i, 剩余字符i+i*i-i/i#;第三步,使用产生式F->i,此时的分析串为i,,分析字符为i,匹配成功,剩余字符串+i*i-i/i#;第四步,因为使用了产生式T->FS,F->i,第一个字符i匹配成功,接着分析字符+,使用产生式S->ε,进行下步;第五步,使用产生式G->+TG,此时的分析串包含i+,分析字符为+,剩余字符串+i*i-i/i#;第六步,重复对产生式T->FS,F->i的使用,对第二个i进行匹配,此时分析串i+i,分析字符为i,剩余串*i-i/i#;第七步,分析字符*,使用产生式S->*FS, 分析串i+i*,剩余串i-i/i#;第八步,字符*匹配成功后,使用产生式F->i,匹配第三个字符i,,此时剩余串-i/i#;第九步,分析字符-,只有产生式G->-TG可以产生字符-。
《编译原理》课后习题答案第5章
2
《编译原理》课后习题答案第五章
#)NS
a
)#...
#)Na
a
)#...
#)N
)
#...
#)
)
#...
#
#
可见输入串(a,a)#是文法的句子。
S→a .
N→ε
计算机咨询网()陪着您
3
《编译原理》课后习题答案第五章
第3题
已知文法 G[S]: S→MH|a H→LSo|ε K→dML|ε L→eHf M→K|bLM 判断 G 是否是 LL(1)文法,如果是,构造 LL(1)分析表。
A B N
FIRST {b} {b,a} {b,a}
FOLLOW {#} {#,b} {#,b }
预测分析表:
a
b
#
A
→baB
→ε
B
→a
→bN
N
→aBbb
→b
由预测分析表中无多重入口判定文法是 LL(1)的。
(2) 文法: A→aABe|a B→Bb|d
提取左公共因子和消除左递归后文法变为: 0) A→a N 1) N→A B e 2) N→ε
非终结符
FIRST 集
FOLLOW 集
计算机咨询网()陪着您
7
《编译原理》课后习题答案第五章
S
{b}...
B
{a}...
N
{ε,a}
对相同左部的产生式可知:
SELECT(N→B a N)∩SELECT(N→ε) ={ a }∩ {# }= 所以文法是 LL(1)的。 预测分析表(Predicting Analysis Table)
A→BaC|CbB B→CbBcB'|cB' B'→aCcB'|ε C→cB'bC'|bC' C'→bBcB'bC'|ε
编译原理 全部参考答案
第二章P-36-6(1)L(G)是0~9组成的数字串;(2)最左推导:N⇒ND⇒NDD⇒NDDD⇒DDDD⇒0DDD⇒01DD⇒012D⇒0127N⇒ND⇒DD⇒3D⇒34N⇒ND⇒NDD⇒DDD⇒5DD⇒56D⇒568最右推导:N⇒ND⇒N7⇒ND7⇒N27⇒ND27⇒N127⇒D127⇒0127N⇒ND⇒N4⇒D4⇒34N⇒ND⇒N8⇒ND8⇒N68⇒D68⇒568P-36-7G(S):(没有考虑正负符号问题)S→P|APP→1|3|5|7|9A→AD|NN→2|4|6|8|PD→0|N或者:(1)S→ABC|CA→1|2|3|4|5|6|7|8|9B→BA|B0|εC→1|3|5|7|9P-36-8G(E):E→T|E+T|E-TT→F|T*F|T/FF→(E)|i最左推导:E⇒E+T⇒T+T⇒F+T⇒i+T⇒i+T*F⇒i+F*F⇒i+i*F⇒i+i*iE⇒T⇒T*F⇒F*F⇒i*F⇒i*(E)⇒i*(E+T)⇒i*(T+T)⇒i*(F+T)⇒i*(i+T)⇒i*(i+F)⇒i*(i+i)最右推导:E⇒E+T⇒E+T*F⇒E+T*i⇒E+F*i⇒E+i*i⇒T+i*i⇒F+i*i⇒i+i*iE⇒T⇒T*F⇒T*(E)⇒T*(E+T)⇒T*(E+F)⇒T*(E+i)⇒T*(T+i)⇒T*(F+i)⇒T*(i+i)⇒F*(i+i)⇒i*(i+i)语法树:SiSeSiSiiSiS i S eS iiP-36-9句子:iiiei 有两个语法树: S ⇒iSeS ⇒iSei ⇒iiSei ⇒iiiei S ⇒iS ⇒iiSeS ⇒iiSei ⇒iiiei因此iiiei 是二义性句子,因此 该文法是二义性的。
P-36-10 S →TS|T T →(S)|()P-36-11L1: G(S): S →AC A →aAb|ab C →cC|ε L2: G(S): S →AB A →aA|ε B →bBc|bc L3: G(S): S →AB A →aAb|ε B →aAb|ε L4: G(S): S →1S0|A A →0A1|ε或者:S →A|B A →0A1|ε B →1B0|A 第三章(1)Ei+i+iE +TE +TT F iF iF iEE +TT F iT *FF iii+i*i Ei-i-iE-TE -TT F iF iF i确定化:最小化:{0,1,2,3,4,5},{6}{0,1,2,3,4,5}0={1,3,5} {0,1,2,3,4,5}1={1,2,4,6} {0,1,2,3,4},{5},{6} {0,1,2,3,4}0={1,3,5} {0,1,2,3},{4},{5},{6}{0,1,2,3}0={1,3} {0,1,2,3}1={1,2,4} {0,1},{2,3},{4},{5},{6}{0,1}0={1} {0,1}1={1,2} {2,3}0={3} {2,3}1={4} {0},{1},{2,3},{4},{5},{6}P64-8(1)(0|1)*01(2)(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*(0|5)|(0|5)(3)0*1(0|10*1)* | 1*0(1|01*0)*P84-12(a)a最小化:{0,1} {2,3}{0,1}a={1},{0,1}b={2}{2,3}a={0,3},{2,3}={3}{0,1},{2},{3}a(b)已经确定化,只需最小化:{0,1},{2,3,4,5}{0,1}a = {1} {0,1}b = {2,4}{2,3,4,5}a = {1,3,0,5} {2,3,4,5}b = {2,3,4,5}又:{2,4}a = {1,0} {2,4}b = {3,5} {3,5}a={3,5} {3,5}b = {2,4} 分划为:{0,1},{2,4},{3,5}{0,1}a = {1} {0,1}b = {2,4}{2,4}a = {1,0} {2,4}b = {3,5}{3,5}a = {3,5} {3,5}b = {2,4}所以不能再分aP64-14正规式:(0|10)*还可以:然后再确定化,最小化,结果应该一样。
编译原理填空集锦
1-01.编译程序的工作过程一般可以划分为词法分析,语法分析,语义分析,之间代码生成,代码优化等几个基本阶段,同时还会伴有表格处理和出错处理 .1-02.若源程序是用高级语言编写的,目标程序是机器语言程序或汇编程序,则其翻译程序称为编译程序.1-03.编译方式与解释方式的根本区别在于是否生成目标代码 .1-04.翻译程序是这样一种程序,它能够将用甲语言书写的程序转换成与其等价的用乙语言书写的程序 .1-05.对编译程序而言,输入数据是源程序,输出结果是目标程序.1-06.如果编译程序生成的目标程序是机器代码程序,则源程序的执行分为两大阶段: 编译阶段和运行阶段 .如果编译程序生成的目标程序是汇编语言程序,则源程序的执行分为三个阶段:编译阶段, 汇编阶段和运行阶段 .1-07.若源程序是用高级语言编写的,目标程序是机器语言程序或汇编程序,则其翻译程序称为编译程序。
1-08.一个典型的编译程序中,不仅包括词法分析、语法分析、中间代码生成、代码优化、目标代码生成等五个部分,还应包括表格处理和出错处理。
其中,词法分析器用于识别单词。
1-09.编译方式与解释方式的根本区别为是否生成目标代码。
2-01.所谓最右推导是指:任何一步α?β都是对α中最右非终结符进行替换的。
2-02.一个上下文无关文法所含四个组成部分是一组终结符号、一组非终结符号、一个开始符号、一组产生式。
2-03.产生式是用于定义语法成分的一种书写规则。
2-04.设G[S]是给定文法,则由文法G所定义的语言L(G)可描述为:L(G)={x│S x,x∈VT*} 。
2-05.设G是一个给定的文法,S是文法的开始符号,如果S x(其中x∈V*),则称x是文法的一个句型。
2-06.设G是一个给定的文法,S是文法的开始符号,如果S x(其中x∈VT*),则称x是文法的一个句子。
3-01.扫描器的任务是从源程序中识别出一个个单词符号。
4-01.语法分析最常用的两类方法是自上而下和自下而上分析法。
编译原理一些习题答案
第2章形式语言基础2.2 设有文法G[N]: N -> D | NDD -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9(1)G[N]定义的语言是什么?(2)给出句子0123和268的最左推导和最右推导。
解答:(1)L(G[N])={(0|1|2|3|4|5|6|7|8|9)+} 或L(G[N])={α| α为可带前导0的正整数}(2)0123的最左推导:N ⇒ ND ⇒ NDD ⇒ NDDD ⇒ DDDD ⇒ 0DDD ⇒ 01DD ⇒ 012D ⇒ 0123 0123的最右推导:N ⇒ ND ⇒ N3 ⇒ ND3 ⇒ N23 ⇒ ND23 ⇒ N123 ⇒ D123 ⇒ 0123268的最左推导:N ⇒ ND ⇒ NDD ⇒ DDD ⇒ 2DDD ⇒ 26D ⇒ 268268的最右推导:N ⇒ ND ⇒ N8 ⇒ ND8 ⇒ N68 ⇒ D68 ⇒ 2682.4 写一个文法,使其语言是奇数的集合,且每个奇数不以0开头。
解答:首先分析题意,本题是希望构造一个文法,由它产生的句子是奇数,并且不以0开头,也就是说它的每个句子都是以1、3、5、7、9中的某个数结尾。
如果数字只有一位,则1、3、5、7、9就满足要求,如果有多位,则要求第1位不能是0,而中间有多少位,每位是什么数字(必须是数字)则没什么要求,因此,我们可以把这个文法分3部分来完成。
分别用3个非终结符来产生句子的第1位、中间部分和最后一位。
引入几个非终结符,其中,一个用作产生句子的开头,可以是1-9之间的数,不包括0,一个用来产生句子的结尾,为奇数,另一个则用来产生以非0整数开头后面跟任意多个数字的数字串,进行分解之后,这个文法就很好写了。
N -> 1 | 3 | 5 | 7 | 9 | BNB -> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | B02.7 下面文法生成的语言是什么?G1:S->ABA->aA| εB->bc|bBc G2:S->aA|a A->aS解答:B ⇒ bcB ⇒ bBc⇒ bbccB ⇒ bBc⇒ bbBcc ⇒ bbbccc……A ⇒εA ⇒ aA ⇒ aA ⇒ aA ⇒ aaA ⇒ aa……∴S ⇒ AB ⇒ a m b n c n , 其中m≥0,n≥1即L(G1)={ a m b n c n | m≥0,n≥1} S ⇒ aS ⇒ aA ⇒ aaS ⇒ aaaS ⇒ aA ⇒ aaS ⇒ aaaA ⇒aaaaS ⇒ aaaaa ……∴S ⇒ a2n+1 , 其中n≥0即L(G2)={ a2n+1 | n≥0}2.11 已知文法G[S]: S->(AS)|(b)A->(SaA)|(a)请找出符号串(a)和(A((SaA)(b)))的短语、简单短语和句柄。
编译原理递归下降分析法C语言
编译原理递归下降分析法C语言编译原理是计算机科学中的一个重要领域,主要研究如何将高级语言程序转化为机器可执行的目标代码。
在编译原理中,递归下降分析法是一种常用的语法分析方法,它通过递归地从上至下对程序进行分析,最终确定程序的语法结构。
递归下降分析法是一种自顶向下的语法分析方法,基于产生式和预测分析表来实现对程序的语法分析。
该方法的基本思想是,每个非终结符对应一个处理过程,通过递归调用这些处理过程来分析整个程序。
在C语言的递归下降分析法中,需要定义对应C语言语法结构的处理过程,这些处理过程通常对应于C语言中的各种语句、表达式、声明等。
递归下降分析法的实现主要包括两个步骤:构造预测分析表和编写递归下降分析程序。
预测分析表是一个二维表格,行对应于非终结符,列对应于终结符,表格中的每个元素记录了该产生式的编号。
通过预测分析表,可以预测下一个分析符号,并选择相应的产生式进行语法分析。
编写递归下降分析程序时,首先需要确定递归下降分析程序的数据结构和接口。
一般来说,分析程序的数据结构包括符号栈、语法树等,接口包括初始化、语法分析、错误处理等。
接下来,根据语法规则编写对应的递归下降分析函数,每个函数对应一个非终结符的处理过程。
在实际编写过程中,通常使用递归调用来实现对程序的逐步分析,直到达到终结符。
递归下降分析法在C语言编译器中的应用非常广泛。
通过该方法,可以对C语言程序进行语法分析,检测代码中的语法错误,并生成相应的语法树。
在生成语法树之后,可以继续进行语义分析、中间代码生成、代码优化等编译过程。
总的来说,递归下降分析法是一种重要的语法分析方法,可以用于对C语言程序进行语法分析。
它通过自顶向下的递归调用,从上至下地解析语法规则,最终确定程序的语法结构。
递归下降分析法在实际编译器设计中有广泛应用,是理解和学习编译原理的重要内容。
编译原理 语法分析(2)_ LL(1)分析法1
自底向上分析法
LR分析法的概念 LR分析法的概念 LR(0)项目族的构造 LR(0)项目族的构造 SLR分析法 SLR分析法 LALR分析法 LALR分析法
概述
功能:根据文法规则 文法规则, 源程序单词符号串 单词符号串中 功能:根据文法规则,从源程序单词符号串中
识别出语法成分,并进行语法检查。 识别出语法成分,并进行语法检查。
9
【例】文法G[E] 文法G[E] E→ E +T | T 消除左递归 T→ T * F | F F→(E)|i 请用自顶向下的方法分析是否字 分析表 符串i+i*i∈L(G[E])。 符串i+i*i∈L(G[E])。
E→TE’ E’→+TE’|ε T →FT’ T’→*FT’|ε F→(E)|i
编译程序组织结构
表 处 理
前
端 中
源 程 序
词 法 分 析
语 法 分 析
语 义 分 析
间 代 码 生 成
中 后 目 端 间 标 代 代 码 码 优 生 化 成
目 标 程 序
错 误 处 理
第4章 语法分析
自顶向下分析法
递归子程序法(递归下降分析法) 递归子程序法(递归下降分析法) LL(1)分析法 LL(1)分析法
通常把按LL(1)方法完成语法分析任务的程序叫LL(1)分析程序或者LL(1)分析器。 通常把按LL(1)方法完成语法分析任务的程序叫LL(1)分析程序或者LL(1)分析器。 LL(1)方法完成语法分析任务的程序叫LL(1)分析程序或者LL(1)分析器
输入串
一、分析过程
#
此过程有三部分组成: 此过程有三部分组成: 分析表 总控程序) 执行程序 (总控程序) 分析栈) 符号栈 (分析栈)
编译原理第5章 LL(1)文法及其分析程序
}
else error( )
}
}
27
5.2 预测分析程序(Predictive
parser)无回溯的自顶向下分析程序
特征——根据下一个(几个)输入符号为当前要处理 的非终结符选择产生式
要求——文法是LL(1)的 第一个L 从左到右扫描输入串 第二个L 生成的是最左推导 1 向前看一个输入符号(lookahead)
第5章 LL(1)文法及其分析程序
5.1 自上而下的语法分析 5.2 预测分析程序
递归下降子程序 表驱动的预测分析程序 5.3 LL(1)分析程序的生成
LL(1)文法 FIRST和FOLLOW集 定义和计算 5.4 非LL(1)文法的改造
1
5.1自上而下的语法分析
1语法分析概念 2自上而下的语法分析的一般过程 3自上而下的语法分析面临的问题
到分析结束。
5
分析算法分类
分析算法可分为:
自上而下分析法:
从文法的开始符号出发,寻找与输入符号 串匹配的推导,或者说,为输入串寻找一 个最左推导。
自下而上分析法:
从输入符号串开始,逐步进行归约,直至 归约到文法的开始符号。
6
两种方法反映了语法树的两种构 造过程。
自上而下方法是从文法符号开始,将它做为语法
SaASaSbASaabASaabbaSaabbaa
SaASaSbASaSbAaaabAaaabbaa
4
语法分析
在语言的编译实现中,把句子分析的过程称
为语法分析,即完成这个任务的程序称为 语法分析程序或称为识别程序。分析算法 又称识别算法。 从左到右的分析算法,即总是从左到右地识 别输入符号串,首先识别符号串中的最左 符号,进而依次识别右边的一个符号,直
编译原理实验(二)
实验编号:语法分析(2)一、实验目的及要求编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
1待分析的简单语言的语法用扩充的BNF表示如下:⑴ <程序>::=begin<语句串>end⑵ <语句串>::=<语句>{;<语句>}⑶ <语句>::=<赋值语句>⑷ <赋值语句>::=ID :=<表达式>⑸ <表达式>::=<项>{+<项>卜<项>}⑹<项>::=<因子>{*<因子> | /<因子>⑺ <因子>::=ID | NUM | (<表达式>)2实验要求说明输入单词串,以“ #”结束,如果是文法正确的句子,则输出成功信息,打印“succesS', 否则输出"error”。
例如:输入begin a:=9; x:=2*3; b:=a+x end # 输出success!输入x:=a+b*c end # 输出error二、实验环境Microsoft Visual Studio VC6.0三、算法描述(1)主程序示意图如图2-1所示。
”-1 •: 结束图2-1语法分析主程序示意图(2) 递归下降分析程序示意图如图 2-2所示。
(3)语句串分析过程示意图如图 2-3所示。
调用expression 函数否是 否 是否是否调用语句串分析程序是 否出错处理否syn=O&&kk=O ?是打印分析成功出错处理否否否是2调用term 函数调用statement 函数调用statement 函数调用scaner调用scaner调用scaner 调用scaner图2-2 (4)statement 语 图2-3语句串分析示意图是否:=?是否+ , -?递归下降分析程序示意图J 分析程序流程如图 2-4、2-5、2-6、2-7所示。
1是调用scaner是否end?调用s caner是否标识符?#i nclude"stdio.h"#in elude "stri ng.h" char prog[100],toke n[ 8],ch; char *rwtab [6]={"begi n","if',"the n" ,"while","do","e nd"};int syn ,p,m, n,sum;调用term函数出错处理图2-4 statement语句分析函数示意图出错处理图2-5 expression表达式分析函数示意图四、源程序清单-3 •-4 •int kk;factor();〃 因子 expressio n();〃 表达式judgue();〃 判断语句、下一条语句 term();〃 项stateme nt();〃 赋值语句 lrparser();〃 判断、输出函数 scan er();〃 读下一个字符 yucu();void mai n(){ p=0;printf(- 请输入源程序:\n"); do {scan f("%c",&ch); prog[p++]=ch; }while(ch!='#'); p=0; sca ner(); lrparser(); prin tf(" 语法分析结束! \n");lrparser() {printf(" *********************语法分析程序 ************* **\n");if (syn==1) //begi n{sca ner();yucu();if (syn==6) //end{sca ner();if (sy n==O && kk==O)prin tf("success \n");}else{if(kk!=1)prin tf("error,lose 'end' !\n"); kk=1;}}else{prin tf("error,lose 'beg in' ! \n");kk=1;return 0;}yucu()• 5 •{stateme nt();while(sy n==26) //;{sca ner();stateme nt();}return 0;}stateme nt(){if (sy n==10){sca ner();if (syn==18){sca ner();expressi on();}else{prin tf("error!"); -6 •kk=1;}}else{prin tf("error!");kk=1;}return 0;}expressi on(){term();while(s yn==13 || syn==14){sca ner();term();}return 0;}term(){factor();while(s yn==15 || syn==16)sea ner();factor();-7 •}return 0;}factor(){if(syn==10 || syn==11)scan er(); // 为标识符或整常数时,读下一个单词符号else if(syn==27){sca ner();expressi on();if(sy n==28)sca ner();else{printf("')' 错误\n"); kk=1;}}else{printf(" 表达式错误\n"); kk=1;}return 0;sea ner(){ sum=O;• 8 •for(m=0;m<8;m++)toke n[m]=NULL;〃数组清空m=0;ch=prog[p++];while(ch==' ')ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){toke n[ m++]=ch;ch=prog[p++];}p--;sy n=10;toke n[m++]='\0';for(n=0;n<6;n++)if(strcmp(toke n,rwtab[ n])==0)〃判断是否为关键字{syn=n+1;break;}}else if((ch>='0')&&(ch<='9')){ while((ch>='0')&&(ch<=9)){ sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;-9 •}else switch(ch){ case 'v':m=O; ch=prog[p++]; if(ch=='>'){ syn=21;}else if(ch=='='){ sy n=22;}else{ sy n=20;p--;}break;case '>':m=0; ch=prog[p++]; if(ch=='='){ syn=24;}else{ syn=23;p--;}break;case ':':m=0;ch=prog[p++]; if(ch=='='){ syn=18;-10 •}else{ syn=17;p--;}break;case '+': syn=13; break;case '-': syn=14; break;case '*': syn=15;break;case '/': syn=16;break;case '(': syn=27;break;case ')': syn=28;break;case '=': syn=25;break;case ';': syn=26;break;case '#': syn=0;break; default: syn=-1;break;}return 0;-11 •五、运行结果及分析输入begin a:=9;x:=2*3;b:二a+x end # 输出successerror输入x:=a+b*c end # 输出-12 •。
编译原理课后答案 (3)
编译原理课后答案问题一计算机程序的执行是一个多阶段的过程,其中编译是其中的一环。
请问编译的三个主要阶段分别是什么?答:编译过程一般可以分为三个主要阶段,分别是词法分析、语法分析和代码生成。
下面分别对这三个阶段进行介绍。
1. 词法分析词法分析是编译过程的第一步,也是最基础的一步。
它的任务是将源代码中的字符序列分解成一个个具有独立含义的单词,这些单词被称为“记号”或“词法单元”。
词法分析器根据程序中每一个字符的组合规则,将其转化为一个个词法单元,并记录下词法单元的类型标记。
词法分析器的工作一般通过有限状态自动机来实现,它根据一定的词法规则进行扫描和分析。
2. 语法分析语法分析是编译过程的第二步,它接收词法分析器生成的词法单元流,根据语法规则进行分析,并生成一棵语法树。
语法分析的主要任务是确定输入程序的结构,检查程序的语法正确性,并生成用于后续处理的输入形式。
语法分析器一般采用的是自顶向下或自底向上的分析方法,常用的方法有递归下降法和LR(1)分析法。
3. 代码生成代码生成是编译过程的最后一步,它将语法分析生成的语法树转化为目标机器的可执行代码。
代码生成器通过遍历语法树,将每个语法树节点转化为相应的目标机器代码。
代码生成过程中需要考虑到目标机器的特性和限制,以及优化代码的效率和性能。
问题二请解释一下编译原理中的词法规则是什么?答:编译原理中的词法规则指的是一组规定词法单元模式的规则。
它描述了如何将输入字符序列转换为词法单元,并为每个词法单元定义了一个标记。
词法规则一般使用正则表达式来描述词法单元的模式。
编译器根据词法规则构建词法分析器,用于将源代码分割成一系列的词法单元。
词法规则的灵活性和准确性对编译过程的性能和结果都有较大的影响。
一个完整的词法规则一般包含以下几个部分:1.正则表达式:描述了词法单元的模式,使用特定的正则表达式语法来表示。
2.动作:描述了当词法单元匹配到模式时,需要执行的动作或处理过程。
编译原理之递归下降语法分析程序(实验)
编译原理之递归下降语法分析程序(实验)⼀、实验⽬的利⽤C语⾔编制递归下降分析程序,并对简单语⾔进⾏语法分析。
编制⼀个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
⼆、实验原理每个⾮终结符都对应⼀个⼦程序。
该⼦程序根据下⼀个输⼊符号(SELECT集)来确定按照哪⼀个产⽣式进⾏处理,再根据该产⽣式的右端:每遇到⼀个终结符,则判断当前读⼊的单词是否与该终结符相匹配,若匹配,再读取下⼀个单词继续分析;不匹配,则进⾏出错处理每遇到⼀个⾮终结符,则调⽤相应的⼦程序三、实验要求说明输⼊单词串,以“#”结束,如果是⽂法正确的句⼦,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。
例如:输⼊begin a:=9;b:=2;c:=a+b;b:=a+c end #输出success输⼊a:=9;b:=2;c:=a+b;b:=a+c end #输出‘end' error四、实验步骤1.待分析的语⾔的语法(参考P90)2.将其改为⽂法表⽰,⾄少包含–语句–条件–表达式E -> E+T | TT -> T*F | FF -> (E) | i3. 消除其左递归E -> TE'E' -> +TE' | εT -> FT'T' -> *FT' | εF -> (E) | i4. 提取公共左因⼦5. SELECT集计算SELECT(E->TE) =FIRST(TE')=FIRSI(T)-FIRST(F)U{*}={(, i, *}SELECT(E'->+TE')=FIRST(+TE')={+}SELECT(E'->ε)=follow(E')=follow(E)={#, )}SELECT(T -> FT')=FRIST(FT')=FIRST(F)={(, i}SELECT(T'->*FT')=FRIST(*FT')={*}SELECT(T'->ε)=follow(T')=follow(T)={#, ), +}SELECT(F->(E))=FRIST((E)) ={(}SELECT(F->i)=FRIST(i) ={i}6. LL(1)⽂法判断 其中SELECT(E'->+TE')与SELECT(E'->ε)互不相交,SELECT(T'->*FT')与SELECT(T'->ε)互不相交,SELECT(F->(E))与SELECT(F->i)互不相交,故原⽂法为LL(1)⽂法。
递归下降程序实验报告
一、实验目的1. 理解递归下降分析法的原理和实现方法。
2. 掌握递归下降分析程序的设计和调试。
3. 加深对编译原理中语法分析部分的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 递归下降分析法原理介绍2. 递归下降分析程序的设计与实现3. 递归下降分析程序的调试与测试四、实验步骤1. 递归下降分析法原理介绍递归下降分析法是一种自顶向下的语法分析方法,它将文法中的非终结符对应为分析过程中的递归子程序。
当遇到一个非终结符时,程序将调用对应的递归子程序,直到处理完整个输入串。
2. 递归下降分析程序的设计与实现(1)定义文法以一个简单的算术表达式文法为例,文法如下:E -> E + T| TT -> T F| FF -> ( E )| id(2)消除左递归由于文法中存在左递归,我们需要对其进行消除,消除后的文法如下:E -> T + E'E' -> + T E' | εT -> F T'T' -> F T' | εF -> ( E ) | id(3)设计递归下降分析程序根据消除左递归后的文法,设计递归下降分析程序如下:```cpp#include <iostream>#include <string>using namespace std;// 定义终结符const char PLUS = '+';const char MUL = '';const char LPAREN = '(';const char RPAREN = ')';const char ID = 'i'; // 假设id为'i'// 分析器状态int index = 0;string input;// 非终结符E的分析程序void E() {T();while (input[index] == PLUS) {index++;T();}}// 非终结符T的分析程序void T() {F();while (input[index] == MUL) {index++;F();}}// 非终结符F的分析程序void F() {if (input[index] == LPAREN) {index++; // 跳过左括号E();if (input[index] != RPAREN) {cout << "Error: Missing right parenthesis" << endl; return;}index++; // 跳过右括号} else if (input[index] == ID) {index++; // 跳过标识符} else {cout << "Error: Invalid character" << endl;return;}}// 主函数int main() {cout << "Enter an arithmetic expression: ";cin >> input;index = 0; // 初始化分析器状态E();if (index == input.size()) {cout << "The expression is valid." << endl;} else {cout << "The expression is invalid." << endl;}return 0;}```3. 递归下降分析程序的调试与测试将以上代码编译并运行,输入以下表达式进行测试:```2 +3 (4 - 5) / 6```程序输出结果为:```The expression is valid.```五、实验总结通过本次实验,我们了解了递归下降分析法的原理和实现方法,掌握了递归下降分析程序的设计与调试。
编译原理期末复习题+答案-北华航天工业学院
一、单项选择题概述部分1.构造编译程序应掌握 。
DA. 源程序B. 目标语言C. 编译方法D. 以上三项都是2.编译程序绝大多数时间花在 上。
DA. 出错处理B. 词法分析C. 目标代码生成D. 表格管理3.编译程序是对 。
DA. 汇编程序的翻译B. 高级语言程序的解释执行C. 机器语言的执行D. 高级语言的翻译4. 将编译程序分成若干“遍”,是为了 。
BA. 提高程序的执行效率B. 使程序的结构更为清晰C 利用有限的机器内存并提高机器的执行效率D. 利用有限的机器内存但降低了机器的执行效率词法分析部分1.DFA M(见图1-1)接受的字集为 。
DA. 以0开头的二进制数组成的集合B. 以0结尾的二进制数组成的集合C. 含奇数个0的二进制数组成的集合D. 含偶数个0的二进制数组成的集合 2.词法分析器的输出结果是 。
C A. 单词的种别编码 B. 单词在符号表中的位置C. 单词的种别编码和自身值D. 单词自身值3.正规式M1和M2等价是指 。
CA. M1和M2的状态数相等B. M1和M2的有向边条数相等C. M1和M2所识别的语言集相等D. M1和M2状态数和有向边条数相等4.词法分析器的加工对象是 。
CA .中间代码B .单词C .源程序D .元程序5.同正规式(a|b )*等价的正规式为 。
DA .(a|b)+B .a*|b*C .(ab)*D .(a*|b*)+6. 两个DFA 等价是指: 。
DA. 这两个DFA 的状态数相同B. 这两个DFA 的状态数和有向弧条数都相等C. 这两个DFA 的有向弧条数相等D. 这两个DFA 接受的语言相同7. 下列符号串不可以由符号集S ={a,b}上的正闭包运算产生的是:(A )A. εB. aC. aaD. ab8.称有限自动机A1和A2等价是指________。
DA .A1和A2都是定义在一个字母表上的有限自动机B .A1和A2状态数和有向边数相等C .A1和A2状态数或有向边数相等图1-11D.A1和A2所能识别的字符串集合相等9.同正规式(a|b)+等价的正规式是_______。
第四章3-递归下降法
注意
对于具有多个产生式的非终极符,可用 Case语句进行多分支选择 到底选择哪个产生式进行分析呢? 产生式A→被选择的条件是: 当前要匹配的输入符属于predict(A→)。
问题
例如: 文法中有:A →ac A → ab A的两个产生式的预测集合中都有a,该 调用哪个产生式呢? Swithc(symb){ case a:{….} case a:{….} }
while x>y do if x>z then x:= x+y else x:= y
Begin Match($while); Exp; Match($do); Stm
End
具有多个产生式的非终极符
当产生式中形如: A 1| 2| …| n 则按下面的方法编写子程序A: procedure A( ) begin if tokenPredict(A1) then (1) else if tokenPredict(A2) then (2) else …… if tokenPredict(An) then (n) else err( ) end 其中对i=X1X2…Xn,(i) = ’(X1);’(X2);…;’(Xn); 如果XiVN,’(Xi)= Xi 如果XiVT,’(Xi)= Match(Xi) 如果Xi= , () = skip(空语句)
具有多个产生式的非终极符
当产生式中形如: A 1| 2| …| n 也可以写成 则按下面的方法编写子程序A: Case结构 procedure A( ) begin if tokenPredict(A1) then (1) else if tokenPredict(A2) then (2) else …… if tokenPredict(An) then (n) else err( ) end 其中对i=X1X2…Xn,(i) = ’(X1);’(X2);…;’(Xn); 如果XiVN,’(Xi)= Xi 如果XiVT,’(Xi)= Match(Xi) 如果Xi= , () = skip(空语句)
编译原理分知识点习题自上而下语法分析 (1)
1.设有文法G[S]:S→ABA→bB|AaB→Sb|a试消除该文法的左递归。
解:本题考查消除左递归的方法。
应用消除文法左递归的算法对文法G[S]消除左递归的过程如下:(1)将非终结符排序为:U1=S,U2=A,U3=B(2)进入算法排序:i=1时,对文法无影响i=2,j=1时:A→Aa有直接左递归,消去该直接左递归,得A→bBA’A’→aA’|εi=3,j=1时:改写文法,有B→ABb|aj=2时:改写文法,有B→bBA’Bb|a无左递归。
(3)所以文法G[S]消除左递归后变为:G’[S]:S→ABA→bBA’A’→aA’|εB→bBA’Bb|a2.设有文法G[E]:E→Aa|BbA→cA|eBB→bd试按照递归子程序法为该文法构造语法分析程序。
解:本题考查递归子程序的构造方法。
首先判断文法是否满足递归子程序法对文法的要求,然后再构造递归子程序。
因为:(1)该文法无左递归。
(2)文法的产生式E→Aa|Bb和A→cA|eB的右部有若干选项,判断这两条产生式右部各候选式的终结首符号集合是否两两互不相交。
对产生式E→Aa|Bb,有FIRST(Aa)∩FIRST(Bb)={c,e}∩{b}=ø对产生式A→cA|eB,有FIRST(cA)∩FIRST(eB)={c}∩{e}=ø文法中其他产生式都只有一个非空ε的右部。
综合(1)、(2),该文法可以采用自上而下分析方法进行语法分析而不会出现回朔和无限循环。
下面为该文法的每一个非终结符号构造递归子程序。
假设用READAWORD代表读下一个单词。
用P(E)、P(A)、P(B)分别表示非终结符号E、A、B对应的子程序名。
约定输入符号串以“#”作为输入结束符。
P(E)的递归子程序为:PROCEDURE P(E);BEGINIF WORD IN FIRST(Aa)THENBEGINP(A);READAWORD;IF WORD=’a’THEN READAWORDELSE ERRORENDELSE IF WORD IN FIRST(Bb)THENBEGINP(B);READAWORD;IF WORD=’b’THEN READAWORDELSE ERRORENDELSE ERROREND;P(A)的递归子程序为:PROCEDURE P(A);BEGINIF WORDD=’c’THENBEGINREADAWORD;P(A)ENDELSE IF WORD=’e’THENBEGINREADWORD;P(B)ENDELSE ERROREND;P(B)的递归子程序为:PROCEDURE P(B);BEGINIF WORD=’b’THENBEGINREADAWORD;IF WORD=’d’THEN READAWORDELSE ERRORENDELSE ERROREND;主程序中的主要内容为:READAWORD;P(E);IF WORD=”#”THEN WRITE(“RIGHT!”)ELSE WRITE(“ERROR!”)3.已知文法G[E]:G[E]:E→E+T|TT→T*F|FF→i|(E)请按递归子程序法为其构造语法分析程序。
递归下降法
题目:编程识别由下列文法所定义的表达式的递归下降语法分析器。
E→E+T | E-T | TT→T*F | T/F |FF→(E) | i输入:每行含一个表达式的文本文件。
输出:分析成功或不成功信息。
解答:(1)分析a) ∵E=>E+T=>E+T*F=>E+T*(E)即有E=>E+T*(E)存在左递归。
用直接改写法消除左递归,得到如下:E →TE’E’→+TE’ | −TE’|εT →FT’T’→*FT’ | /FT’|εF → (E) | ib) 对于以上改进的方法。
可得:对于E’:FIRST( E’ )=FIRST(+TE’)∪FIRST(-TE’)∪{ε}={+,−,ε} 对于T’:FIRST( T’ )=FIRST(*FT’)∪FIRST(/FT’)∪{ε}={*,∕,ε}而且: FIRST( E ) = FIRST( T ) = FIRST( F )=FIRST((E))∪FIRST(i)={(,i }由此我们容易得出各非终结符的FOLLOW集合如下:FOLLOW( E )= { ),#}FOLLOW(E’)= FOLLOW(E)={ ),#}FOLLOW( T )= FIRST(E’)\ε∪FOLLOW(E’)={+,−,),#}FOLLOW( T’ ) = FOLLOW( T ) ={+,−,),#}FOLLOW( F )=FIRST(T’)\ε∪FOLLOW(T’)={*,∕,+,−,),#}由以上FOLLOW集可以我们可以得出SELECT集如下:对E SELECT(E→TE’)=FIRST(TE’)=FIRST(T)={ (,i }对E’ SELECT(E’→+TE’)={ + }SELECT(E’→−TE’)={ − }SELECT(E’→ε)={ε,),#}对T SELECT(T→FT’)={(,i}对T’ SELECT(T’→*FT’)={ * }SELECT(T’→∕FT’)={ ∕ }SELECT(T’→ε)={ε,+,−,),#}对F SELECT(F→(E) )={ ( }SELECT(F→i)={ i }∴SELECT(E’→+TE’)∩SELECT(E’→−TE’)∩SELECT(E’→ε)=ΦSELECT(T’→*FT’)∩SELECT(T’→∕FT’)∩SELECT(T’→ε)=ΦSELECT(F→(E) )∩SELECT(F→i)= Φ由上可知,有相同左部产生式的SELECT集合的交集为空,所以文法是LL (1)文法。
编译原理语法分析—自上而下分析
对文法G的任何符号串=X1X2…Xn构造集 合FIRST()。
1. 置FIRST()=FIRST(X1)\{};
2. 若对任何1ji-1,FIRST(Xj), 则把FIRST(Xi)\{}加至FIRST()中; 特别是,若所有的FIRST(Xj)均含有, 1jn,则把也加至FIRST()中。显 然,若=则FIRST()={}。
T→T*F | F
F→(E) | i
经消去直接左递归后变成:
E→TE E→+TE | T→FT T→*FT | F→(E) | i
(4.2)
例如文法G(S): S→Qc|c Q→Rb|b R→Sa|a
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
(4.3)
一个文法消除左递归的条件: 不含以为右部的产生式 不含回路。
即A的任何两个不同候选 i和 j FIRST(i)∩FIRST( j)=
当要求A匹配输入串时,A就能根据它所面临的第
一个输入符号a,准确地指派某一个候选前去执
行任务。这个候选就是那个终结首符集含a的。
提取公共左因子:
假定关于A的规则是 A→ 1 | 2 | …| n | 1 | 2 | … | m (其中,每个 不以开头)
*
特别是,若S A ,则规定
#FOLLOW(A)
构造不带回溯的自上而下分析的文法条件
1. 文法不含左递归,
2. 对于文法中每一个非终结符A的各个产生式 的候选首符集两两不相交。即,若
A→ 1| 2|…| n 则 FIRST( i)∩FIRST( j)= (ij)
3. 对文法中的每个非终结符A,若它存在某个 候选首符集包含,则
1)算符优先分析法:按照算符的优先关系和结 合性质进行语法分析。适合分析表达式。
编译原理课程设计WHILE循环语句的翻译程序设计(递归下降法、输出四元式)
学号:课程设计题目WHILE循环语句的翻译程序设计(递归下降法、输出四元式)学院计算机科学与技术专业计算机科学与技术班级计算机班姓名指导教师2012 年 1 月 6 日目录1.问题描述 (3)1.1问题描述 (3)1.2主要任务 (3)1.3测试数据 (3)2文法及属性文法的描述 (3)2.1文法的描述 (3)2.2 while-do循环语句的文法 (4)2.3递归文法的优化 (4)2.4属性文法的描述 (5)3.语法分析方法描述 (6)3.1程序设计对文法的要求 (6)3.2语法分析的思想 (7)3.3递归下降文法实现原理 (7)3.4中间代码形式 (8)4简要的分析与概要设计 (8)4.1全局程序的概要设计 (8)4.2词法分析 (9)4.3递归下降翻译器的设计 (9)4.4语法制导翻译 (10)5详细的算法描述 (10)5.1算法描述 (10)5.2运行结果 (14)6. 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等). 156.1研制过程 (15)6.2本设计的评价、特点 (16)6.3感受和体会 (16)6.4对程序改进的想法 (17)课程设计任务书学生姓名:专业班级:计算机班指导教师:工作单位:计算机科学与技术学院题目: WHILE循环语句的翻译程序设计(递归下降法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码四元式的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
北华航天工业学院
《编译原理》课程实验报告
课程实验题目:递归下降子程序实验作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术
作者所在班级:xxxx
作者学号:xxxxx _ 作者姓名:xxxx
指导教师姓名:xxxxx
完成时间:2011年3月28日
一、实验目的
通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。
分析递归下降子程序的优缺点。
二、实验内容及要求
1.针对算术表达式文法:E→TE’
E’→ +TE’|ε
T→FT’
T’→*FT’ |ε
F→(E) |i
为其编写递归下降子程序,判定某个算术表达式是否正确:如j+k*m,j*k+m
输入:其输入数据应该为词法分析器输出的记号形式:i+i*i,i*i+i
输出:分析结果:算术表达式结构正确或结构错误。
三、实验程序设计说明
1.实验方案设计
各个函数之间的调用关系如下图所示:
2.程序源代码
源代码如下:
#include<stdio.h>
#include<iostream>
#include<fstream>
#include<string>
char a[10];
int lookahead=0;
void E1();
void T();
void T1();
void F();
void E()
{
printf("E->TE'\n");
T();
E1();
}
void E1()
{
if(a[lookahead]=='+')
{
printf("E'->+TE'\n");
lookahead++;
T();
E1();
}
else
printf("T'->ε\n"); }
void T()
{
printf("T->FT'\n");
F();
T1();
}
void T1()
{
if(a[lookahead]=='*')
{
printf("T'->*FT'\n");
lookahead++;
F();
T1();
}
else
printf("T'->ε\n"); }
void F()
{
if(a[lookahead]=='i')
{
printf("F->i\n");
lookahead++;
}
else if (a[lookahead]=='(')
{
lookahead++;
E();
if(a[lookahead]==')'){
printf("F->(E)\n");
lookahead++;
}
else{
printf("\n括号不匹配分析失败!\n");
exit (0);
}
}
else{
printf("括号不匹配,分析失败!\n");
exit(0);
}
}
int main()
{
while(1)
{
printf("请输入算数表达式(以#键结束):");
scanf("%s",a);
E();
if((a[lookahead]=='#'))
printf("句子结构正确\n");
else
printf("无结束标志,分析失败\n");
}
return 0;
}
3.程序的执行结果
程序运行结果如下所示:
四、实验中出现的问题及解决方法
1.错误处理:最初程序只是将所有的错误都简单的显示为句子结构错误,并没有进行具体详细的说明和解释,最后通过修改程序,细化错误类型,使用了对if语句的嵌套,将错误分为三种类型。
2.句子结构分析:最初程序只能分析结构比较简单的句子类型,比如输入的字符不匹配等问题,输入类似i+i*+等缺少操作数结构类型的句子则不能做出正确的判断,通过修改
F()等相关函数解决了这个问题;但此程序只能分析此类文法的句子结构,如果文法改变则需要修改程序,才能进一步分析对应的句子结构。
尽管,在实验过程中遇到的问题得到了解决,但是仍然有很多缺陷。
尤其是在进行错误处理时只有三种,并不完善,并没有对错误进行详细的分析和说明的功能。
五、体会、意见或建议
通过本次实验基本掌握了语法分析的原理和递归下降子程序分析方法,通过编写程序进一步复习巩固了c语言的相关知识,由于对c语言的掌握不扎实,在编程过程中遇到了很多基础性问题,通过不断的查阅课本,最终解决了问题,但程序仍然存在很多值得改进和完善的地方,这就提醒我们在以后的学习过程当中应该及时复习巩固以前学过的相关知识。