📄 5.8.2_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.8.2_2.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='5.8.2_3.htm'"></img></td>
</tr>
</table>
<br><br>
<table><tr><td>    </td>
<td class="content">
<P>
<b>语句的类型检查 </b>
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
语句没有值,指派给它们的类型是基本类型void。如果在语句中发现类型错误,指派给语句的类型是type_error。因为表达式嵌在语句中,因此,对表达式进行类型检查总是需要的。
</p>
</td></tr></table>
<table><tr><td></td>
<td class="content">
<P>
S→id:=E {S.type:=IF id.type=E.type
<br>
THEN
void <br>
ELSE
type_error} <br>
S→IF E THEN S<span class="down">1</span>
{S.type:=IF E.type=boolean <br>
THEN
S<span class="down">1</span>.type <br>
ELSE
type_error} <br>
S→WHILE E DO S<span class="down">1</span>
{S.type:=IF E.type=boolean <br>
THEN
S<span class="down">1</span>.type <br>
ELSE
type_error} <br>
S→S<span class="down">1</span>;S<span class="down">2</span>
{S.type:=IF (S<span class="down">1</span>.type=void)AND(S<span class="down">2</span>.type=void)
<br>
THEN
void <br>
ELSE
type_error} <p>
<b>图5.34</b> 检查语句类型的翻译模式
<p>
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
检查语句的翻译模式有图5.34给出。对赋值语句要检查表达式的类型和左部变量是否等价,实际上,是检查它们是否赋值相容。对IF语句和WHILE语句仅检查它们的表达式是否为boolean类型。错误由复合语句传播,因为只有当每个子语句都有类型void时,语句序列的类型才是void。在这些语义动作中,类型不匹配会产生类型type_error。当然,友好的类型检查器还应该报告类型不匹配的性质和位置。
</p>
</td></tr></table>
<br>
<hr size=2 color=red width=90%>
<br>
<table><tr><td>    </td>
<td class="content">
<P>
<b>函数引用的类型检查 </b>
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
引用一个函数,要么是标准函数,要么是在说明部分说明的函数。因此,对说明部分的分析,应该能知道被引用函数的类型。为此,在图5.32中的翻译模式中加入下面的产生式和语义动作:
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
T→T<sub>1</sub>'→'T<sub>2</sub> {T.type:=T<sub>1</sub>.type→T<sub>2</sub>.type}
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
用作函数构造符的箭头两边加单引号是为了把它和用作产生式元符号的箭头加以区别。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
函数引用可看成一个表达式作用与另一个表达式,它的类型检查是:
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
E→E<sub>1</sub>(E<sub>2</sub>)
{E.type:=IF(E<sub>2</sub>.type=s)AND(E<sub>1</sub>.type=s→t)
<br>
THEN
t <br>
ELSE
type_error}
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
这表明,当E<sub>1</sub>是把类型s映射到类型t的函数时,如果实元E<sub>2</sub>的类型为s,则结果类型为t。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
上面的讨论是针对单个参数的情况,不难把它推广到多个参数的情况。事实上,类型为T<sub>1</sub>、T<sub>2</sub>、…、T<sub>n</sub>的n个变元可以看成类型为T<sub>1</sub>*T<sub>2</sub>*…*T<sub>n</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.8.2_2.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='5.8.2_3.htm'"></img></td>
</tr>
</table>
</BODY>
<html><script language="JavaScript">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -