语法与语义分析
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
符合文法
12
二、自顶向下分析(续二 )
自顶向下分析的难点: 如果规则中含有一条或者多条类似(1)的 规则,则在推导过程中很难确定到底选用 那一条规则,如果采用遍历全部规则的方 法则最明显的缺点就是效率低。
E::=T1| T2 | T3 | T4 | …...| Tn (1)
13
二、自顶向下分析(续二 )
难点解决: 候选式: 如有规则A::=T1| T2 | T3 | T4 | …...| Tn ,
则Ti称为A的后选式。 思路:通过当前的输入字符a来决定对后选式的选择。 方法: 1、首先对文法的每个规则A=:: 求可选集。
First(), 当不为空
Select(A=:: )=
Follow(A), 当为空
6
一、常用的终结符号集(续四)
P: E::=E+T|T T::=T*F|F F::=i|(E) 则因: E E; * E E+T; * E (E)* Follow(E)={#,+,)};
7
一、常用的终结符号集(续五)
P: E::=E+T|T T::=T*F|F F::=i|(E) 则因: * E F; * E T*F +T; * E F*F; * E (F) Follow(E)={#,+,*,)};
21
四、虚拟机(续一)
Java虚拟机 Java Source
Java Compiler Java Byte Code Java Virtual Machine Operating System Hardware
22
五、递归子程序方法
简单子程序(参见P119图3)
子ຫໍສະໝຸດ Baidu序
嵌套子程序(参见P119图4)
16
A::=aT1| aT2 | T3 | T4 | …...| Tn且
二、自顶向下分析(续五)
例:文法:G=({a,b,x},{Z,V},Z,P) P: Z::=aV|bZ (1) V::=baZ|x (2) 待分析符号串:bbabaax. 自顶向下分析: Z bZ bbZ bbaV bbabaZ bbabaaV bbabaax
3
一、常用的终结符号集(续一)
1、首符号集
定义:设有文法G=(VT,VN,S,P),字汇表为V,则符号串 的首符号集定义为 First()* ={| y, VT , y V*} 特别,若为空串,则有 First( )= 例如:文法:G=({i,+,*,(,)},{T,E,F},E,P)
17
推导与归约&自顶向下与自底向上
直接推导、直接归约、推导、归约
直接推导:设有文法G=(VT,VN,S,P),, (VT VN)*, 如果有A——〉P,则称A直接推导出,即: A 其中‘’表示直接推导。 可以称A直接推导出,或者 是A的直接推导。 与推导方向相反,称直接归约到A记作: A
(四) 语法与语义分析
•常用的终结符号集 •自顶向下分析 •自底向上分析 •虚拟机 •递归子程序方法 •逆波兰表达式
语法与语义分析
1.编译程序逻辑图
表 格 管 理
源 程 序
词 法 分 析
语 法 分 析
中 间 代 码 生 成
处
中 间 代 码 优 化
目 标 代 码 生 成
理
目 标 程 序
错
误
2
一、常用的终结符号集
8
一、常用的终结符号集(续六)
3、可选集
定义:设有文法G=(VT,VN,S,P),规则P中 A=::a,则该规则的可选集定义为:
First(a), 当a不为空 Select(A=::a)= Follow(A), 当a为空
9
一、常用的终结符号集(续七)
例如:文法:G=(a,b,c,d, },{S,B},S,P)其中 P: S=::aBc|bB B=::bB|d|
直接递归 递归子程序(参见P119图5.6) 间接递归
23
五、递归子程序方法(续一)
例:计算f(n)=n!的函数 function rfact(n:integer):integer; begin if n>1 then rfact:=n*rfact(n-1) else rfact:=1 end;
24
0 *
+ 如果记 a1 a1 ,则 * a1 an 表示自a1出发经过 0步或 若 干步可推导出an, a1 an 意味着a1 = an 或者a1 an
19
推导与归约&自顶向下与自底向上
文 推 归 法 导 约 句子分析 自顶向下 自底向上
20
四、虚拟机
虚拟机:虚拟机不是一台实际的机器,而是为 了便于讨论的一台假设和抽象的计算机。
五、递归子程序方法(续二)
递归子程序出口和入口工作: 一)递归入口工作 二)递归出口工作
25
六、逆波兰表达式
中缀表达式
简单表达式的表示法
前缀表达式(波兰表示法)
后缀表达式(逆波兰表示法)
26
六、逆波兰表达式(续一)
中缀法 前缀法 a+b +ab a+b*c +a*bc (a+b)*c *+abc a<b <ab 后缀法 ab+ abc*+ ab+c* ab<
14
二、自顶向下分析(续三 )
2、 当不等于,则对当前输入的符号a,若有 a First() 则可以选用规则A=:: 进行推导,即采用后选式。 3、如果非终结符有n个后选式,即A::=T1| T2 | T3 | T4 | …...| Tn ,则要分(I)(II)两种情况: (I)首符号不相同 对于文法中有规则A::=T1| T2 | T3 | T4 | …...| Tn ,若n个后选 式的首符号均不相同即First(Ti) First(Tj)= (ij) 对于待分析的符号串,如果其第一个符号(即当前的输入 符号)为a,且有a First(Tk),则选择规则A::= Tk进行推导, 即选择后选式Tk。 15
自顶向下分析的思路:
对于文法 G=(VT,VN,S,P),待分析的句子 (符号串)a,分析思路就是从 S出发,试图推导出符 号串 a. 从推导角度看,分析思路即为从文法的开始符开 始根据规则试图建立一个推导序列,若得到所给 的字符串则字符串得到识别,其结构符合文法, 否则不符合文法。(参见第二章)
11
4
一、常用的终结符号集(续二)
P: E::=E+T|T T::=T*F|F F::=i|(E) 则 First(E)={i,(}; First(T*F)={I,(}; First((i))={(}; First(i+i)={i};
5
一、常用的终结符号集(续三)
2、向前看集
定义:设有文法G=(VT,VN,S,P),非终结符号U的向 前看集定义为 Follow(U)={a|S * …Ua…,a VTU{#}} #:非终结符号U后面的符号串为空,则将U后的符号记作特殊 符号#; Follow(U)={所有含有U的句型中紧跟U之后的终结符}U{#} 例如:文法:G=({i,+,*,(,)},{T,E,F},E,P)
18
推导与归约&自顶向下与自底向上
推导: 如果a1可直接推导出 a2, a2可直接推导出a3,…… an1可直接推导出an,即存在一个自a1到an的直接推导序 列 + a1 a2 a3 … an-1 an(n>0) 则称a1可推导出an,记作a1 an表示从a1出发经过一步 或若干步,可推导出an,这个推导长度为n-1;
栈 * *( *( * (+ * (+ *( *(*(*( * + + +/ +/ + -
1.2运算符栈:存放暂时不能处理的运算符。 2、具体步骤(参P131) 3、框图(参见下页)
31
开始 输入运算符的优先关系
由左至右扫描中缀表达式 运算分量 N 运算符 N Y 退栈 Y error Y Y 左括号( N 右括号) N Y Y 输 出 栈为空 N 当前运算符优 先级大于栈顶 运算符优先级 N 退栈输出 Y 入 栈 Y 入 栈
a
运算分量
+
运算符
b
运算分量
27
六、逆波兰表达式(续一)
中缀、前缀、后缀表示法功能等价 共同点: 1、运算符的个数不变; 2、运算分量的次序不变; 后缀表示法的好处: a:无括号,形式简洁; b:运算符的顺序与运算的次序完全相同。
28
六、逆波兰表达式(续二)
逆波兰表达式—中缀表达式
ab+c* abc+* ab * c + — — — (a+b)*c a*(b+c) a*b+c a*(b+c-d)+e/f-g
文法 定义:文法G是一个四元组,G=(VT,VN,S,P),其中 VT为终结符号集,这是个非空有限集。 VN为非终结符号集合,它也是非空有限集。 S为一文法开始符,是一个特殊的非终结符。S VN P是产生式的非空有限集,其中每个产生式(或称规则) 是一序偶(U,x)通常写作U——〉x或U::=x; ——〉( 或::= )意为“由……组成”或“产生”; 字汇表: V=(VT VN) VT VN=
入栈
栈顶为( N 栈为空 N 退栈输出
退栈输出 N 栈顶为( Y
栈为空 Y 结束
N
error
32
六、逆波兰表达式
当前的符号 输入区 ( (a+b*c)*d a a+b*c)*d + +b*c)*d b b*c)*d * *c)*d c c)*d )*d ) )*d *d * *d d d 栈 ( ( (+ (+ (+* (+* (+ ( * *
二、自顶向下分析(续四 )
(II)首符号相同 对于文法中有规则A::=T1| T2 | T3 | T4 | …...| Tn ,若 First(Ti) First(Tj) (ij) a:试探法——>回溯现象 b:左提左因子法修改文法,将问题转化到(I)
左提左因子:
文法中有规则
First(Ti) First(Tj) = (i,j3,ij), First(Ti) a, (I=3,4,5…) 改写文法规则为: A::= aV | T3 | T4 | …...| Tn V::=T1|T2
实例1:
输出区 a a ab ab abc abc* abc*+ abc*+ abc*+ abc*+d abc*+*
33
实
当前符号 a * ( b + c d
例
) + e / f g
2
输入区 a*(b+c-d)+e/f-g *(b+c-d)+e/f-g (b+c-d)+e/f-g b+c-d)+e/f-g +c-d)+e/f-g c-d)+e/f-g -d)+e/f-g -d)+e/f-g d)+e/f-g )+e/f-g )+e/f-g +e/f-g e/f-g /f-g f-g -g -g -g g
Priority()>Priority()>Priority(*、/) >Priority(+、-)
:表示单目减(负号) (的优先数小于其右边运算符的优先数; (的优先数大于其左边运算符的优先数; )的优先数最低,其不进运算栈,也不进输出区。
30
六、逆波兰表达式(续四)
中缀表达式—逆波兰表达式
二、自顶向下分析(续一)
例:文法:G=({i,+,-,/,*,(,)},{T,E,F},E,P) P: E::=T|E+T|E-T (1) T::=F|T*F|T/F (2) F::=i|(E) (3) 分析句子(i+i)-i是否符合文法: E E-T E-F E-i T-i F-i (E)-i (E+T)-i (E+F)-i (E+i)-i (T+i)-i (F+i)-i (i+i)-i
Select(S=::aBc)=First(aBc)={a} Select(S=::bB)=First(bB)={b} Select(B=::bB)=First(bB)={b} Select(B=::d)=First(d)={d} Select(B=:: )=Follow(B)={c,#,}
10
二、自顶向下分析
abc+d-*ef/+g- —
1.运算符出现的先后顺序即代表计算的先后顺序。 2.每次遇到运算符,取左端紧邻的两个(一个)运算分 量作为该运算符号的两个(一个)运算分量
29
六、逆波兰表达式(续三)
中缀表达式—逆波兰表达式
1、定义运算符号的优先级 用自然数来表示运算符的优先级。故也称优先数 1.1常用运算符的优先数关系:
12
二、自顶向下分析(续二 )
自顶向下分析的难点: 如果规则中含有一条或者多条类似(1)的 规则,则在推导过程中很难确定到底选用 那一条规则,如果采用遍历全部规则的方 法则最明显的缺点就是效率低。
E::=T1| T2 | T3 | T4 | …...| Tn (1)
13
二、自顶向下分析(续二 )
难点解决: 候选式: 如有规则A::=T1| T2 | T3 | T4 | …...| Tn ,
则Ti称为A的后选式。 思路:通过当前的输入字符a来决定对后选式的选择。 方法: 1、首先对文法的每个规则A=:: 求可选集。
First(), 当不为空
Select(A=:: )=
Follow(A), 当为空
6
一、常用的终结符号集(续四)
P: E::=E+T|T T::=T*F|F F::=i|(E) 则因: E E; * E E+T; * E (E)* Follow(E)={#,+,)};
7
一、常用的终结符号集(续五)
P: E::=E+T|T T::=T*F|F F::=i|(E) 则因: * E F; * E T*F +T; * E F*F; * E (F) Follow(E)={#,+,*,)};
21
四、虚拟机(续一)
Java虚拟机 Java Source
Java Compiler Java Byte Code Java Virtual Machine Operating System Hardware
22
五、递归子程序方法
简单子程序(参见P119图3)
子ຫໍສະໝຸດ Baidu序
嵌套子程序(参见P119图4)
16
A::=aT1| aT2 | T3 | T4 | …...| Tn且
二、自顶向下分析(续五)
例:文法:G=({a,b,x},{Z,V},Z,P) P: Z::=aV|bZ (1) V::=baZ|x (2) 待分析符号串:bbabaax. 自顶向下分析: Z bZ bbZ bbaV bbabaZ bbabaaV bbabaax
3
一、常用的终结符号集(续一)
1、首符号集
定义:设有文法G=(VT,VN,S,P),字汇表为V,则符号串 的首符号集定义为 First()* ={| y, VT , y V*} 特别,若为空串,则有 First( )= 例如:文法:G=({i,+,*,(,)},{T,E,F},E,P)
17
推导与归约&自顶向下与自底向上
直接推导、直接归约、推导、归约
直接推导:设有文法G=(VT,VN,S,P),, (VT VN)*, 如果有A——〉P,则称A直接推导出,即: A 其中‘’表示直接推导。 可以称A直接推导出,或者 是A的直接推导。 与推导方向相反,称直接归约到A记作: A
(四) 语法与语义分析
•常用的终结符号集 •自顶向下分析 •自底向上分析 •虚拟机 •递归子程序方法 •逆波兰表达式
语法与语义分析
1.编译程序逻辑图
表 格 管 理
源 程 序
词 法 分 析
语 法 分 析
中 间 代 码 生 成
处
中 间 代 码 优 化
目 标 代 码 生 成
理
目 标 程 序
错
误
2
一、常用的终结符号集
8
一、常用的终结符号集(续六)
3、可选集
定义:设有文法G=(VT,VN,S,P),规则P中 A=::a,则该规则的可选集定义为:
First(a), 当a不为空 Select(A=::a)= Follow(A), 当a为空
9
一、常用的终结符号集(续七)
例如:文法:G=(a,b,c,d, },{S,B},S,P)其中 P: S=::aBc|bB B=::bB|d|
直接递归 递归子程序(参见P119图5.6) 间接递归
23
五、递归子程序方法(续一)
例:计算f(n)=n!的函数 function rfact(n:integer):integer; begin if n>1 then rfact:=n*rfact(n-1) else rfact:=1 end;
24
0 *
+ 如果记 a1 a1 ,则 * a1 an 表示自a1出发经过 0步或 若 干步可推导出an, a1 an 意味着a1 = an 或者a1 an
19
推导与归约&自顶向下与自底向上
文 推 归 法 导 约 句子分析 自顶向下 自底向上
20
四、虚拟机
虚拟机:虚拟机不是一台实际的机器,而是为 了便于讨论的一台假设和抽象的计算机。
五、递归子程序方法(续二)
递归子程序出口和入口工作: 一)递归入口工作 二)递归出口工作
25
六、逆波兰表达式
中缀表达式
简单表达式的表示法
前缀表达式(波兰表示法)
后缀表达式(逆波兰表示法)
26
六、逆波兰表达式(续一)
中缀法 前缀法 a+b +ab a+b*c +a*bc (a+b)*c *+abc a<b <ab 后缀法 ab+ abc*+ ab+c* ab<
14
二、自顶向下分析(续三 )
2、 当不等于,则对当前输入的符号a,若有 a First() 则可以选用规则A=:: 进行推导,即采用后选式。 3、如果非终结符有n个后选式,即A::=T1| T2 | T3 | T4 | …...| Tn ,则要分(I)(II)两种情况: (I)首符号不相同 对于文法中有规则A::=T1| T2 | T3 | T4 | …...| Tn ,若n个后选 式的首符号均不相同即First(Ti) First(Tj)= (ij) 对于待分析的符号串,如果其第一个符号(即当前的输入 符号)为a,且有a First(Tk),则选择规则A::= Tk进行推导, 即选择后选式Tk。 15
自顶向下分析的思路:
对于文法 G=(VT,VN,S,P),待分析的句子 (符号串)a,分析思路就是从 S出发,试图推导出符 号串 a. 从推导角度看,分析思路即为从文法的开始符开 始根据规则试图建立一个推导序列,若得到所给 的字符串则字符串得到识别,其结构符合文法, 否则不符合文法。(参见第二章)
11
4
一、常用的终结符号集(续二)
P: E::=E+T|T T::=T*F|F F::=i|(E) 则 First(E)={i,(}; First(T*F)={I,(}; First((i))={(}; First(i+i)={i};
5
一、常用的终结符号集(续三)
2、向前看集
定义:设有文法G=(VT,VN,S,P),非终结符号U的向 前看集定义为 Follow(U)={a|S * …Ua…,a VTU{#}} #:非终结符号U后面的符号串为空,则将U后的符号记作特殊 符号#; Follow(U)={所有含有U的句型中紧跟U之后的终结符}U{#} 例如:文法:G=({i,+,*,(,)},{T,E,F},E,P)
18
推导与归约&自顶向下与自底向上
推导: 如果a1可直接推导出 a2, a2可直接推导出a3,…… an1可直接推导出an,即存在一个自a1到an的直接推导序 列 + a1 a2 a3 … an-1 an(n>0) 则称a1可推导出an,记作a1 an表示从a1出发经过一步 或若干步,可推导出an,这个推导长度为n-1;
栈 * *( *( * (+ * (+ *( *(*(*( * + + +/ +/ + -
1.2运算符栈:存放暂时不能处理的运算符。 2、具体步骤(参P131) 3、框图(参见下页)
31
开始 输入运算符的优先关系
由左至右扫描中缀表达式 运算分量 N 运算符 N Y 退栈 Y error Y Y 左括号( N 右括号) N Y Y 输 出 栈为空 N 当前运算符优 先级大于栈顶 运算符优先级 N 退栈输出 Y 入 栈 Y 入 栈
a
运算分量
+
运算符
b
运算分量
27
六、逆波兰表达式(续一)
中缀、前缀、后缀表示法功能等价 共同点: 1、运算符的个数不变; 2、运算分量的次序不变; 后缀表示法的好处: a:无括号,形式简洁; b:运算符的顺序与运算的次序完全相同。
28
六、逆波兰表达式(续二)
逆波兰表达式—中缀表达式
ab+c* abc+* ab * c + — — — (a+b)*c a*(b+c) a*b+c a*(b+c-d)+e/f-g
文法 定义:文法G是一个四元组,G=(VT,VN,S,P),其中 VT为终结符号集,这是个非空有限集。 VN为非终结符号集合,它也是非空有限集。 S为一文法开始符,是一个特殊的非终结符。S VN P是产生式的非空有限集,其中每个产生式(或称规则) 是一序偶(U,x)通常写作U——〉x或U::=x; ——〉( 或::= )意为“由……组成”或“产生”; 字汇表: V=(VT VN) VT VN=
入栈
栈顶为( N 栈为空 N 退栈输出
退栈输出 N 栈顶为( Y
栈为空 Y 结束
N
error
32
六、逆波兰表达式
当前的符号 输入区 ( (a+b*c)*d a a+b*c)*d + +b*c)*d b b*c)*d * *c)*d c c)*d )*d ) )*d *d * *d d d 栈 ( ( (+ (+ (+* (+* (+ ( * *
二、自顶向下分析(续四 )
(II)首符号相同 对于文法中有规则A::=T1| T2 | T3 | T4 | …...| Tn ,若 First(Ti) First(Tj) (ij) a:试探法——>回溯现象 b:左提左因子法修改文法,将问题转化到(I)
左提左因子:
文法中有规则
First(Ti) First(Tj) = (i,j3,ij), First(Ti) a, (I=3,4,5…) 改写文法规则为: A::= aV | T3 | T4 | …...| Tn V::=T1|T2
实例1:
输出区 a a ab ab abc abc* abc*+ abc*+ abc*+ abc*+d abc*+*
33
实
当前符号 a * ( b + c d
例
) + e / f g
2
输入区 a*(b+c-d)+e/f-g *(b+c-d)+e/f-g (b+c-d)+e/f-g b+c-d)+e/f-g +c-d)+e/f-g c-d)+e/f-g -d)+e/f-g -d)+e/f-g d)+e/f-g )+e/f-g )+e/f-g +e/f-g e/f-g /f-g f-g -g -g -g g
Priority()>Priority()>Priority(*、/) >Priority(+、-)
:表示单目减(负号) (的优先数小于其右边运算符的优先数; (的优先数大于其左边运算符的优先数; )的优先数最低,其不进运算栈,也不进输出区。
30
六、逆波兰表达式(续四)
中缀表达式—逆波兰表达式
二、自顶向下分析(续一)
例:文法:G=({i,+,-,/,*,(,)},{T,E,F},E,P) P: E::=T|E+T|E-T (1) T::=F|T*F|T/F (2) F::=i|(E) (3) 分析句子(i+i)-i是否符合文法: E E-T E-F E-i T-i F-i (E)-i (E+T)-i (E+F)-i (E+i)-i (T+i)-i (F+i)-i (i+i)-i
Select(S=::aBc)=First(aBc)={a} Select(S=::bB)=First(bB)={b} Select(B=::bB)=First(bB)={b} Select(B=::d)=First(d)={d} Select(B=:: )=Follow(B)={c,#,}
10
二、自顶向下分析
abc+d-*ef/+g- —
1.运算符出现的先后顺序即代表计算的先后顺序。 2.每次遇到运算符,取左端紧邻的两个(一个)运算分 量作为该运算符号的两个(一个)运算分量
29
六、逆波兰表达式(续三)
中缀表达式—逆波兰表达式
1、定义运算符号的优先级 用自然数来表示运算符的优先级。故也称优先数 1.1常用运算符的优先数关系: