第六章 算符优先分析文法

合集下载

算符优先分析编译原理演示文稿

算符优先分析编译原理演示文稿
算符优先分析编译原理演示文 稿
(优选)算符优先分析编译原 理
6.3 算符优先分析法
算符优先文法的定义 算符优先关系表的构造 算符优先分析算法 算符优先分析法的局限性
6.3.1 算符优先分析
• 自下而上分析算法模型----移进归约 • 算符优先分析不是规范归约
算符优先分析的可归约 串是句型的最左素短语 定义: cfg(上下文无关文法) G 的句型的素短
2)’<‘关系
– 求出每个非终结符B的FIRSTVT(B)
– 若A→…aB…,则b∈FIRSTVT(B),则a<b
3)’>’关系
– 求出每个非终结符B的LASTVT(B)
– 若A→…Bb…,则a∈LASTVT(B),则a>b
计算算符优先关系
例文法G’[E’]: (0) E’→#E# (1) E→E+T (2) E→T (3) T→T*F (4) T→F (5) F→PF|P (6) P→(E) (7) P→i
例 G’[E]:
算符优先关表
E→E+T|T
T→T*F|F F→P↑F|P
P→(E)|i
+ * ( ) i#
+>< << >< >
*> > < < > < >
> > < < > < >
( < < < <=<
)>>>
>
>
i >>>
>
>
#< < < <
<=

算符优先分析大学编译原理

算符优先分析大学编译原理
1
6.1 自底向上优先分析概述
• 有两种优先分析法: 1。 简朴优先分析法:
求出文法全部符号(终止符,非终止符) 之间优先关系,按这种关系拟定规约过 程中旳句柄。 2。算符优先分析法:考虑算符之间优先关 系旳规约(非规范规约)
2
6.3 算符优先分析法
算符优先文法旳定义 算符优先关系表旳构造 算符优先分析算法 算符优先分析法旳不足
• 比规范归约快 • 可能造成把错误旳句子得到正确旳归约。
该措施仅合用于体现式旳语法分析
17
利用算符优先分析算法分析输入串
• 举例 p115: 分析输入串i+i#
• G’[E]: E→E+T|T T→T*F|F F→P↑F|P P→(E)|i
+ * ( ) i#
+>< << >< >
*> > < < > < >
第6章 自低向上优先分析
• 即移进-规约分析。思想: 对符号串自左向右扫描,将输入符号移入一种 后进先出栈中,边移入边分析,一旦栈顶符号 串形成某个句型旳句柄或可规约串时(该句柄 或可规约串相应某个产生式右部),就用该产 生式旳左部非终止符替代相应右部旳文法符号 串,即规约。反复这一过程,直到栈中只剩余 文法旳开始符号时则以为分析成功,即输入旳 符号串是文法旳句子。
E E+ T E +T F
T T* F i
E
E+T
E+T F
T
i
句型T+T+F旳素短语为:T+T
5
分析程序模型
输入串#
总控程序
输出
# 算符优先关系表 产生式

第6章 LR分析

第6章 LR分析

(3)查状态转换表,新的状态进状态栈。 ※接受:分析成功,终止分析。 ※出错:报告出错信息。 (2) 具体分析过程:
LR分析算法
• 置ip指向输入串w的第一个符号
▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ 令S为栈顶状态 a是ip指向的符号 重复 begin if ACTION[S,a]=Sj then begin PUSH j,a(进栈) ip 前进(指向下一输入符号) end else if ACTION[S,a]=rj (第j条产生式为A)
Action[sm, ai]= sj 表示移进ai ,并转 j 状态 格局变为: 分析栈 s0s1… sm j 输入串 #X1…Xmai ai+1…an#
4、LR分析器的工作过程(续2)
Action[sm, ai]= rj 表示用第 j 条产生式 A→Xm-(k-1)…Xm (有k个符号) 进行归约, 格局变为: 分析栈 s0s1… sm-k 输入串 #X1…Xm-kA aiai+1…an#
2、LR分析器的逻辑结构
• 一个输入串,结束符#,指针ip指当前符号。 • 一个下推分析栈,状态栈和符号栈合在一起,记录 分析的历史和展望材料。状态栈顶的状态sn, 是能识 别符号栈中的符号串X1X2…Xn 的DFA的状态。 • 一个LR分析表,两个子表合在一起。 • 一个LR分析程序,其大致的工作过程:分析的每一 步都根据分析栈顶的状态和当前输入符号,查分析 表,以决定下一步的动作。 • 不同的LR分析器,其总控程序都一样,不同的是其 LR分析表,构造LR分析表的方法不同就形成各种不 同的LR分析法。
一、相关概念
前缀是指该字的任意首部。
例:字abc 的前缀有ε,a,ab,abc
活前缀:是指规范句型的一个前缀,这种

算符优先_实验报告

算符优先_实验报告

一、实验目的1. 理解算符优先分析法的原理和过程。

2. 掌握算符优先分析法的实现方法。

3. 通过实验加深对自底向上语法分析方法的理解。

二、实验内容1. 算符优先分析法原理介绍算符优先分析法是一种自底向上的语法分析方法,它通过比较相邻算符的优先次序来识别句型中的句柄,进而执行归约。

该方法的核心是确立文法的终结符之间的优先关系。

2. 实验步骤(1)判断文法是否为OG文法:OG文法要求所有产生式右部至少有一个终结符。

(2)判断文法是否为OPG文法:计算FIRSTVT集、LASTVT集,并构建算符优先矩阵。

(3)对句子进行分析:根据分析表判断句子是否为文法的句子。

(4)实现程序:从文件和键盘读取输入,将结果输出到指定文件和屏幕,并具有一致性。

3. 实验数据(1)文法:g[e]:e->e+t|t(2)测试句子:12+t, t+12, 12+13t, 12+t13三、实验过程1. 判断文法是否为OG文法根据给定的文法,我们可以看到所有产生式右部至少有一个终结符,因此该文法为OG文法。

2. 判断文法是否为OPG文法,并构建算符优先矩阵(1)计算FIRSTVT集FIRSTVT(e) = {t}FIRSTVT(t) = {t}(2)计算LASTVT集LASTVT(e) = {t}LASTVT(t) = {t}(3)构建算符优先矩阵| + - ( ) t e $+ > - - - > > -- > - - - > > -> > > > > > >( > > > > > > >) - - - - - - -t - - - - - - -e - - - - - - -$ - - - - - - -3. 对句子进行分析(1)分析句子“12+t”根据分析表,我们可以得到以下分析过程:12+t -> 12+t -> 12+t -> t -> t(2)分析句子“t+12”根据分析表,我们可以得到以下分析过程:t+12 -> t+12 -> t+12 -> t+12 -> t+12 -> t -> t (3)分析句子“12+13t”根据分析表,我们可以得到以下分析过程:12+13t -> 12+13t -> 12+13t -> 12+13t -> 12+13t -> t -> t(4)分析句子“12+t13”根据分析表,我们可以得到以下分析过程:12+t13 -> 12+t13 -> 12+t13 -> 12+t13 -> 12+t13 -> t13 -> t13 -> t13 -> t -> t四、实验结果1. 测试句子“12+t”分析结果:正确2. 测试句子“t+12”分析结果:正确3. 测试句子“12+13t”分析结果:正确4. 测试句子“12+t13”分析结果:正确五、实验总结通过本次实验,我们深入了解了算符优先分析法的原理和实现方法。

