Stanford编译原理详解

描述

第二部分的作业是语法分析,通过编写cool.y(这个assignment的任务),利用bison将其自动生成语法分析LALR(1)的代码。

语法分析,就是将词法分析阶段已经识别好的token,按照语法的规则,构建抽象语法树的过程。

比如以下的代码:

 

x = (a + b) * (c - d);

 

可以构成下图的抽象语法树:

 

        =
       / 
      x   *
         / 
        +   -
       /  / 
      a  b c  d

 

具体在cool.y 中,

编译

这部分定义了非终结符non-terminal对应的semanticvalue. Union中的每一个field都可以是parsing动作的结果。

在stanfordcompiler的教学语言cool中,这就对应了AST的一个node。每一个non-terminal,都有其对应的semanticvalue。

左侧的各种类型在cool-tree.aps中都有对应定义,比如Features:

编译

Feature即为class中的成员函数或者成员变量。因为可以有多个Feature,所以存在Features,即LIST[Feature].

下面则具体定义了所有的非终结符对应的AST节点类型。<>内部的,比如classes是在union中定义的value,而右侧的,比如class_list,我们需要定义规约该非终结符时,需要进行的操作。

编译

上图中$$即为action的返回值,对应该抽象语法树AST对应的node。

下面介绍如何声明非终结符对应的规约操作。

编译

具体如何对类的声明构建抽象语法树节点,即class的规则:

1)

 

CLASS TYPEID '{' feature_list '}' ';'
{
  /* 对应动作 action*/
  $$ = class_($2, 
  idtable.add_string("Object"), 
  $4, 
  stringtable.add_string(curr_filename));
}

 

其动作 对应cool-tree.aps中生命的constructor,

编译

传给class_的参数即为

    1)类名称     2)父类名称      3)成员变量/成员函数 

    4)文件名

对应的位置如类名称即为TYPEID,对应$2,  feature_list对应$4,因此其动作action写成了如上图所示的样子。

cool语法中,如果class类没有继承自其他类,那么默认继承自Object类型,因此parent设置为Object。

2)

 

CLASS TYPEID INHERITS TYPEID '{' feature_list '}' ';'
{ $$ = class_($2,$4,$6, 
stringtable.add_string(curr_filename)); }

 

这里唯一不同的即为该类继承自父类,因此其第2个参数,父类名称传入了$4。具体的序号可以参考第205行的注释。

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分