您的位置 首页 java

Java开发C语言解释器:编译并实现If、else逻辑

上一节,我们的 解释器 已经实现了对数组元素的访问和读取,这让我们的解释器有了进一步完善,本节,我们将再接再厉,为解释器增添新的代码执行功能,这次我们要完成的解释功能是,让解释器能够解析并正确执行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);
          copy Child(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节点的执行,最终会落到 Binary Executor里面,我们看看相关代码:

 
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开发C语言解释器:编译并实现If、else逻辑

文章地址:https://www.zhihuclub.com/190380.shtml

关于作者: 智云科技

热门文章

网站地图