算符优先文法分析

算符优先文法分析

算符优先文法分析1.问题描述基于算符优先分析法的语法分析程序要求:(1)输入已知文法,生成文法矩阵,判断该文法是否是算符优先文法。

(2)用程序自动生成该文法的算符优先关系矩阵。

(3)对人工输入的句型或句子,分析该句型或句子是否合法,能否用已知文法推出。

(4)具有通用性。

所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为算符优先文法。

(5)有运行实例。

对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。

2.算符优先分析法2.1算符优先文法定义:设有不含空串的一文法G,如果G中没有形如G>……BC……的产生式,其中B和C为非终结符,且对任意两个终结符a,b之间之多只有<,>,=,三种关系的一种成立,则称G是一个算符优先文法。

非终结符的FIRSTVT集合和LASTVT集合FIRSTVT(B)={b|B→b…或B→Cb…}LASTVT(B)={b|B→…a或B→…aC}2.2算符优先矩阵算符优先关系矩阵,判断输入是否满足已知文法的依据。

根据非终结符的FIRSTVT集合和LASTVT集合产生。

1.“=”关系若A→…ab…或A→…aBb…,则a=b;2.“〈⋅”关系若A→…aB…,对每一个b属于FIRSTVT(B),有a〈⋅b;3.“⋅〉”关系若A→…Bb…,对每一个a属于LASTVT(B),有a⋅〉 b。

2.3如何规约在分析过程中,利用分析栈存放已识别的那部分句型,而句型的其余部分由剩余输入串组成,通过比较栈顶符号和下一个输入符号之间的关系,可以判别栈顶符号是否为句柄尾符号。

如果是句柄尾,则沿栈顶向下,在栈内寻找句柄头(利用关系)。

由关系和关系之间包括的符号串就是句柄,然后把它们弹出栈,并代之以归约后的非终结符。

这样就完成了一次归约过程。

2.4算符优先分析方法的局限性由于算符优先分析法去掉了单非终结符之间的归约,尽管在分析过程中,当决定是否为句柄时采取一些检查措施,但仍难完全避免把错误的句子得到正确的归约。

第六章 语法分析-自下而上分析法

第六章 语法分析-自下而上分析法

