📄 5.6.3_2b.htm
字号:
<html>
<head>
<title>编译原理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link type="text/css" rel="stylesheet" href="../css/specification.css">
</head>
<body>
<table align=right width=300>
<tr>
<td><img src="../images/previous.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='5.6.3_2.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='5.7.0.htm'"></img></td>
</tr>
</table>
<br><br>
<table><tr><td>    </td>
<td class="content">
<P>
在自底向上分析过程中间,正如预期的一样,各个属性可以被计算出来,让我们考虑以下两种情况。第一种情况,如果当前进行的归约是把ε归约为一个标记非终结符号M<sub>j</sub>,我们知道这个标记非终绪符号是属于哪个形式为A→M<sub>1</sub>X<sub>1</sub>…M<sub>n</sub>X<sub>n</sub>的产生式的。因此,我们也能知道为计算继承属性X<sub>j</sub>.i所需的那些属性的位置。此时,X<sub>j-1</sub>的属性X<sub>j-1</sub>.i和X<sub>j-1</sub>.s分别处在val[top-1]和val[top]的位置。于是,X<sub>1</sub>.i在val[top-2(j-1)+1]处,X<sub>1</sub>.s在val[top-2(j-1)+2] 处,X<sub>2</sub>.i在val[top-2(j-2)+1]处,X<sub>2</sub>.s在val[top-2(j-2)+2] 处等等。由于产生式左部的A.i紧挨着X<sub>1</sub>的属性来存放,不难知道,A.i在val[top-2(j-1)] 处。这样我们可以计算出X<sub>j</sub>.i并把它存放在val[top+1]处,它作为归约(ε归约为M<sub>j</sub>) 后的新栈顶。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
第二种情况是当我们把有关符号串归约为一个非标记符号,譬如用产生式A→M<sub>1</sub>X<sub>1</sub>…M<sub>n</sub>X<sub>n</sub>。那么,我们仅需要计算综合属性A.s; 因A.i早已计算出来,并且正好存放在栈中我们将要嵌入A本身的位置的下面的位置。很明显,当归约时,对于计算A.s所需要的那些属性均已存放在已知的位置,即各有关X<sub>j</sub>的位置上。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
由于标记非终结符号在某些情况下可能导致分析冲突,我们可以使用如下的简化。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
1.如果X<sub>j</sub>没有继承属性,我们就不需使用M<sub>j</sub>。当然,如果M<sub>j</sub>被省略,栈中属性的位置会发生变化,但这种变化很容易加入到分析程序中。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
2.如果X<sub>1</sub>.i存在,但它是由复写规则X<sub>1</sub>.i:=A.i计算的,那么,我们可以省略M<sub>1</sub>,因为我们已经知道A.i已经存放在栈中预定的位置,紧挨X<sub>1</sub>下面,并且这个值也可以为计算X<sub>1</sub>.i所用。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
一个重要的事实是,当我们进行分析时,如果继承属性A.i存在的话,它将在数组val中紧挨M1位置下面的位置(地址码较小者)中存放的。由于我们假设开始符号没有继承属性,那么在开始符号为A时,不会发生什么问题。但即使有这样的继承属性,我们也可以把它放在栈底的下面。注意,继承属性与标记非终结符号M<sub>j</sub>相联系,属性X<sub>j</sub>.i总是在M<sub>j</sub>处计算,而且发生在我们开始做归约到X<sub>j</sub>的动作以前。
</p>
</td></tr></table>
<br>
<table align=right width=300>
<tr>
<td><img src="../images/previous.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='5.6.3_2.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='5.7.0.htm'"></img></td>
</tr>
</table>
</BODY>
<html><script language="JavaScript">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -