java开发C语言解释器:间套结构体的解释和执行

更详细的讲解和代码调试演示过程,请参看视频
用java开发C语言编译器

上节,我们完成了解释器对结构体的解释和执行,从而我们的C语言解释器基本上拥有了运行含有结构体的C语言程序的能力,关于结构体,我们还有一点需要解析的,那就是间套结构体,例如下面的C语言程序:

void main() {

struct s1 {
int v1;
} ;

struct s2 {
    struct s1 s;
    int v2;
}

struct s2 tag;
tag.s.v1 = 1;
tag.v2 = 2;

printf("set filed v1 of struct s1 to value : %d, and v2 of tag to value : %d", tag.s.v1, tag.v2); 

}

上面的程序中,我们先定义一个结构体为s1, 然后再定义第二个结构体s2, s2的特点是,在它体内包含了结构体s1, 也就是产生了结构体的间套。我们上一节的代码已经支持了结构体间套的执行,但我觉得,其中的逻辑还是需要进一步解释清楚。

这里写图片描述

根据上一节的理论,我们知道,结构体变量所对应的Symbol对象,它包含了一个链表,这个链表把结构体里面的变量串联起来,当要访问结构体的某个子域时,先找到该结构体的 Symbol对象,从该对象中得到子域链表,再从链表中,根据要访问的子域的名称,找到子域对应的Symbol对象,那么对结构体子域的读写可以直接转换成子域Symbol对象的读写。

当结构体的定义含有间套时,也就是一个结构体内部又定义了另一个结构体,上面的步骤就得反复进行,例如代码中的语句:

tag.s.v1 = 1;

解释器在解读上面语句时,先找到tag对应的Symbol对象,然后从该对象中找到子域的Symbol列表,接着利用子域的名称”s”, 在列表中找到对应的Symbol对象,从这个对象中再次获得子域链表,然后根据子域的名称”v1”,从列表中查找到字符串名称为”v1”的Symbol对象,于是任何对 tag.s.v1 的访问都转换为v1对应的Symbol 对象。

根据上节讲述,对结构体子域的查找为如下代码片段,其位于UnaryNodeExecutor.java中,代码如下:

public class UnaryNodeExecutor extends BaseExecutor{

    @Override
    public Object Execute(ICodeNode root) {
        executeChildren(root);

        int production = (Integer)root.getAttribute(ICodeKey.PRODUCTION); 
        String text ;
        Symbol symbol;
        Object value;
        ICodeNode child;

        switch (production) {
        ....
         case CGrammarInitializer.Unary_StructOP_Name_TO_Unary:
            child = root.getChildren().get(0);
            String fieldName = (String)root.getAttribute(ICodeKey.TEXT);
            symbol = (Symbol)child.getAttribute(ICodeKey.SYMBOL);

            Symbol args = symbol.getArgList();
            while (args != null) {
                if (args.getName().equals(fieldName)) {
                    break;
                }

                args = args.getNextSymbol();
            }

            if (args == null) {
                System.err.println("access a filed not in struct object!");
                System.exit(1);
            }

            root.setAttribute(ICodeKey.SYMBOL, args);
            root.setAttribute(ICodeKey.VALUE, args.getValue());
            break;

        }
        ....
        }
....
}

在解读语句 tag.s.v1 时,上面的代码会执行两次,第一次是解读tag.s的时候,解释器通过字符串tag找到对应的Symbol, 然后从中获得子域链表,接着利用字符串”s”在子域链表中查找对应的Symbol对象,这就是上面代码while循环所做的工作。

第二次是解读s.v1的时候,上面的代码会根据s所对应的子域链表,通过字符串v1查找对应的Symbol对象,以后任何对tag.s.v1的访问都会转换成对该Symbol对象的访问。

如果存在多层结构体间套,上面的代码会反复执行,直到找到最底层的子域所对应的Symbol对象。

我们的解释器解释执行上面的C语言代码后结果如下:

set filed v1 of struct s1 to value : 1, and v2 of tag to value : 2

通过结果来看,我们的解释器支持结构体的间套定义,并支持对间套的结构体进行正确的读写。

更多详细的讲解和代码调试演示,请参看视频。

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值