一、自下而上语法分析的基本问题 1.归约: 如何判断栈顶符号的可归约性以及如何归约,是 自下而上分析的中心问题。 2.短语和句柄
如果S ⇒ αAβ and A ⇒γ,则称γ是句型 αγβ的相对于变量A的短语 * 如果S ⇒αAβ and A⇒γ,则称γ是句型 αγβ的相对于变量A的直接(简单)短语 最左直接短语叫做句柄
e
abbcde
一、自下而上语法分析的基本问题 (3)自下而上分析的关键问题
似乎移进-归约过程很简单,其实不然,在上面第5步,如果用 规则2(P → b)进行归约而不是用规则3(P → Pb)进行归约,结果 会怎么样呢? 上面的归约过程是从文法的句子abbcde开始,每一步都是把最 左直接短语(句柄)替换为相应产生式的左部符号(在步骤5时 栈顶为#aPb,此时是将b归约为P还是将Pb归约为P?由于此时对 于句型aPbcde(即栈内容+输入缓冲区内容)来说Pb是句柄,故 将Pb归约为P)。也就是说,自底向上分析的关键问题是在分析 中如何确定句柄(准确地说为可归约串),即如果知道何时在 栈顶符号串中已形成了某句型的句柄,那么就可以确定何时进 行归约。对此,不同的分析方法有不同的解决办法。这里主要 介绍算符优先及LR分析方法。
例: 移进—归约分析(Shift-reduce parsing)
要点:建立符号栈,用来纪录分析的历史和现状, 并根据所面临的状态,确定下一步动作是移 进还是归约。
输入串 # 符号栈 #
S.R.P
输入串 # 符号栈 #
S.R.P
分析过程:把输入符号串按自左向右顺序一一地 移进符号栈(一次移一个),检查栈中符号,当在栈 顶的若干符号形成当前句型的句柄时,就根据规则进 行归约,将句柄从符号栈中弹出,并将相应的非终结 符号压入栈内(即规则的左部符号),然后再检查栈 内符号串是否形成新的句柄,若有就再进行归约,否 则移进符号。分析一直进行到读到输入串的右界符为 止。最后,若栈中仅含有左界符号和识别符号,则表 示分析成功,否则失败

编译原理之算符优先分析

编译原理之算符优先分析

编译原理之算符优先分析1.算符优先分析:1.1定义是⼀种简单直观、⼴泛使⽤、便于⼿⼯实现的⾃下⽽上的语法分析⽅法。

1.2原理定义算符之间的某种优先关系,寻找“归约串”,并进⾏归约1.3相关知识拓展1.3.1 算符⽂法:产⽣式的右部不包含两个相继的⾮终结符,即不包含形如:.....QR.....1.3.2 算符优先⽂法:任何终结符对(a,b)⾄多⼀种优先级关系。

1.3.3 构造优先关系表步骤:(1)写出FIRSTVT、LASTVTFIRSTVT(P)={a|P->a.....或P->Qa......}LASTVT(P)={a|P->.....a或P->......aQ} (2)列表,根据优先级填表 1.确定同⼀产⽣式的末尾终结符之间⽆优先关系 2.确定=,再使⽤FIRSTVT、LASTVT1.4 算符优先分析算法 素短语:⾄少包含⼀个终结符且不包含更⼩的终结符,如p*p或 i 最左素短语:最左侧的素短语 缺点:跳过了所有单⾮产⽣式所对应的归约步骤。

(单⾮产⽣式:形如:P->Q ,右部只有⼀个⾮终结符的产⽣式)1.5 构造优先函数使⽤构造优先函数代替优先表f:表⼊栈优先函数、g:表⽐较优先函数1.6 举例S→a|Λ|(T) T->T,S|S(1)基本了解:FIRSTVT(P)={a|P->a.... or Qa....}; LASTVT(P)={a|P->...a or P->....aQ}所以对于:S→a|Λ|(T) 则FIRSTVT(S)={a,Λ,(}对于:S→a|Λ|(T) 则LASTVT(S)={a,Λ,)}对于:T->T,S|S 则FIRSTVT(T)={, ,a,Λ,(}对于:T->T,S|S 则LASTVT(T)={, ,a,Λ,)}(2)优先关系aΛ(),a>>Λ>>(<<<=<)>>,<<<>>,<<<>>由于G[S]中任何终结符对(a,b)之多只有⼀种关系成⽴,所以,G[S]为算符优先⽂法。

算符优先算法

算符优先算法

算符优先算法1. 算符优先算法简介算符优先算法(Operator Precedence Parsing)是一种用于解析和计算表达式的方法。

它通过定义运算符之间的优先级和结合性来确定表达式的计算顺序,从而实现对表达式的准确解析和计算。

在算符优先算法中,每个运算符都被赋予一个优先级,表示其与其他运算符之间的优先关系。

根据这些优先级规则,可以将一个表达式转化为一个操作符和操作数构成的序列,并按照一定的顺序进行计算。

2. 算符优先文法在使用算符优先算法进行解析时,需要定义一个文法来描述运算符之间的关系。

这个文法称为算符优先文法。

一个典型的算符优先文法由以下三部分组成:1.终结符:表示可以出现在表达式中的基本元素,例如数字、变量名等。

2.非终结符:表示可以出现在表达式中但不能作为最终结果输出的元素,例如运算符。

3.产生式:描述了如何将非终结符转化为终结符或其他非终结符。

通过定义合适的产生式规则,可以建立起非终结符之间的优先关系。

这些优先关系决定了表达式中运算符的计算顺序。

3. 算符优先表算符优先表(Operator Precedence Table)是算符优先算法的核心数据结构之一。

它用于存储运算符之间的优先级和结合性信息。

一个典型的算符优先表由以下几部分组成:1.终结符集合:包含所有可能出现在表达式中的终结符。

2.非终结符集合:包含所有可能出现在表达式中的非终结符。

3.优先关系矩阵:用于存储运算符之间的优先关系。

矩阵中每个元素表示两个运算符之间的关系,例如“<”表示左运算符优先级低于右运算符,“>”表示左运算符优先级高于右运算符。

“=”表示两个运算符具有相同的优先级。

通过使用算符优先表,可以根据当前输入字符和栈顶字符来确定下一步应该进行的操作,例如移进、规约等。

4. 算法流程下面是一个简化版的算法流程:1.初始化输入串、操作数栈和操作符栈。

2.从输入串中读取一个字符作为当前输入字符。

3.如果当前输入字符为终结符,则进行移进操作,将其压入操作数栈,并读取下一个输入字符。

算符优先分析法

算符优先分析法



a b 表示a的优先级低于b a b 表示a的优先级等于b a b 表示a的优先级大于b 若a,b在任何情况下不可能相继出现,则a,b无关系
表6.2
+ * / id ( ) #
优先关系表
* / id ( ) #
initial
a+b*c#
T1 a + # T2
#<· + +<· *
a #
控制程序
B a #
控制程序
6.2 简单优先分析法

定义

一个文法G,如果它不含ε产生式,也不含任何右部 相同的不同产生式,并且它的任何符号对(X,Y), X,Y∈V或者没有关系,或者存在优先级相同或低于、 高于等关系之一,则这是一个简单优先文法。 X Y 当且仅当G中含有形如P→„XY„ X <·Y 当且仅当G中含有形如P→„XQ„,且Q X · > Y 当且仅当G中含有形如P→„QR„,且 Q „X,R Y„(Y∈FIRST(R)),Y∈VT。
语法分析

推导——自顶向下的语法分析过程

预测分析程序,递归下降分析法(最左推导) 要求文法是LL(1)文法

归约——自底向上的语法分析过程


简单优先分析法,算符优先分析法 LR分析法
自底向上的语法分析过程思想

自底向上语法分析过程是一个最左归约的过程 (规范推导的逆过程,亦称规范归约),从输入 串开始,朝着文法的开始符号进行归约,直到 到达文法的开始符号为止的过程。
例6.1 文法G[S] 产生式如下: ①S→aAcBe ②A→b ③A→Ab ④B→d 输入串 abbcde是不是文法的句子? SaABe aAde aAbcde abbcde

简单优先和算符优先分析方法

简单优先和算符优先分析方法

简单优先和算符优先分析方法简单优先分析(Simple Precedence Parsing)和算符优先分析(Operator Precedence Parsing)是两种常用的自底向上的语法分析方法。

它们是基于符号优先级的理念,通过比较符号之间的优先级关系,来进行语法分析。

1.简单优先分析简单优先分析是一种自底向上的语法分析方法,它利用一个优先级表来确定符号之间的优先关系。

简单优先分析的算法如下:(1)将输入串和符号栈初始化为空。

(2)从输入串中读入第一个输入符号a。

(3)将a与栈顶的符号进行比较:a.如果a的优先级大于栈顶符号的优先级,将a推入符号栈,并读入下一个输入符号。

b.如果a的优先级小于栈顶符号的优先级,将栈中的符号做规约操作,直到栈顶的符号优先级不小于a。

然后,将a推入符号栈。

c.如果a和栈顶符号优先级相等,栈顶的符号出栈,并将a推入符号栈。

(4)重复步骤(3)直到输入串为空。

(5)如果符号栈中只有一个符号且为文法的开始符号,则分析成功。

简单优先分析的优先级表一般由语法规则和符号之间的优先关系组成。

我们可以通过构造优先级关系表来实现简单优先分析。

2.算符优先分析算符优先分析是一种自底向上的语法分析方法,它也是基于符号优先级的理念,但是相对于简单优先分析,算符优先分析更加灵活,并且允许处理左递归的文法。

算符优先分析的算法如下:(1)将输入串和符号栈初始化为空。

(2)从输入串中读入第一个输入符号a。

(3)将a与栈顶的符号进行比较:a.如果a的优先级大于栈顶符号的优先级,将a推入符号栈,并读入下一个输入符号。

b.如果a的优先级小于栈顶符号的优先级,将栈中的符号做规约操作,直到栈顶的符号优先级不小于a。

然后,将a推入符号栈。

c.如果a和栈顶符号优先级相等,根据符号栈中符号的类型执行相应的操作(如归约、移进等)。

(4)重复步骤(3)直到输入串为空。

(5)如果符号栈中只有一个符号且为文法的开始符号,则分析成功。

算符优先分析算法

算符优先分析算法

数学与计算机学院编译原理实验报告年级09软工学号姓名成绩专业软件工程实验地点主楼指导教师湛燕实验项目算符优先关系算法实验日期2012.6.6一、实验目的和要求设计一个算符优先分析器,理解优先分析方法的原理。

重点和难点:本实验的重点是理解优先分析方法的原理;难点是如何构造算符优先关系。

二、实验内容使用算符优先分析算法分析下面的文法:E’→ #E#E → E+T | TT → T*F | FF → P^F | PP → (E) | i其中i可以看作是一个终结符,无需作词法分析。

具体要求如下:1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况;2、如果输入符号串不是正确句子,则指示出错位置。

三、程序设计全局变量有一下几个:static string input;//记录输入串char s[20];//栈int top=-1;//栈顶指针有三个函数:int analyze(string input);//分析输入的串是否符合标准void process();//进行归约的函数int main()input是一个全局变量,记录输入串,用analyze(input)分析输入的是不是符合标准的字符串,(例如“i+i*i^(i+i)”)如果不符合标准,提示用户重新输入。

进行归约的函数主要思想是:先构造优先关系矩阵,有“<”,“>”,“=”和空格四种关系。

Char a 记录栈中最高位的终结符,如果栈中是#E+E,则 a 的赋值是“+”,如果形如“#E+”或“#E+i”则a 赋值“+”或“i”。

charnowchar 记录当前的字符。

a 与 nowchar 按照算符优先关系矩阵找出优先关系。

如果优先关系是“<”,则进行移进;如果优先关系是“>”,则进行归约;如果是“=”,则去掉括号或分析成功。

五、代码和截图自己编写代码如下:#include <iostream>#include <string>using namespace std;static string input;//输入串char s[20];//栈int top=-1;//栈顶指针char VT[7]={'+','*','^','i','(',')','#'};//终结符static char matrix[7][7]={'>','<','<','<','<','>','>','>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>',' ',' ','>','>','<','<','<','<','<','=',' ','>','>','>',' ',' ','>','>','<','<','<','<','<',' ','='}; //优先关系矩阵,不存在优先关系时为空格int analyze(string input);//分析输入的串是否符合标准void process();//规约int main(){//cout<<"输入一个符号串!"<<endl;int flag=1;while(flag==1){cout<<"输入一个符号串!"<<endl;cin>>input;if(analyze(input)==0)flag=1;elseflag=0;}cout<<"***********************************************************"<<endl;cout<<" 表达式文法算符优先关系表"<<endl;cout<<endl;for(inti=0;i<8;i++){cout<<" "<<VT[i];}cout<<endl;cout<<endl;for(i=0;i<7;i++){cout<<VT[i];for(int j=0;j<7;j++){cout<<" ";cout<<matrix[i][j];}cout<<endl;}//cout<<<<endl;cout<<"********************************************************** *"<<endl;cout<<"对输入串"<<input<<"的算符优先分析过程如下:"<<endl;process();cout<<""<<endl;//cout<<" 栈"<<" 优先关系"<<" 当前符号"<<" 剩余输入串"<<" 移进或规约"<<endl;cout<<""<<endl;cout<<""<<endl;cout<<""<<endl;return 1;}int analyze(string input)//分析输入的串是否符合标准{//cout<<input[0]<<input[1]<<input[2]<<input[3]<<endl;intlen = input.length();//获得输入串长度//cout<<len<<endl;int flag=0;//char t;////char temp;for(inti=0;i<len;i++){if((input[len-1]!='i')&&(input[len-1]!=')')) {flag=1;break;}//cout<<input[len-1]<<endl;switch(input[i]){case '(':if(i==0){}else if(input[i-1]=='^'||'+'||'*'){}elseflag=1;break;case ')':if(input[i-1]=='i'){}elseflag=1;break;case '*':if(input[i-1]=='i'||')'){}//cout<<i<<flag<<endl;elseflag=1;break;case '^':if(input[i-1]=='i'||')'){}//cout<<i<<flag<<endl;elseflag=1;break;case '+':if(input[i-1]=='i'||')'){}//cout<<i<<flag<<endl;elseflag=1;break;case 'i':{if(input[len-1]=='i')flag=1;else{}}// cout<<i<<flag<<"输入的是正确的字符串!"<<endl;break;default:// cout<<flag<<endl;flag=1;break;}}//int flag=0;if(flag==0){cout<<"输入的是正确的句子!"<<endl;return 1;}else{cout<<"输入的是错误的句子!"<<endl;return 0;}}void process()//规约{//cout<<s<<endl;//cout<<top;int row;//列int line;//行s[++top]='#';//input="i+i*(i+i)";//cout<<input<<endl;input=input+'#';////cout<<input<<endl;//char temp;inti=0;int k=0;int g;char a;//char nowchar;//++top;//s[top]=input[i];//cout<<s[top-1]<<endl;//cout<<input[i]<<endl;//cout<<s[top]<<endl;int flag=0;char nowchar;//记录当前字符cout<<endl;cout<<"栈"<<" 优先关系"<<" 当前符号"<<" 剩余输入串"<<" 移进或归约"<<endl;nowchar=input[0];while(flag==0)//s[2]!='#'{ //k++;if(s[top]=='E')a=s[top-1];elsea=s[top];for(int n=0;n<7;n++)//记录行{if(a==VT[n])line=n;}for(n=0;n<7;n++)//记录列{if(nowchar==VT[n])row=n;}char compare;for(int m=0;m<7;m++)for(n=0;n<7;n++){if((line==m)&&(row==n))compare=matrix[m][n];}int j;//i=top;///cout<<"******"<<compare<<"******"<<endl;switch(compare){case '<':{//cout<<" ";for(j=0;j<=top;j++)cout<<s[j];//cout<<"@"<<a;//cout<<line<<row;cout<<"&&&"<<s[top]<< a<<compare;//cout<<"(栈)";cout<<" <";cout<<" "<<input[i]<<" ";for(j=strlen(s);j<input.length ();j++)cout<<input[j];cout<<" 移进";//<<10-strlen(s)s[++top]=input[i];//移进if(nowchar=='#'){}elsenowchar=input[strlen(s)-1];//cout<<nowchar;cout<<endl;//cout<<"(剩余输入串)"<<endl;//cout<<endl;i++;break;}case '>'://cout<<" ";for(j=0;j<=top;j++)cout<<s[j];//cout<<"@"<<a;///cout<<"&&&"<<s[top]<<a;cout<<" >";cout<<" "<<input[i]<<" ";//cout<<" ";for(j=strlen(s);j<input.length ();j++)cout<<input[j];//cout<<" "<<endl;cout<<endl;if(s[top]=='E'){top=top-2;s[top]='E';}else if(s[top]==')'){top=top-2;s[top]='E';}elses[top]='E';//归约//cout<<s[top];//if((s[top]=='E')||(s[top]==')'))//i++;if(nowchar=='#'){}elsenowchar=input[strlen(s)-1];cout<<" 归约"<<endl;break;case '=':if(s[top-1]=='('){top=top-1;//a=s[top];s[top]='E';nowchar='#';}//if(s[top-1]=='(')// {// nowchar='#';// }else//cout<<"规约成功"<<endl;{cout<<"#E# 接受"<<endl;flag=1;}break;}//cout<<s[j];}//}如果输入的句子是错误的,提示错误,并要求重新输入。

编译原理算符优先算法语法分析实验报告

编译原理算符优先算法语法分析实验报告

编译原理算符优先算法语法分析实验报告实验报告:算符优先算法的语法分析一、实验目的本次实验旨在通过算符优先算法对给定的文法进行语法分析,实现对给定输入串的分析过程。

通过本次实验,我们能够了解算符优先算法的原理和实现方式,提升对编译原理的理解和应用能力。

二、实验内容1.完成对给定文法的定义和构造2.构造算符优先表3.实现算符优先分析程序三、实验原理算符优先算法是一种自底向上的语法分析方法,通过构造算符优先表来辅助分析过程。

算符优先表主要由终结符、非终结符和算符优先关系组成,其中算符优先关系用1表示优先关系,用2表示不优先关系,用0表示无关系。

算符优先分析程序的基本思路是:根据算符优先关系,依次将输入串的符号压栈,同时根据优先关系对栈内符号进行规约操作,最终判断输入串是否属于给定文法。

四、实验步骤1.定义和构造文法在本次实验中,我们假设给定文法如下:1)E->E+T,T2)T->T*F,F3)F->(E),i2.构造算符优先表根据给定文法,构造算符优先表如下:+*()i#+212112*222112(111012222122i222222#1112203.实现算符优先分析程序我们可以用C语言编写算符优先分析程序,以下是程序的基本框架:```c#include <stdio.h>//判断是否为终结符int isTerminal(char c)//判断条件//匹配符号int match(char stack, char input)//根据算符优先关系表进行匹配//算符优先分析程序void operatorPrecedence(char inputString[]) //定义栈char stack[MAX_SIZE];//初始化栈//将#和起始符号入栈//读入输入串//初始化索引指针//循环分析输入串while (index <= inputLength)//判断栈顶和输入符号的优先关系if (match(stack[top], inputString[index])) //栈顶符号规约} else//符号入栈}//计算新的栈顶}//判断是否成功分析if (stack[top] == '#' && inputString[index] == '#')printf("输入串符合给定文法!\n");} elseprintf("输入串不符合给定文法!\n");}```五、实验结果经过实验,我们成功实现了算符优先算法的语法分析。

