java开发C语言解释器:编译并实现IfElse语句逻辑流程

来源:互联网 发布:知柏地黄丸方歌 编辑:程序博客网 时间:2024/06/05 12:08

具体的代码说明,讲解,调试,演示,请参看视频:
用java开发编译器

上一节,我们的解释器已经成功实现了对数组元素的读取和访问,这让我们的解释器有了进一步的完善,本节,我们将再接再厉,为解释器增添新的代码执行功能,这次我们要完成的解释功能是,让解释器能够解析并正确执行If Else 条件判断语句。

这次我们需要解释执行的C语言程序示例如下:

void f() {int a;int b;a = 1;if (a > 0) {        b = a + 2;    }}

上面代码只有if 条件判断,完成了上面代码的解析执行功能后,我们再进一步,增添else 的解析执行功能,也就是,我们会进一步让解释器执行如下代码:

void f() {int a;int b;a = 1;if (a > 1) {        b = a + 2;    }else {        b = a + 3;    }}

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

根据上面语法表达式,解析器构造的语法执行树如下:

这里写图片描述

接下来我们看看相关代码实现,首先是CodeTreeBuilder.java里面,增添了构造上面代码执行树的相关代码:

 public ICodeNode buildCodeTree(int production, String text) {        ICodeNode node = null;        Symbol symbol = null;        switch (production) {        ...        case CGrammarInitializer.Expr_TO_Test:            node = ICodeFactory.createICodeNode(CTokenType.TEST);            node.addChild(codeNodeStack.pop());            break;        case CGrammarInitializer.If_Test_Statement_TO_IFStatement:            node = ICodeFactory.createICodeNode(CTokenType.IF_STATEMENT);            node.addChild(codeNodeStack.pop()); //Test            node.addChild(codeNodeStack.pop()); //Statement            break;        case CGrammarInitializer.IfElseStatemnt_Else_Statemenet_TO_IfElseStatement:            node = ICodeFactory.createICodeNode(CTokenType.IF_ELSE_STATEMENT);            node.addChild(codeNodeStack.pop()); //IfStatement            node.addChild(codeNodeStack.pop()); // statement            break;        ...        }

如果当前解析执行的C代码只有if 没有else部分的话,那么解释器会依赖类IfStatementExecutor去解释执行对应代码,我们看看相关代码实现:

public class IfStatementExecutor extends BaseExecutor {     @Override      public Object Execute(ICodeNode root) {         ICodeNode res = executeChild(root, 0);          Integer val = (Integer)res.getAttribute(ICodeKey.VALUE);         copyChild(root, res);           if (val != null && val != 0) {             executeChild(root, 1);         }            return root;        }}

上面的代码逻辑是这样的,If 节点先执行它第一个孩子节点,它的第一个孩子节点是Test节点,也就是先执行if判断条件,如果判断条件成立,也就是返回值val的结果不是0,那么就执行If节点的第二个孩子,第二个孩子对应的是if语句接下来用大括号包着的代码块,对应于语法表达式就是Statement节点。

如果C语言中的条件判断形式是if else, 那么解释器会依赖类ElseStatementExecutor,来对相关的C语言代码进行解释执行,该类的代码如下:

package backend;import java.util.Collections;public class ElseStatementExecutor extends BaseExecutor {    @Override    public Object Execute(ICodeNode root) {        //先执行if 部分         ICodeNode res = executeChild(root, 0);         Object obj = res.getAttribute(ICodeKey.VALUE);         if ((Integer)obj == 0) {             //if 部分没有执行,所以执行else部分             res = executeChild(root, 1);          }         copyChild(root, res);         return root;    }}

它先执行它的第一个孩子节点,根据语法表达式它的第一个孩子节点对应的是IF 节点,也就是他先执行if 部分的代码,如果if判断条件成立,那么该节点执行后的返回结果将不会是0,如果是0的话,表明if 判断条件不成立,因此该节点要执行它的二孩子,也就是else 部分对应的Statment节点。

If 部分的条件判断,也就是Test节点的执行,最终会落到BinaryExecutor里面,我们看看相关代码:

public class BinaryExecutor extends BaseExecutor{    @Override    public Object Execute(ICodeNode root) {        executeChildren(root);        ICodeNode child;        int production = (int)root.getAttribute(ICodeKey.PRODUCTION);        switch (production) {        ...        case CGrammarInitializer.Binary_RelOP_Binary_TO_Binray:             val1 = (Integer)root.getChildren().get(0).getAttribute(ICodeKey.VALUE);             String operator = (String)root.getChildren().get(1).getAttribute(ICodeKey.TEXT);             val2 = (Integer)root.getChildren().get(2).getAttribute(ICodeKey.VALUE);             switch (operator) {             case "==":                 root.setAttribute(ICodeKey.VALUE, val1 == val2 ? 1 : 0);                 break;             case "<":                 root.setAttribute(ICodeKey.VALUE, val1 < val2? 1 : 0);                 break;             case "<=":                 root.setAttribute(ICodeKey.VALUE, val1 <= val2? 1 : 0);                 break;             case ">":                 root.setAttribute(ICodeKey.VALUE, val1 > val2? 1 : 0);                 break;             case ">=":                 root.setAttribute(ICodeKey.VALUE, val1 >= val2? 1 : 0);                 break;             case "!=":                 root.setAttribute(ICodeKey.VALUE, val1 != val2? 1 : 0);                 break;        ...        }

它会解析if条件判断语句,把判断结果返回给父节点,如果条件成立的话,返回整形数值1,如果条件不成立,返回整形数值0,If 节点根据这个返回值,觉得是否执行它对应的Statment子节点

具体的代码说明,讲解,调试,演示,请参看视频:
用java开发编译器

0 0