java开发编译器:C语言逻辑控制语句if else if 的语法解析
2016-11-08 21:05
393 查看
具体的代码讲解和演示过程请参看视频:
用java开发编译器
从这节开始,我们看看解析器如何对逻辑控制语句,例如if else, for, while , do…while, goto 等语句进行相应的语法解析。
如果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.
下面我们看一个具体的分析实例:
对应语句:
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 这种条件转移控制代码。
用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 这种条件转移控制代码。
相关文章推荐
- Reactjs开发自制编程语言Monkey的编译器:语法解析
- java开发编译器:自底向上语法解析的基本原理
- java开发编译器之:LALR语法解析及代码生成
- 3 Java基础语法(运算符,键盘录入,流程控制语句,if语句)
- java学习之路 之 基本语法-程序流程控制-(if-else)语句练习题
- (基于Java)编写编译器和解释器-第7章:解析(Parsing)控制语句-第二部分(连载)
- java开发C语言编译器:消除冗余语句和把ifelse控制语句编译成字节码
- Java基础语法——运算符、流程控制语句、if条件语句
- java学习之路 之 基本语法-程序流程控制-(if-else)语句练习题
- (基于Java)编写编译器和解释器-第7章:解析(Parsing)控制语句-第一部分(连载)
- 图灵社区 : 阅读 : [讨论] Java语言被很多人抱怨语法繁琐、开发效率低、体系繁杂而笨重,为什么还有这么强的生命力,尤其是在企业软件领域?
- 初识JAVA——流程控制之if语句
- 第二章 java语言基本语法————流程控制
- 黑马程序员—Java语言基础(程序流程控制-if、switch、for、while、do while、break、continue)
- Tiny语言编译器开发之语法分析
- java中的if控制语句
- 【Java学习笔记】基础知识学习2【条件逻辑控制语句】
- JAVA程序设计1——开发环境搭建、数据类型及流程控制语句
- JavaSE基础第二部分:Java基础语法之流程控制语句
- JAVA基础:Java编程中if语句语法