算符优先文法的构造

算符优先文法的构造

算符优先⽂法的构造算符优先⽂法的构造算符优先⽂法属于⾃底向上的⽂法分析,需要不断的进⾏移进-规约操作,让⼀个输⼊的句⼦通过不断的移进-规约,最终变成⽂法的开始符号。

在移进-规约的过程中我们需要知道先对什么进⾏规约,得有个先后关系,故需要构造⽂法的算符优先表,来帮助规约分析时的规约对象。

构造FirstVT集和LastVT集FirstVT和LastVT分别代表某个⾮终结符所产⽣的句型中第⼀个和最后⼀个终结符的集合。

具体产⽣规则如下:Firstvt找Firstvt的三条规则:如果要找A的Firstvt,A的候选式中出现:A->a.......,即以终结符开头,该终结符⼊FirstvtA->B.......,即以⾮终结符开头,该⾮终结符的Firstvt⼊A的FirstvtA->Ba.....,即先以⾮终结符开头,紧跟终结符,则终结符⼊FirstvtLastvt找Lastvt的三条规则:如果要找A的Lastvt,A的候选式中出现:A->.......a,即以终结符结尾,该终结符⼊LastvtA->.......B,即以⾮终结符结尾,该⾮终结符的Lastvt⼊A的LastvtA->.....aB,即先以⾮终结符结尾,前⾯是终结符,则终结符⼊Firstvt构造算符优先表算符优先关系表即确定各个终结符的优先关系,以便之后寻找最左素短语。

