if
语句是用来判定所给定的条件是否满足,根据判定的结果决定执行给出来的两种操作之一。
if
语句有下面三种形式:
1.
if
(表达式)语句
2.
if
(表达式)语句
1 else
语句
2
3.
if
(表达式
1
)语句
1
else if
(表达式
2
)语句
2
else if
(表达式
3
)语句
3
else
语句
4
那么
LCC
又是怎么样处理
if
语句的呢?
LCC
在函数
statement
调用
ifstmt
来处理的。下面就来查看
ifstmt
函数的源程序。
#001 static void ifstmt(int lab, int loop, Swtch swp, int lev)
#002 {
#003 t = gettok();
#004 expect('(');
#005 definept(NULL);
#006
第
3
行获取下一个记号,主要就是获取条件括号。
第
4
行是判断下一个记号是左括号开始。
第
5
行是定义了运行点。
#007 walk(conditional(')'), 0, lab);
#008
第
7
行是先调用函数
conditional
来处理条件表达式,然后再调用函数
walk
把条件表达式变成
DAG
森林。
#009 refinc /= 2.0;
#010 statement(loop, swp, lev);
#011
第
9
行是引用计数。由于条件语句分为两个分支,所以需要除
2
。
第
10
行是调用函数
statement
处理条件后面的第一个语句,这是递归调用处理。
#012 if (t == ELSE)
#013 {
#014 branch(lab + 1);
#015 t = gettok();
#016 definelab(lab);
#017 statement(loop, swp, lev);
#018 if (findlabel(lab + 1)->ref)
#019 definelab(lab + 1);
#020 }
#021 else
#022 definelab(lab);
#023 }
第
12
行是判断下一个记号是否有
else
关键字,如果有这个关键字说明它是第二、第三种
if
语句的形式,那么第
13
行到第
20
行就是处理
else
后面的语句。
第
14
行调用函数
branch
来生成跳转标号代码。
第
15
行是获取下一个记号。
第
16
行定义一个标号。
第
17
行是递归调用函数
statement
来处理
else
后面的语句。
第
22
行是生成标号
1
。
LCC
会把
if
语句生成下面形式:
if
表达式
== 0 goto
标号
1
语句
1
goto
标号
2
标号
1
:语句
2
标号
2
:
上面的代码
definelab(lab)
是生成标号
1
,
definelab(lab + 1)
是生成标号
2
。