LCC编译器的源程序分析(39)goto语句

本文详细解析了goto语句及标号的处理过程,包括如何定义标号、处理goto语句,以及如何避免重复定义等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在现代设计的程序里,很少再用到goto语句了。虽然使用goto语句是比较高效,但它使程序也会得非常难懂,非常难维护,比较容易出错,所以很少使用goto语句的。goto语句为无条件跳转语句,它的一般形式为:
 goto 标号;
LCC里的是用下面的代码来处理:
#001 case GOTO:   
#002         walk(NULL, 0, 0);
#003         definept(NULL);
#004         t = gettok();
#005         if (t == ID)
#006         {
#007               Symbol p = lookup(token, stmtlabs);
#008 
#009               if (p == NULL)
#010               {
#011                    p = install(token, &stmtlabs, 0, FUNC);
#012                    p->scope = LABELS;
#013                    p->u.l.label = genlabel(1);
#014                    p->src = src;
#015               }
#016               use(p, src);
#017               branch(p->u.l.label);
#018               t = gettok();
#019         }
#020         else
#021               error("missing label in goto/n"); expect(';');
#022         break;
2行复位所有分配的内存。
3行定义执行点。
4行获取下一个记号。
5行判断goto语句后面是否标号变量。如果是标号变量,就跳到第6行到第19行里处理。否则就在第21行里提示出错。
7行里查找标号是否已经定义。
9行是当标号还没有定义时,就把这个标号安装到符号表里。这是在第9行到第15行里处理。
17行是生成跳转到标号的代码。
 
下面再来分析标号语句是怎么样定义的,如下:
#001 case ID:    
#002         if (getchr() == ':')
#003         {
#004               stmtlabel();
#005               statement(loop, swp, lev);
#006               break;
#007         }
2行就判断一个ID标识符是否标号变量,如果在一个ID后面紧跟着一个冒号,就是表示声明了一个标号变量,所以在第4行里调用函数stmtlabel来处理标号。
5行是处理标号后面的语句。
 
下面来分析函数stmtlabel
#001 static void stmtlabel(void)
#002 {
#003  Symbol p = lookup(token, stmtlabs);
#004 
#005  if (p == NULL)
#006  {
#007         p = install(token, &stmtlabs, 0, FUNC);
#008         p->scope = LABELS;
#009         p->u.l.label = genlabel(1);
#010         p->src = src;
#011  }
#012 
#013  if (p->defined)
#014         error("redefinition of label `%s' previously defined at %w/n", p->name, &p->src);
#015 
#016  p->defined = 1;
#017  definelab(p->u.l.label);
#018  t = gettok();
#019  expect(':');
#020 }
3行是查找这个标号是否定义。
5行判断这个标号是否定义,如果没有定义就添加到符号表。
7行是保存到符号表。
8行到第10行都是设置标号的属性。
13行当重复定义标号时,提示出错。
16行设置这个标号已经定义。
17行定义一个标号。
18行获取下一个记号。
19行检查标号后是否冒号。
 
这样就可以处理goto语句和标号语句了,到这里就把所有基本的语句分析完成了。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值