算符优先表分以下⼏种情况:E->...aBc...和E->...ac...,在产⽣式中存在类似关系的终结符优先级相等,即a和c的优先级相等。

E->Ab,在产⽣式中存在⼀个⾮终结符在前⼀个终结符在后的情况,则A的LastVT集合中的终结符优先级都⾼于终结符b的优先级E->aB,在产⽣式中存在⼀个终结符在前和⼀个⾮终结符在后的情况,则B的FirstVT集合中的终结符优先级都⾼于终结符a的优先级其实⼤⽩话说起来就遵循⼀种就⾏:就是产⽣式中哪些终结符⼀起能规约成左部⾮终结符,则两者优先级相等,⽽终结符和⾮终结符在同⼀个产⽣式中,⾮终结符的终结符集合需要先规约成⾮终结符,所以那些⾮终结符的终结符的优先级要⾼于与⾮终结符在同⼀产⽣式中的终结符寻找待规约串寻找规约串即寻找最左素短语。

算符优先分析算法(c语言)

算符优先分析算法(c语言)

编译原理实验一实验目的设计、编制并调试一个算符优先分析算法,加深对此分析法的理解二实验过程先在算符栈置“$”,然后开始顺序扫描表达式,若读来的单词符号是操作数,这直接进操作数栈,然后继续读下一个单词符号。

分析过程从头开始,并重复进行;若读来的是运算符θ2则将当前处于运算符栈顶的运算符θ1的入栈优先数f与θ2的比较优先函数g进行比较。

