loop_in_codes

低调做技术__欢迎移步我的独立博客 codemaro.com 微博 kevinlynx

实现一种解释性脚本语言(五)

author: Kevin Lynx email: zmhn320#163.com date: 3.10.2009

符号表

    在上一节中,当我们的解释器解释执行age=age+1这个语法树时,会涉及到变量age的值
。实际上我们还需要个保存脚本中相关变量的模块,当我们的解释器获取到一个ID树节点时
,需要从这个模块中获取出该变量的值,并参与运算。
    这个我称之为符号表。我想到这里,我所说的概念很可能和教科书有点不一样了。

什么是符号表?

    符号表(symbol table)就如同其字面意思一样,是一个表,更宽泛地说是一个保存符号
的容器。
    脚本中诸如变量函数之类的东西都算作符号,例如age。符号表就是保存这些符号的容
器。
    在kl中,符号表保存着某一个作用域里的变量。其全局符号表还保存着函数符号,对于
函数符号而言,其值为语法树树节点的指针值。当调用一个函数时,将该值转换为树节点,
然后执行。当然,这应该算做解释执行一节的细节,不多说。

    再明确下符号表的作用,举例,在上一节中,涉及到这么一个例子函数:
    value factor( TreeNode *node )
    {
        switch( node->type )
        {
            case ID:
                /* 在这里,发现一个树节点类型为ID,就需要根据ID对应的名字,也就
                 是age,在符号表中查找age的值 */
                return age;   
        /* ... */
        }
    }
    以上注释阐述了符号表的作用。

符号表的实现

    其实不管符号表如何实现,对于其他模块而言,对符号表的唯一要求就是提供几个类似
这样的接口:
    value sym_lookup( const char *name );
    void sym_insert( const char *name, value val );
    也就是说,提供查找符号值,以及插入新符号的接口。

    在kl中,使用了<编译原理与实践>中相同的符号表数据结构实现。即使用了hash表,
hash数组中每个元素保存的是一个链表头节点。每一个符号字符串通过散列函数得到hash数
组索引,然后在该索引里进行一次线性查找。很典型的hash结构。

    另一方面,因为kl支持全局和函数局部两个作用域。所以kl中有一个全局符号表,用于
保存全局变量以及所有的函数符号;同时每一次进入一个函数时,就会创建一个临时的局部
符号表,用于存储局部变量;后来,为了支持插件,插件函数被特定地保存在另一个全局符
号表里。

代码导读

    kl中的符号表实现代码在klsymtab.h/klsymtab.c中,实现比较简单,无需多言。

posted on 2009-03-10 08:58 Kevin Lynx 阅读(3163) 评论(0)  编辑 收藏 引用 所属分类: kl脚本实现编译原理


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理