CS143 Tour of the Cool Support Code 阅读

A Tour of the Cool Support Code介绍了写Cool编译器过程中我们可以使用的数据结构。

本文是我阅读这篇指导的笔记,会随着我做作业的进度慢慢地更新。

Introduction

数据结构包括如下:

  • 链表linked list
  • 字符串表string table
  • 符号表symbol table
  • 其他暂时还没在作业中用到的东西。

阅读原文应该与源码配合,源码在includeassignment文件夹中的对应作业下。

Lists

list.h中实现了简单的链表。

  • 成员:T *headList<T>* tail,可以看出这是一个递归的定义。
  • hd()返回首元素
  • tl()返回尾元素
  • list_map()list中的每个元素执行一个操作,该操作由调用方给出。
  • list_print()打印整个链表
  • list_length()链表长度

链表使用的例子可以在字符串表和符号表的实现中找到。

String Tables

由于有大量的字符串需要管理,并且很多都是重复的,为了保证高效,就有了string table

注意:

  • String Tables包括String TableInt Table以及Id Table3个。
  • Entry:表中的元素称作词条Entry,存放string和每个字符串唯一的整数标识index,即<index,string>键值对。
  • 相同的字符串在一个表中只会存在一个,但不同表,如String TableInt Table,中可能存在一样的字符串。
  • Symbol:指向Entry的指针。

Entry

API
class Entry {
protected:
  char *str;     // 字符串 value
  int  len;      // 长度
  int index;     // 标识,即key
public:
  Entry(char *s, int l, int i);
  int equal_string(char *s, int len) const;  // 判断s与str是否相等
  bool equal_index(int ind) const; // 判断index是否与ind相等
  ostream& print(ostream& s) const; // 输出
  char *get_string() const; // 返回字符串
  int get_len() const;// 返回长度
};

函数具体实现在stringtab.cc文件中。

string table 中的3种Entry

有3种词条,分别存放不同类型的数据:

  • 真的字符串,如string fghij = "abcde"中的"abcde"
  • 变量名的字符串表示,如string fghij = "abcde"中的fghij
  • 数字的字符串表示,如int abc = 123;中的123

上面3种即对应:

// stringtab.h
class StringEntry : public Entry {
public:
  void code_def(ostream& str, int stringclasstag);
  void code_ref(ostream& str);
  StringEntry(char *s, int l, int i);
};
class IdEntry : public Entry {
public:
  IdEntry(char *s, int l, int i);
};
class IntEntry: public Entry {
public:
  void code_def(ostream& str, int intclasstag);
  void code_ref(ostream& str);
  IntEntry(char *s, int l, int i);
};

Tables

有了上面的几个Entry,就可以实现对应的Table了。

首先是一个父table,指明各个子table中可用的方法:

// stringtab.h
template <class Elem> 
class StringTable
{
protected:
   List<Elem> *tbl;   // 用List存放
   int index;         // the current index
public:
   StringTable(): tbl((List<Elem> *) NULL), index(0) { }   
   // 添加元素,返回新词条的指针
   Elem *add_string(char *s, int maxchars);// 加入s的前缀,长度maxchars
   Elem *add_string(char *s); // 加入s
   Elem *add_int(int i); // 在表中加入代表数字i的字符串
    
   // iterator.
   int first();       // 返回第一个Entry的index
   int more(int i);   // 检查是否
   int next(int i);   // 返回下一个Entry的index
   // 查找,返回目标的指针
   Elem *lookup(int index);      // 查找index对应的Entry
   Elem *lookup_string(char *s); // 查找string对应的Entry

   void print();  // 打印整个table

};

然后3table继承上面的父类:

// stringtab.h
class IdTable : public StringTable<IdEntry> { }; // 变量名 identifier table
class StrTable : public StringTable<StringEntry> // string table
{
public: 
   void code_string_table(ostream&, int classtag);
};
class IntTable : public StringTable<IntEntry> // int table
{
public:
   void code_string_table(ostream&, int classtag);
};

函数方法具体的实现在stringtab_function.h中。

上面所说的内容是PA2中需要用到的。

Utilities

utilities.h中定义了一些可能用到的辅助函数。

Abstract Syntax Trees

在语法分析完成时,程序中就有了一棵AST,可以查看cool-tree.aps进一步理解AST,这个文件是aps语言编写的,大致了解一下内容就可以了。

phyla 和 constructors

cool-tree.aps中可以看到一些phylum类型的变量和对应的构造函数,可以用这些构造函数生成AST的节点。

cool.y中有使用构造函数的例子如下:

class_($2,$4,$6,stringtable.add_string(curr_filename))

这样就创建了一个class_节点。

AST Lists

有一些数组类型的phylum,含有若干个变量,如:

phylum Classes = LIST[Class_];

对于列表类型的变量, aps自动提供了如下函数(以Class举例):

在这里插入图片描述

分别表示:

  • 构造空的列表Classes
  • 构造仅有一个元素的列表Classes
  • 在尾部添加元素
  • 返回第index个元素
  • 返回列表长度

这些方法是实现语法树的基础,通过这些方法我们可以方便地模拟文法,进而实现语法树。

所有内容都可以在cool-tree.cc中找到实现。

除此之外,比较重要的是6.5中的构造函数列表,我们会使用列表中的函数构造节点。

上面所说的是PA3要用到的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值