百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Java开发C语言解释器根据执行树执行代码

toyiye 2024-05-25 20:11 13 浏览 0 评论

前一节,我们建立起了代码执行树,本节我们看看,如何根据执行树执行c语言代码,以下是我们上一节构建的执行树:


这些执行树,本质上是图论里面的有向图,我们执行代码的过程,实际上是根据有向图进行深度优先遍历的过程,我们先遍历到底层节点,根据底层节点的信息执行相应动作,然后把执行的结果传递给上一层节点,然后再根据传递上来的信息做相应的操作,以此类推,知道返回到根节点时,执行结束。


我们先看看与解释器相关的代码实现:


public interface Executor {
    public Object Execute(ICodeNode root);
}

Executor是一个接口,执行树中每个节点都对应相应类型的executor,具体每个类型的executor都实现Executor接口,例如类型为no_comma_expr类型的节点就会对应一个NoCommaExprExecutor类,在上面的接口基础上,我们先实现一个解释器的基类叫BaseExecutor

package backend;

import java.util.Collections;

public abstract class BaseExecutor implements Executor{
    protected void executeChildren(ICodeNode root) {
        ExecutorFactory factory = ExecutorFactory.getExecutorFactory();
        Collections.reverse(root.getChildren());
        int i = 0;
        while (i < root.getChildren().size()) {
            ICodeNode child = root.getChildren().get(i);
            Executor executor = factory.getExecutor(child);
            executor.Execute(child);
            i++;
        }
    }


    protected void copyChild(ICodeNode root, ICodeNode child) {
        root.setAttribute(ICodeKey.SYMBOL, child.getAttribute(ICodeKey.SYMBOL));
        root.setAttribute(ICodeKey.VALUE, child.getAttribute(ICodeKey.VALUE));
        root.setAttribute(ICodeKey.TEXT, child.getAttribute(ICodeKey.TEXT));
    }
}

BaseExecutor实现两个调用,一个是executeChildren,这个接口的作用是,当我们遍历到执行树上的某个节点时,要根据该节点进行相应的代码操作,while循环里就是从孩子队列里取出每个孩子对下,然后从Executor的工厂类获得对应的执行对象去进行相应的动作。

copyChild目的是,把孩子节点的所有相关信息拷贝到父节点。

接下来我们看看Executor工厂类:

package backend;
import fromtend.CTokenType;
public class ExecutorFactory{
	private static ExecutorFactory executorFactory = null;
	private ExecutorFactory(){
  }
	public static ExecutorFactory getExecutorFactory(){
  	
    if(executorFactory==null){
    	executorFactory = new ExecutorFactory();
    }
    return executorFactory; 
  }
	pubic Exectory getExecutor(ICodeNode.TokenType){
  	CTokenType type = (CTokenTYpe)node.getAttribute(ICodeKey.TokenType)
		switch(type){
    	case UNARY:
            return new UnaryNodeExecutor();
        case BINARY:
            return new BinaryExecutor();
        case NO_COMMA_EXPR:
            return new NoCommaExprExecutor();
        case EXPR:
            return new ExprExecutor();
        case STATEMENT:
            return new StatementExecutor();
        case STMT_LIST:
            return new StatementListExecutor();
        }

        return null;
    }
  
  }
}

通过getExecutor可以看到,工程类会根据传入的节点类型生成对应的执行对象,当前节点类型有集中,我们就可以生成集中不同类型的节点执行器。我么先看看某个具体节点执行器的实现,例如BinaryExecutor:

package backend;
import java.util.Collections;
import frontend.CGrammarInitializer;
import frontend.Symbol;
public class BinaryExecutor extends BaseExecutor{
	public Object Execute(ICodeNode root){
  	executeChildren(root);
  }
	ICodeNode child;
  int production = (int)root.getAttribute(ICodeKey.PRODUCTION);
	case CGrammarInitializer.Uanry_TO_Binary:
            child = root.getChildren().get(0);
            copyChild(root, child);
            break;

        case CGrammarInitializer.Binary_Plus_Binary_TO_Binary:
            Collections.reverse(root.getChildren());
            //先假设是整形数相加
            int val1 = (Integer)root.getChildren().get(0).getAttribute(ICodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttribute(ICodeKey.VALUE);
            root.setAttribute(ICodeKey.VALUE, val1 + val2);

            System.out.println("Assign sum of " + root.getChildren().get(0).getAttribute(ICodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttribute(ICodeKey.TEXT) + " to variable " + root.getAttribute(ICodeKey.TEXT));
            break;
        }

        return root;
}

在Execute函数中,先调用executeChildren对所有汉字节点执行操作,然后根据执行节点所对应的表达式进行相应的操作,例如,如果当前binary节点对应的表达式是:

binary= binary+binary

那么我们知道,当前要执行的就是加法操作,于是执行器从当前节点的两个子节点所对应的表达式进行相应的操作,获得要做加法操作的两个加数,把他们相加后存到当前节点,这样当前节点的父节点就可以拿到当前节点的执行结果,以便进行相应的操作。

其他的执行器逻辑类似,具体我们看看语句:

a=a+b

是如何被执行的

1: 从第二个图开始,执行树的根节点是STMT_LIST, 然后一直往下遍历,直到倒数第二个节点:NO_COMMA_EXPR.

2: NO_COMMA_EXPR 有两个子节点,于是先执行这两个子节点,因此先往下走,遍历到最下方的NO_COMMA_EXPR节点。

3:当前节点有一个孩子节点,BINARY, 于是向右走,遍历到子节点BINARY.

4: 当前BINARY有两个子节点,因此可以先往右走,一直遍历到最底层节点UNARY.

5: UNARY是最底层节点,因此可以直接执行,执行的过程是,根据UNARY节点的SYMBOL对象,获得变量a对应的数值,把该数值存储到节点里,然后返回到父节点BINARY。

6: 在父节点BINARY中,根据前面显示的代码,该节点要做的只是把子节点所有信息拷贝过来,当然也就把变量a的值以及对应的Symbol也拷贝过来,然后再返回父节点,也是BINARY节点。

7:当前BINARY节点还有一个子节点,对应的是变量b,因此继续遍历第二个子节点,执行过程跟步骤4,5,6一样,这样当前BINARY节点的两个子节点就分别含有变量a 和 b 对应的数值,根据前面代码,BINARY对应的执行器会把两个子节点的数值相加,然后存储到当前节点。

8:然后继续返回到父节点NO_COMMA_EXPR, 该节点执行是所做的操作就是把子节点的值拷贝过来,于是当前节点就包含了a + b的结果,然后继续返回到父节点NO_COMMA_EXPR.

9: 此时节点NO_COMMA_EXPR 正右边还有一个子节点,于是执行该子节点,该子节点执行后的作用是得到变量a对应的Symbol对象。

10:由于所有子节点都执行完毕,当前节点NO_COMMA_EXPR可以执行相应操作,它做的动作是将下方子节点NO_COMMA_EXPR的数值赋值到右边节点所得到的Symbol对象里,也就是把 a+b的值设置到变量a所对应的Symbol对象中,这样,语句a = a + b; 就执行结束了。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码