• C语言解释器的实现类型解析(三)


    上一篇:C语言解释器的实现--词法分析(二)

    1.类型的表示
      C语言的类型是相当灵活的,除了标准的类型(int char float double long 等等)外,自己根据需求,能定义出无穷的类型。一个具体的例子:
           int * a[10];
      它表示的意思是:
           a is ARRAY 0..9 of POINTER to INT
      仔细观察它的意思,就会发现,这个类型是其他基本类型按照一定顺序的组合:ARRAY|POINTER|INT。要表示这种形式,链表是最合适不过的了。如下图:


        
       (图2.1类型的表示)
     
      还有一些情况,比如结构体类型,那么上述的表示就不大合适了。例如下面的结构体:
          struct _a{
              int n;
              char * p[10];
          };
      结构中的每个域分别是由一个个的类型组成的。那么,我们可以用一个类型链表组成。具体就是:
          _a is STRUCT of
              n: INT
              p: ARRAY 0..9 of POINTER to INT
      如下图所示:
         

        
       (图2.2结构体的表示)
     
      程序中的类型定义如下:
          typedef struct type_t ttype_t;
          typedef struct type_t * ptype_t;
          typedef struct type_list_t ttype_list_t;
          typedef struct type_list_t * ptype_list_t;
          struct type_t{
              int bty;
              int size;
              ptype_t ty;
              ptype_list_t sty;
              char * name;
              char * tag;
              char * pos;
          };
          struct type_list_t{
              ptype_t ty;
              ptype_list_t next;
          };

    2.类型解析
      定义一个类型,我们可以把它分成三个部分:
      specifier + id + dclor
      对应到一个具体的定义:int * p[10]; 这三部分分别是:
      specifier     int *
      id              p
      dclor         [10]
      类型的解析过程是这样的,首先找到id,然后根据一个规则(向右再向左),依次解析出这个类型:
     

      
      (图2.3类型的解析过程)
     
      在第2步,有几种情况:
      a. [   表示数组,如果遇到[ 则进入解析数组函数
      b. (   表示函数,如果遇到( 则进入解析参数列表函数
     
      所以我们的解析函数是这样的:
          void dclor( ptype_t ty ){
              switch( *token ){
              case ALY: dcl_arrays(ty); break;
              case '(': ty->pos = prog;  dcl_args(ty); break;
              }
             
              dcl_pointers(ty);
             
              while(tok_top >= 0){
                  if( *tok_stack[tok_top].token == '(' ){  //左边是( 继续向右解析
                      token_pop();
                      get_token();
                      dclor(ty);
                  }
                  else{
                      struct token_node  node;
                      node = token_pop();
                      if( strcmp( node.token, "splitor" ) == 0 ){
                          //结束
                          break;
                      }
                      if( node.ty != NULL ){ 
                          sbt.ty = node.ty;
                      }
                      dcl_specifier( node.tok, NULL );
                  }
              }
          }
      
      对于类型的解析,我这里推荐下《C专家编程》中的类型解释部分,里面讲解得更加透彻。

  • 相关阅读:
    (3.4)常用知识-char与varchar的选择
    (3.3)常用知识-索引使用、维护与填充因子
    (3.2)常用知识-字符串处理
    (3.1)常用知识-日期处理
    基于Sql Server 2008的分布式数据库的实践
    将expression转化为数据类型int时发生算术溢出错误
    webserver and application server
    web前端
    linkin
    jquery load
  • 原文地址:https://www.cnblogs.com/linxr/p/2303908.html
Copyright © 2020-2023  润新知