2.2 各种单词符号对应的种别码2.3 算符优先程序的功能完成一个交互式面向对象的算符优先分析程序,而一个交互式面向对象的算符优先分析程序基本功能是:(1)输入文法规则(2)对文法进行转换(3)生成每个非终结符的FirstVT和LastVT(4)生成算符优先分析表(5)再输入文法符号(6)生成移进规约步骤三设计源码算符优先分析器#include "stdio.h"#include "stdlib.h"#include "iostream.h"char data[20][20]; //算符优先关系char s[100]; //模拟符号栈schar lable[20]; //文法终极符集char input[100]; //文法输入符号串char string[20][10]; //用于输入串的分析int k;char a;int j;char q;int r; //文法规则个数int r1;int m,n,N; //转化后文法规则个数char st[10][30]; //用来存储文法规则char first[10][10]; //文法非终结符FIRSTVT集char last[10][10]; //文法非终结符LASTVT集int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析int zhongjie(char c); //判断字符c是否是终极符int xiabiao(char c); //求字符c在算符优先关系表中的下标void out(int j,int k,char *s); //打印s栈void firstvt(char c); //求非终结符c的FIRSTVT集void lastvt(char c); //求非终结符c的LASTVT集void table(); //创建文法优先关系表void main(){int i,j,k=0;printf("请输入文法规则数:");scanf("%d",&r);printf("请输入文法规则:\n");for(i=0;i<r;i++){scanf("%s",st[i]); //存储文法规则,初始化FIRSTVT集和LASTVT集*/first[i][0]=0; /*first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数*/ last[i][0]=0;}for(i=0;i<r;i++) //判断文法是否合法{for(j=0;st[i][j]!='\0';j++){if(st[i][0]<'A'||st[i][0]>'Z'){printf("不是算符文法!\n");exit(-1);}if(st[i][j]>='A'&&st[i][j]<='Z'){if(st[i][j+1]>='A'&&st[i][j+1]<='Z'){printf("不是算符文法!\n");exit(-1);}}}}for(i=0;i<r;i++){for(j=0;st[i][j]!='\0';j++){if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='| ')lable[k++]=st[i][j];}}lable[k]='#';lable[k+1]='\0';table();printf("每个非终结符的FIRSTVT集为:\n"); //输出每个非终结符的FIRSTVT集for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<first[i][0];j++){printf("%c ",first[i][j+1]);}printf("\n");}printf("每个非终结符的LASTVT集为:\n"); //输出每个非终结符的LASTVT集for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<last[i][0];j++){printf("%c ",last[i][j+1]);}printf("\n");}printf("算符优先分析表如下:\n");for(i=0;lable[i]!='\0';i++)printf("\t%c",lable[i]);printf("\n");for(i=0;i<k+1;i++){printf("%c\t",lable[i]);for(j=0;j<k+1;j++){printf("%c\t",data[i][j]);}printf("\n");}printf("请输入文法输入符号串以#结束:");scanf("%s",input);deal();}void table(){char text[20][10];int i,j,k,t,l,x=0,y=0;int m,n;x=0;for(i=0;i<r;i++){firstvt(st[i][0]);lastvt(st[i][0]);}for(i=0;i<r;i++){text[x][y]=st[i][0];y++;for(j=1;st[i][j]!='\0';j++){if(st[i][j]=='|'){text[x][y]='\0';x++;y=0;text[x][y]=st[i][0];y++;text[x][y++]='-';text[x][y++]='>';}else{text[x][y]=st[i][j];y++;}}text[x][y]='\0';x++;y=0;}r1=x;printf("转化后的文法为:\n");for(i=0;i<x;i++) //输出转化后的文法规则串{printf("%s\n",text[i]);}for(i=0;i<x;i++) /*求每个终结符的推导结果(去掉"->"后的转化文法,用于最后的规约)*/ {string[i][0]=text[i][0];for(j=3,l=1;text[i][j]!='\0';j++,l++)string[i][l]=text[i][j];string[i][l]='\0';}for(i=0;i<x;i++){for(j=1;text[i][j+1]!='\0';j++){if(zhongjie(text[i][j])&&zhongjie(text[i][j+1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+1]);data[m][n]='=';}if(text[i][j+2]!='\0'&&zhongjie(text[i][j])&&zhongjie(text[i][j+2])&&!zhongjie(text[i][j+1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+2]);data[m][n]='=';}if(zhongjie(text[i][j])&&!zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j+1])break;}m=xiabiao(text[i][j]);for(t=0;t<first[k][0];t++){n=xiabiao(first[k][t+1]);data[m][n]='<';}}if(!zhongjie(text[i][j])&&zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j])break;}n=xiabiao(text[i][j+1]);for(t=0;t<last[k][0];t++){m=xiabiao(last[k][t+1]);data[m][n]='>';}}}}m=xiabiao('#');for(t=0;t<first[0][0];t++){n=xiabiao(first[0][t+1]);data[m][n]='<';}n=xiabiao('#');for(t=0;t<last[0][0];t++){m=xiabiao(last[0][t+1]);data[m][n]='>';}data[n][n]='=';}void firstvt(char c) //求FIRSTVT集{int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(fflag[i]==0){n=first[i][0]+1;m=0;do{if(m==2||st[i][m]=='|'){if(zhongjie(st[i][m+1])){first[i][n]=st[i][m+1];n++;}else{if(zhongjie(st[i][m+2])){first[i][n]=st[i][m+2];n++;}if(st[i][m+1]!=c){firstvt(st[i][m+1]);for(j=0;j<r;j++){if(st[j][0]==st[i][m+1])break;}for(k=0;k<first[j][0];k++)int t;for(t=0;t<n;t++){if(first[i][t]==first[j][k+1])break;}if(t==n){first[i][n]=first[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');first[i][n]='\0';first[i][0]=--n;fflag[i]=1;}}void lastvt(char c) //求LASTVT集{int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(lflag[i]==0){n=last[i][0]+1;m=0;do{if(st[i][m+1]=='\0'||st[i][m+1]=='|'){if(zhongjie(st[i][m])){last[i][n]=st[i][m];}else{if(zhongjie(st[i][m-1])){last[i][n]=st[i][m-1];n++;}if(st[i][m]!=c){lastvt(st[i][m]);for(j=0;j<r;j++){if(st[j][0]==st[i][m])break;}for(k=0;k<last[j][0];k++){int t;for(t=0;t<n;t++){if(last[i][t]==last[j][k+1])break;}if(t==n){last[i][n]=last[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');last[i][n]='\0';last[i][0]=--n;lflag[i]=1;}}int deal(){int i,j;int x,y;int z; //输入串的长度k=1;s[k]='#'; //栈置初值for(i=0;input[i]!='\0';i++); //计算输入串的长度z=i--;i=0;while((a=input[i])!='\0'){if(zhongjie(s[k]))j=k;elsej=k-1;x=xiabiao(s[j]);y=xiabiao(a);if(data[x][y]=='>'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("规约\n");do{q=s[j];if(zhongjie(s[j-1]))j=j-1;else j=j-2;x=xiabiao(s[j]);y=xiabiao(q);}while(data[x][y]!='<');int m,n,N;for(m=j+1;m<=k;m++){for(N=0;N<r1;N++)for(n=1;string[N][n]!='\0';n++){if(!zhongjie(s[m])&&!zhongjie(string[N][n])){if(zhongjie(s[m+1])&&zhongjie(string[N][n+1])&&s[m+1]==string[N][n+1]){s[j+1]=string[N][0];break;}}elseif(zhongjie(s[m]))if(s[m]==string[N][n]){s[j+1]=string[N][0];break;}}}k=j+1;if(k==2&&a=='#'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("结束\n");printf("输入串符合文法的定义!\n");return 1; //输入串符合文法的定义}}elseif(data[x][y]=='<'||data[x][y]=='='){ //移进out(1,k,s);printf("%c",a);out(i+1,z,input);printf("移进\n");k++;s[k]=a;i++;}else{printf("\nflase");return 0;}}printf("\nflase");return 0;}void out(int j,int k,char *s){int n=0;int i;for(i=j;i<=k;i++){printf("%c",s[i]);n++;}for(;n<15;n++){printf(" ");}}int xiabiao(char c) //求字符c在算符优先关系表中的下标{int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return i;}return -1;}int zhongjie(char c) //判断字符c是否是终极符{int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return 1;}return 0;}四实验结果。

第六章 算符优先分析文法

第六章 算符优先分析文法

E’→#E# E→E+T|T T→T*F|F F→P↑F|P P→(E)|i ( )
直接看产生式的右部, 直接看产生式的右部,若出现了 →…ab ab…或 →…a A → ab 或A → aBb,则a=b
25
求 < 关系
• 求出每个非终结符B的FIRSTVT(B) 求出每个非终结符 的 • 若A→…aB…,则∀b∈FIRSTVT(B),a<b , ∈ , E’→#E# FIRSTVT(E’) ={#} E→E+T|T FIRSTVT(E) ={+,*,↑, ( , i } T→T*F|F FIRSTVT(T) ={*,↑, ( , i } F→P↑F|P FIRSTVT(F) ={↑, ( , i } P→(E)|i ( ) FIRSTVT(P) ={ ( , i } E’→#E#且P→(E)则{#,(}<FIRSTVT(E) → E#且P→(E)则{#,( FIRSTVT(E) # < + , # <* ,#<↑ , #< (,# <I, (< +,( <*, (<↑ , (<( ,( <i
16
如果Ab或 如果 或(bA)出现在算符文法的句型γ中, )出现在算符文法的句型γ 其中A∈ , 其中 ∈VN, b ∈ VT,则γ中任何含 的短语必 , 中任何含b的短语必 含有A。 含有 。
* S => γ =abAβ
γ中含b的短语不含有 。 中含 的短语不含有A。 不含有
S a BB AB β b
当且仅当G中含有形如A 的产生式, a > b当且仅当G中含有形如A→…Bb…的产生式, B 的产生式 + 且B+ …a或B⇒…aC 。 ⇒ a a 所以不是算符优先文法。 所以不是算符优先文法。 21

编译原理 第六章 算符优先分析法

编译原理 第六章 算符优先分析法

