LCC编译器的源程序分析(29)if条件语句

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  

你可能感兴趣的:(null,编译器,branch)