算符优先文法
概述
自底向上分析
在自底向上分析中,分析过程的每一步都是从当前句型中选择一个可规约的子串,将它规约到某个非终结符。
自底向上分析的关键问题是在分析过程中如何确定句柄或其他可规约串,也就是说如何知道何时在栈符号串中已形成某句型的句柄或其他可规约串。
优先关系
任何两个可能相继出现的终结符 a a a和 b b b可能有三种优先关系:
- a < b a < b a<b: a a a的优先级低于 b b b
- a = b a = b a=b: a a a的优先级等于 b b b
- a > b a > b a>b: a a a的优先级大于 b b b
算符文法
一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含
…
Q
R
…
\dots QR \dots
…QR…形式的产生式右部,则我们称该文法为算符文法。
约定:
- a , b a,b a,b代表任意终结符
- P , Q , R P,Q,R P,Q,R代表任意非终结符
- ' … \dots …'代表由终结符和非终结符组成的任意序列,包括空字
算符优先文法
假定 G G G是一个不含 ϵ \epsilon ϵ-产生式的算符文法,对于任何一对终结符 a , b a,b a,b,我们说:
- a = b a = b a=b,当且仅当文法 G G G中含有形如 P → … a b … P \rightarrow \dots ab \dots P→…ab…或 P → … a Q b … P \rightarrow \dots aQb \dots P→…aQb…的产生式;
- a < b a < b a<b,当且仅当 G G G中含有形如 P → … a R … P \rightarrow \dots aR \dots P→…aR…的产生式,而 R ⇒ b … R \Rightarrow b\dots R⇒b…或 R ⇒ Q b … R \Rightarrow Qb\dots R⇒Qb…;
-
a
>
b
a > b
a>b,当且仅当
G
G
G中含有形如
P
→
…
R
b
…
P \rightarrow \dots Rb \dots
P→…Rb…的产生式,而
R
⇒
…
a
R \Rightarrow \dots a
R⇒…a或
R
⇒
…
a
Q
R \Rightarrow \dots aQ
R⇒…aQ;
如果一个算符文法 G G G中的任何终结符对 ( a , b ) (a,b) (a,b)至多只满足 a = b 、 a < b 、 a > b a = b、a < b、a > b a=b、a<b、a>b这三个关系之一,则称 G G G是一个算符优先文法。
构造算符优先表的算法
确定算符优先关系
- 确定满足关系
=
=
=的所有终结符对
- a = b a = b a=b,当且仅当文法 G G G中含有形如 P → … a b … P \rightarrow \dots ab \dots P→…ab…或 P → … a Q b … P \rightarrow \dots aQb \dots P→…aQb…的产生式
- 通过检查 G G G的每个产生式的每个候选式,可找出所有满足 a = b a = b a=b的终结符对
- 确定满足关系$ < $的所有终结符对
- a < b a < b a<b,当且仅当 G G G中含有形如 P → … a R … P \rightarrow \dots aR \dots P→…aR…的产生式,而 R ⇒ b … R \Rightarrow b\dots R⇒b…或 R ⇒ Q b … R \Rightarrow Qb\dots R⇒Qb…
- 构造 F I R S T V T ( P ) = { a ∣ P ⇒ a … FIRSTVT(P) = \{a|P \Rightarrow a\dots FIRSTVT(P)={a∣P⇒a…或 R ⇒ Q a … , a ∈ V T 且 Q ∈ V N } R \Rightarrow Qa\dots,a \in V_T且Q \in V_N\} R⇒Qa…,a∈VT且Q∈VN}。
- 确定满足关系$ > $的所有终结符对
- a > b a > b a>b,当且仅当 G G G中含有形如 P → … R b … P \rightarrow \dots Rb \dots P→…Rb…的产生式,而 R ⇒ … a R \Rightarrow \dots a R⇒…a或 R ⇒ … a Q R \Rightarrow \dots aQ R⇒…aQ
- 构造 L A S T V T ( P ) = { a ∣ P ⇒ … a LASTVT(P) = \{a|P \Rightarrow \dots a LASTVT(P)={a∣P⇒…a或 R ⇒ … a Q , a ∈ V T 且 Q ∈ V N } R \Rightarrow \dots aQ,a \in V_T且Q \in V_N\} R⇒…aQ,a∈VT且Q∈VN}。
- 根据
F
I
R
S
T
V
T
FIRSTVT
FIRSTVT和
L
A
S
T
V
T
LASTVT
LASTVT集合,检查每个产生式的候选式,确定满足关系
<
<
<和
>
>
>的所有终结符对
- 假定有个产生式的一个候选形为 … a P … \dots aP \dots …aP…,那么,对任何 b ∈ F I R S T V T ( P ) b \in FIRSTVT(P) b∈FIRSTVT(P),有 a < b a < b a<b
- 假定有个产生式的一个候选形为 … P b … \dots Pb \dots …Pb…,那么,对任何 a ∈ L A S T V T ( P ) a \in LASTVT(P) a∈LASTVT(P),有 a > b a > b a>b
构造集合 F I R S T V T ( P ) FIRSTVT(P) FIRSTVT(P)的算法
反复使用下面两条规则构造集合FIRSTVT§
- 若有产生式 P → a … P \rightarrow a \dots P→a…或 P → Q a … P \rightarrow Qa \dots P→Qa…,则 a ∈ F I R S T V T ( P ) a \in FIRSTVT(P) a∈FIRSTVT(P)
- 若 a ∈ F I R S T V T ( Q ) a \in FIRSTVT(Q) a∈FIRSTVT(Q),且有产生式 P → Q … P \rightarrow Q \dots P→Q…,则 a ∈ F I R S T V T ( P ) a \in FIRSTVT(P) a∈FIRSTVT(P)
构造集合 L A S T V T ( P ) LASTVT(P) LASTVT(P)的算法
反复使用下面两条规则构造集合LASTVT§
- 若有产生式 P → … a P \rightarrow \dots a P→…a或 P → … a Q P \rightarrow \dots aQ P→…aQ,则 a ∈ L A S T V T ( P ) a \in LASTVT(P) a∈LASTVT(P)
- 若 a ∈ L A S T V T ( Q ) a \in LASTVT(Q) a∈LASTVT(Q),且有产生式 P → … Q P \rightarrow \dots Q P→…Q,则 a ∈ L A S T V T ( P ) a \in LASTVT(P) a∈LASTVT(P)
构造算符优先表实例
考虑下面的文法
G
(
E
)
G(E)
G(E):
(1)
E
→
E
+
T
∣
T
E \rightarrow E + T | T
E→E+T∣T
(2)
T
→
T
∗
F
∣
F
T \rightarrow T * F | F
T→T∗F∣F
(3)
F
→
P
↑
F
∣
P
F \rightarrow P \uparrow F | P
F→P↑F∣P
(4)
P
→
(
E
)
∣
i
P \rightarrow (E) | i
P→(E)∣i
先计算
F
I
R
S
T
V
T
FIRSTVT
FIRSTVT和
L
A
S
T
V
T
LASTVT
LASTVT:
-
F
I
R
S
T
V
T
FIRSTVT
FIRSTVT集:
F I R S T V T ( E ) = { + , ∗ , ↑ , ( , i } FIRSTVT(E) = \{+,*,\uparrow,(,i\} FIRSTVT(E)={+,∗,↑,(,i}
F I R S T V T ( T ) = { ∗ , ↑ , ( , i } FIRSTVT(T) = \{*,\uparrow,(,i\} FIRSTVT(T)={∗,↑,(,i}
F I R S T V T ( F ) = { ↑ , ( , i } FIRSTVT(F) = \{\uparrow,(,i\} FIRSTVT(F)={↑,(,i}
F I R S T V T ( P ) = { ( , i } FIRSTVT(P) = \{(,i\} FIRSTVT(P)={(,i} -
L
A
S
T
V
T
LASTVT
LASTVT集:
L A S T V T ( E ) = { + , ∗ , ↑ , ) , i } LASTVT(E) = \{+,*,\uparrow,),i\} LASTVT(E)={+,∗,↑,),i}
L A S T V T ( T ) = { ∗ , ↑ , ) , i } LASTVT(T) = \{*,\uparrow,),i\} LASTVT(T)={∗,↑,),i}
L A S T V T ( F ) = { ↑ , ) , i } LASTVT(F) = \{\uparrow,),i\} LASTVT(F)={↑,),i}
L A S T V T ( P ) = { ) , i } LASTVT(P) = \{),i\} LASTVT(P)={),i}
然后构造算符优先表:
+ + + | ∗ * ∗ | ↑ \uparrow ↑ | i i i | ( ( ( | ) ) ) | |
---|---|---|---|---|---|---|
+ + + | > | < | < | < | < | > |
∗ * ∗ | > | > | < | < | < | > |
↑ \uparrow ↑ | > | > | < | < | < | > |
i i i | > | > | > | > | ||
( ( ( | < | < | < | < | < | = |
) ) ) | > | > | > | > |
算符优先分析算法
最左素短语
- 一个文法 G G G的句型的素短语是指这样一个短语,它至少含有一个终结符,并且,除它自身之外不再含任何更小的素短语
- 最左素短语是指处于句型最左边的那个素短语
最左素短语定理
- 算符优先文法句型(括在两个#之间)的一般形式:
# N 1 a 1 N 2 a 2 … N n a n N n + 1 \#N_1a_1N_2a_2\dots N_na_nN_{n+1} #N1a1N2a2…NnanNn+1
其中, a i a_i ai都是终结符, N i N_i Ni是可有可无的非终结符 - 定理:一个算符优先文法
G
G
G的任何举行的最左素短语是满足如下条件的最左子串
N
j
a
j
…
N
i
a
i
N
i
+
1
N_ja_j\dots N_ia_iN_{i+1}
Njaj…NiaiNi+1
- a j − 1 < a j a_{j-1} < a_j aj−1<aj
- a j = a j + 1 , … , a i + 1 = a i a_j = a_{j+1},\dots ,a_{i + 1} = a_i aj=aj+1,…,ai+1=ai
- a > a i + 1 a > a_{i + 1} a>ai+1
流程
- 使用一个符号栈 S S S,用它寄存终结符和非终结符, k k k代表符号栈 S S S的使用深度
- 在正确的情况下,算法工作完毕时,符号栈 S S S应呈现: # N # \# N \# #N#
评价
- 算符优先分析结果产生的分析树,不一定是语法树
- 优点:简单、快速
- 缺点:可能错误接受非法句子