编译原理第六章算符优先分析法第6章自底向上优先分析第六章算符优先分析法课前索引【课前思考】◇ 什么是自下而上语法分析的策略?◇ 什么是移进-归约分析?◇ 移进-归约过程和自顶向下最右推导有何关系?◇ 自下而上语法分析成功的标志是什么?◇ 什么是可归约串?◇ 移进-归约过程的关键问题是什么?◇ 如何确定可归约串?◇ 如何决定什么时候移进,什么时候归约?◇ 什么是算符文法?什么是算符优先文法?◇ 算符优先分析是如何识别可归约串的?◇ 算符优先分析法的优缺点和局限性有哪些?【学习目标】算符优先分析法是自下而上(自底向上)语法分析的一种,尤其适应于表达式的语法分析,由于它的算法简单直观易于理解,因此,也是学习其它自下而上语法分析的基础。

通过本章学习学员应掌握:◇ 对给定的文法能够判断该文法是否是算符文法◇ 对给定的算符文法能够判断该文法是否是算符优先文法◇ 对给定的算符文法能构造算符优先关系表,并能利用算符优先关系表判断该文法是否是算符优先文法。

◇ 能应用算符优先分析算法对给定的输入串进行移进-归约分析,在分析的每一步能确定当前应移进还是归约,并能判断所给的输入串是否是该文法的句子。

◇ 了解算符优先分析法的优缺点和实际应用中的局限性。

【学习指南】算符优先分析法是自下而上语法分析的一种,它的算法简单、直观、易于理解,所以通常作为学习其它自下而上语法分析的基础。

为学好本章内容,学员应复习有关语法分析的知识,如:什么是语言、文法、句子、句型、短语、简单短语、句柄、最右推导、规范归约基本概念。

【难重点】◇ 通过本章学习后,学员应该能知道算符文法的形式。

◇ 对一个给定的算符文法能构造算符优先关系分析表,并能判别所给文法是否为算符优先文法。

◇ 分清规范句型的句柄和最左素短语的区别,进而分清算符优先归约和规范归约的区别。

◇ 算符优先分析的可归约串是句型的最左素短语,在分析过程中如何寻找可归约串是算符优先分析的关键问题。

《编译原理》第6章 (1)

《编译原理》第6章 (1)

…a
a >b
24
由定义直接构造:
预备知识:
定义两个集合:
+ + FIRSTVT(B)={b|B b…或B Cb…},
+ + LASTVT(B)={b|B …b或B …bC}
即最后一个终结符 即第一个终结符
25
三种优先关系的计算为: a)≡关系 条件:A…ab... A…aBb… b) <关系 条件:A…aB… bFIRSTVT(B) 结论:a<b c) >关系 条件:A…Bb… aLASTVT(B) 结论:a>b
20
定义:设G是不含产生式的算符文法,若G中任何两个终 结符号之间至多有一种优先关系存在,则G是一个算符 优先文法OPG。 注:不允许有ab、 a≡b、 ab 中的两种同时存在 要完成运算符间优先级的比较,最简单的办法是先定义 各种可能相继出现的运算符的优先级,并将其表示成矩 阵形式,即得到一个算符优先关系表。在分析过程中通 过查询矩阵元素而获得算符间的优先关系。
了解算符优先分析法的优缺点和实际应用中的局限性
2
【学习指南】
算符优先分析法是自下而上语法分析的一种,它的算
法简单、直观、易于理解,故通常作为学习其它自下 而上语法分析的基础。在学习前,应复习有关语法分 析的知识,如:什么是语言、文法、句子、句型、短 语、简单短语、句柄、最右推导、规范归约基本概念
S
A
A→Ab
最右推导 句型
abbcde
句柄 归约用规则 b A→b
S→aAcBe
aAbcde
Ab
d
A→Ab
B→d
A
A→b
B
B→d
aAcde

算符优先分析法详解

算符优先分析法详解

四川大学计算机学院 金军
12
2
优先表构造算法
FOR 每一条产生式P→X1X2…Xn FOR i:=1 TO n-1 DO BEGIN IF Xi 和 Xi+1 均为终结符 THEN 置 Xi=Xi+1 IF I<=n-2且Xi和Xi+2都为终结符,而Xi+1 为非终结符, THEN置Xi=Xi+2 IF Xi为终结符而Xi+1为非终结符 THEN FOR FISTVT(Xi+1)中的每个a DO 置 Xi< a IF Xi为非终结符而Xi+1为终结符THEN FOR LASTVT(Xi)中的每个a DO 置 Xi >a END
四川大学计算机学院 金军
1
算符优先文法
现在按照算符优先分析法的设计思路,构 造一种文法,通过它可以自动产生终结符 的优先关系表。
算符优先文法
一个文法,如果它的任何产生式的右部都 不含两个相继(并列)的非终结符,即不 含如下形式的产生式右部:
…QR…
则我们称该文法为算符文法。 在后面的定义中,a、b代表任意终结符; P、Q、R代表任意非终结符;‘…’代表有 终结符和非终结符组成的任意序列,包括 空字。
LASTVT(U)的构造:
若有产生式U → …a或U → …aV,则 a∈LASTVT(U); 若a∈LASTVT(V),且有产生式U → …V,则 a∈LASTVT(U)。
四川大学计算机学院 金军 9 四川大学计算机学院 金军 10
FIRSTVT构造算法
建立一个二维布尔数组F[P, a],使得F[P, a]为真的条件适当且仅当a∈FIRSTVT(P); 再用一个栈STACK,把所有初值为真的数 组元素F[P, a]的符号对(P, a)全都放到栈 中,对栈施加如下操作:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按一定原则求出该文法所有符 号之间的优先关系,并按照这种 之间的优先关系, 优先关系 关系确定规约过程中的句柄,是 一种规范规约 规范规约。 一种规范规约。
?
5
特点:准确、规范,但分析效率底, 特点:准确、规范,但分析效率底, 实际使用价值不大。 实际使用符优先分析法
20
例:已知表达式文法G[E]: 已知表达式文法G[E]: G[E] E→E+E | E*E | (E) | i 证明G[E]不是OPG文法。 G[E]不是OPG文法 证明G[E]不是OPG文法。 证明如下: 证明如下: 因为: →E+ 因为:E→E+E , E ⇒E * E 则有 + < *
a < b当且仅当G中含有形如A→…aB…的产生式, 当且仅当G中含有形如A 的产生式, a 的产生式 且B+ b…或B⇒Cb…; ⇒ 或 + ; 又因为: 又因为:E→E*E, E⇒E+E 则有 + > *
9
算符优先分析法
直观的算符优先分析法 算符优先分析法 区别是什么? 区别是什么?
• 算符优先关系的产生
10
直观算符优先分析法 算符优先关系: 算符优先关系:
a < b a = b a > b 表示a优先级低于b 表示a优先级低于b 表示a优先级相同b 表示a优先级相同b 表示a优先级高于b 表示a优先级高于b
只规定算符( 之间的优先关系。 只规定算符(终结符)之间的优先关系。 算符 在归约过程中只要找到句柄就归约,不必 就归约, 考虑归约到哪个非终结符,因此不是规 范归约。 范归约。 特点:速度快, 特点:速度快,特别适合于表达式的分析
通过算符之间的优先关系来确定句柄
6
先看一个例题: 先看一个例题: 例. 已知文法G[E]: :
• 含b的短语不含有其他元素; 的短语不含有其他元素; • 含b的短语含有它前面的元素。 的短语含有它前面的元素。
的短语不一定含b。 含A的短语不一定含 。 的短语不一定含
17
算符优先关系的定义
• 设G是一个算符文法,a和b是任意两个终结符, 是一个算符文法, 是任意两个终结符, 是非终结符, 如下: A,B,C是非终结符,算符优先关系如下: (1)a= 当且仅当G中含有形如A→ ab…或 A→…ab (1)a=b当且仅当G中含有形如A→ ab 或 A→…aBb 的产生式; aBb…的产生式 A→ aBb 的产生式; a< 当且仅当G中含有形如A→ aB…的 A→…aB (2) a<b当且仅当G中含有形如A→ aB 的 产生式, 产生式,且B⇒b…或B⇒Cb ; 或 Cb…; + + a> 当且仅当G中含有形如A→ A→…B 的 (3) a>b当且仅当G中含有形如A→ Bb…的 产生式, 产生式,且B⇒…a或B⇒…aC 。 a aC
+ firstVT(B)={b firstVT(B)={b|B⇒b… 或 B⇒Cb…} } + lastVT(B)={a + a lastVT(B)={a|B⇒…a 或 B⇒…aC} a +
22
三种算符优先关系的计算: 三种算符优先关系的计算:
1) = 关系 直接看产生式的右部, 直接看产生式的右部,若出现了 →…ab ab…或 →…aBb aBb, A → ab 或A → aBb,则a=b 2) < 关系 求出每个非终结符B 求出每个非终结符B的FIRSTVT(B) A→…aB aB…, ∈FIRSTVT(B), 若A→ aB ,则∀b∈FIRSTVT(B),a<b 3) > 关系 求出每个非终结符B 求出每个非终结符B的LASTVT(B) A→…Bb Bb…, ∈LASTVT(B), 若A→ Bb ,则∀a∈LASTVT(B),a>b
23
已知文法如下, 例:已知文法如下,计算优先关系 E’→#E# →#E# E→E+T|T T→T*F|F F→P↑F|P P→( P→(E)|i 分析: 分析: 计算优先关系实际上是求 #,+,× #,+,×,↑,(,), i ,(,), 之间的优先关系
24
求 = 关系
∵ E’→#E# ∴ # = # →#E# ∵ P→(E) ∵ ( = ) 写入优先关系表 = 关系
16
如果Ab或 如果 或(bA)出现在算符文法的句型γ中, )出现在算符文法的句型γ 其中A∈ , 其中 ∈VN, b ∈ VT,则γ中任何含 的短语必 , 中任何含b的短语必 含有A。 含有 。
* S => γ =abAβ
γ中含b的短语不含有 。 中含 的短语不含有A。 不含有
S a BB AB β b
# > > > > > > > =
14
<
<
算符文法的定义
• 设有一文法G,如果G中没有形如 设有一文法G 如果G A→…BC BC… (…∈V*) A→ BC ∈ 的产生式,其中B 的产生式,其中B和C为非终结符,则称G为 为非终结符,则称G 算符文法(或称OG文法) OG文法 算符文法(或称OG文法)。 即任何一个产生式中都不包含两个非终结 相邻的情况,就是算符文法。 符相邻的情况,就是算符文法。
15
算符文法的性质
性质1 性质1:在算符文法中任何句型都不包含两 个相邻的非终结符。 个相邻的非终结符。 性质2:如果Ab或(bA)出现在算符文法的 性质2 如果Ab或 bA) Ab 句型γ 其中A 句型γ中,其中A∈VN, b ∈ VT,则γ中任 何含b 短语必含有 必含有A 何含b的短语必含有A。 (含b的短语必含A,含A的短语不一定含b) 的短语必含A 的短语不一定含b
13
简单算符优先关系表如下
+ * /

( ) i #
+ > > > > > < > > <
> > > > > < > > <
* < < > > > < > > <
/ < < > > > < > > <

< < < < < < > > <
( < < < < < <
) > > > > > = > >
i < < < < < <
3
回顾-简单优先分析法 回顾-
#
A c B
a b bcde
→ A →b A →Ab B →d S→aAcBe A →Ab A →b
S⇒aAcBe ⇒aAcde ⇒aAbcde ⇒abbcde ⇒
S→aAcBe → B →d
S c
a A b
A b
B
e
d
4
回顾-简单优先分析法 回顾-
简单优先分析算法的基本思想: 简单优先分析算法的基本思想:
+ +
18
(2) a<b当且仅当 中含有形如 当且仅当G中含有形如 当且仅当 中含有形如A→…aB…的产 的产 + 生式, 生式,且B⇒b…或B⇒Cb…; ⇒ 或 + ⇒
A … a B … b …
A … B b … … a
(3) a>b当且仅当 中含有形如 当且仅当G中含有形如 当且仅当 中含有形如A→…Bb…的产 的产 + 生式, 生式,且B⇒…a或B⇒…aC 。 ⇒ 或 + ⇒
E→E+E E→E*E E→ i 输入串i+i*i ,归约过程如下 输入串i+i*i
7
G[E]:E→E+E, E→ E*E, E→ i :
步骤 1) ) 2) ) 3) ) 4) ) 5) ) 6) ) 7) ) 8) ) 9) ) 10) ) 11) ) 符号栈 输入符号串 # i+i*i# #i +i*i# #E +i*i# #E+ i*i# #E+i *i# #E+E *i# #E+E* i# #E+E*i # #E+E*E # #E+E # #E #
E’→#E# E→E+T|T T→T*F|F F→P↑F|P P→(E)|i ( )
直接看产生式的右部, 直接看产生式的右部,若出现了 →…ab ab…或 →…a A → ab 或A → aBb,则a=b
25
求 < 关系
• 求出每个非终结符B的FIRSTVT(B) 求出每个非终结符 的 • 若A→…aB…,则∀b∈FIRSTVT(B),a<b , ∈ , E’→#E# FIRSTVT(E’) ={#} E→E+T|T FIRSTVT(E) ={+,*,↑, ( , i } T→T*F|F FIRSTVT(T) ={*,↑, ( , i } F→P↑F|P FIRSTVT(F) ={↑, ( , i } P→(E)|i ( ) FIRSTVT(P) ={ ( , i } E’→#E#且P→(E)则{#,(}<FIRSTVT(E) → E#且P→(E)则{#,( FIRSTVT(E) # < + , # <* ,#<↑ , #< (,# <I, (< +,( <*, (<↑ , (<( ,( <i
1
第六章 自底向上优先分析
郑先容
本章主要内容及学时安排
6.1 自底向上语法优先分析概述 6.2 简单优先分析法 6.3 算符优先分析法 6.3 算符优先分析法 理论讲授: 理论讲授:4学时 上机: 上机:2学时
2
本次课重点与难点
相关文档
最新文档