java开发编译器:C语言逻辑控制语句if else if 的语法解析

具体的代码讲解和演示过程请参看视频:
用java开发编译器

从这节开始,我们看看解析器如何对逻辑控制语句,例如if else, for, while , do…while, goto 等语句进行相应的语法解析。

if else 语句的语法解析

我们先看看 if else 的语法定义:

IF_STATEMENT -> IF LP TEST RP STATEMENT
IF_ELSE_STATEMENT -> IF_STATEMENT
IF_ELSE_STATEMENT ->IF_ELSE_STATEMENT ELSE STATEMENT
STATEMENT -> IF_ELSE_STATEMENT
TEST -> EXPR
DECL -> VAR_DECL EQUAL INITIALIZER 
INITIALIZER -> EXPR

如果C编译器遇到下面的语句:
if (i < 0)
i = 1;
else if (i == 0)
i = 2;
else
i = 3;

最开始的 if (i < 0) 则对应表达式:
IF_STATEMENT -> IF LP TEST RP STATEMENT
括号中间的 i < 0, 对应于语法中的TEST, 如果if 后面跟着else 关键字的话,像上面的例子, 那么代码:
if (i < 0)
i = 1;
else
这部分对应语法表达式:
IF_ELSE_STATEMENT ->IF_ELSE_STATEMENT ELSE STATEMENT
中的 IF_ELSE_STATEMENT ELSE 这部分, 剩下的部分:
if (i ==0)
i = 2;
else
i = 3;
则对应 STATEMENT , 其实这部分先是对应:

IF_ELSE_STATEMENT ->IF_ELSE_STATEMENT ELSE STATEMENT

然后再由:
STATEMENT -> IF_ELSE_STATEMENT
回归到STATEMENT.

下面我们看一个具体的分析实例:

void f() {
 int a = 0;
 int i = 0;
 if (i < 1)
   a = 1;
 else if (i < 2)
   a = 2;
 else 
   a = 3;
}

对应语句:
int a = 0;
int i = 0;
解析过程前面章节已经详细描述,这里不再分析,我们看看if 部分语句的分析:

1: 读入关键字if, 返回标签IF
2: 读入左括号,返回标签LP
3: 读入变量i, 返回对应标签NAME,根据表达式:
UNARY -> NAME
BINARY -> UNARY
进行递归
4:读入符号 <, 得到标签 RELOP
5: 读入数字1, 返回标签NUMBER
6: 根据下面表达式进行连续递归:
UNARY -> .NUMBER
BINARY -> .UNARY
BINARY -> .BINARY RELOP BINARY
NO_COMMA_EXPR -> .BINARY
EXPR -> .NO_COMMA_EXPR
TEST -> .EXPR
也就是说括号内的表达式 i < 0, 被推导为 TEST -> EXPR

7: 读入右括号LP, 如果变量i,返回标签NAME, 接着进行下面的表达式递归:
UNARY -> .NAME
BINARY -> .UNARY
NO_COMMA_EXPR -> .BINARY
8: 读入等号,得到标签 EQUAL, 继续读入数值1,然后根据下面表达式进行递归:
UNARY -> .NUMBER
BINARY -> .UNARY
NO_COMMA_EXPR -> .BINARY
9: 此时满足表达式:
NO_COMMA_EXPR -> .NO_COMMA_EXPR EQUAL NO_COMMA_EXPR
因此根据该表达式再次递归。
然后再根据表达式:
EXPR -> .NO_COMMA_EXPR
进行递归。
10:读入分号,得到标签SEMI, 此时EXPR SEMI 正好构成表达式:
STATEMENT -> .EXPR SEMI
的右半部分,因此可以进行对应reduce操作。

11: 此时解析堆栈上的所有符号就能满足表达式:
IF_STATEMENT -> .IF LP TEST RP STATEMENT
因此,当前解析的内容都对应非终结符IF_STATEMENT. 继续根据表达式:
IF_ELSE_STATEMENT -> .IF_STATEMENT
再递归一次。

12: 接下来的else 后面部分,其解析过程跟前面解析if相关语句的流程是一样的。先把关键字else读入,得到标签ELSE. 后面又是if else 的重复,所以解析过程跟前面步骤是一样的。

13: 读入最后一个else, 然后读入变量名i, 根据以下表达式进行递归:
UNARY -> .NAME
BINARY -> .UNARY
NO_COMMA_EXPR -> .BINARY
14: 读入等号得到标签EQUAL, 读入数值3,根据下面表达式进行递归:
UNARY -> .NUMBER
BINARY -> .UNARY
NO_COMMA_EXPR -> .BINARY

15: 此时表达式:
NO_COMMA_EXPR -> .NO_COMMA_EXPR EQUAL NO_COMMA_EXPR
的右边可以满足,于是就可以进行对应的递归操作。
然后再次依赖表达式:
EXPR -> .NO_COMMA_EXPR
再进行一次递归。

16:读入接下来的分号,得到标签SEMI,然后又可以根据下面表达式进行递归:
STATEMENT -> .EXPR SEMI
17:得到STATEMENT后,IF_ELSE_STATEMENT 的语法表达式右边部分又得到满足:
IF_ELSE_STATEMENT -> .IF_ELSE_STATEMENT ELSE STATEMENT
这样的话,整个if … else if … else …. 这段代码就全被上面的语法表达式给吸收了。

18: 最后再跟进表达式:
STATEMENT -> .IF_ELSE_STATEMENT
进行递归,这也说明,if else 相关语法是对应于STATEMENT这个非终结符的。

后续的解析流程跟前面分析的一样,最后解析器会进入到接收状态,这表明我们给的的语法能够正确的解析if else if 这种条件转移控制代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值