zoukankan      html  css  js  c++  java
  • 现代编译原理--第零章(含代码)

      《现代编译原理》,俗称,虎书。因为这本书对实践的要求比较高,所以选择了这本书来作为编译原理的学习书籍,想一步一步的记录下来,最终完成一个完整的编译器。但是,一个人看书总是感觉很孤独。今天看第一章的题目,看完了都不知道要干什么。无奈找了一本中文版的,翻译的也不如人意,还不如看英文的。最后去晚上找了半天才找到别人写的第一章作业运行后,才知道要实现什么功能。然后自己徒手开始写,居然没有逻辑bug的就完了。呵呵。突然感觉网上的资料太少,所以写这一个系列的文章也想把志同道合的聚集起来,大家一起来讨论虎书。本人毕业半年,有写的不对还希望大家指正。

      这本书的第一章,和其他外国书籍一样,先是讨论了一下本书的结构,需要有怎样的基础以及用到那些工具。然后介绍了编译器的各个方面。就个人而言,像这种总结和概述的章我一般喜欢看完全书以后再回头看看,那个时候就会对整本书有比较深刻的理解。但是这本书第一章给了一个小的练习,总结来说就是利用前面介绍的数据结构和文法规则创建一个计算print数量的函数和一个直线型程序语言翻译器。程序很简单,但是作为入门的练习,个人人为实在太好了。

      第一,这个作业让我开始关注编程语言本身。以前都是将程序语言作为整块去理解,理解其表达的逻辑含义和功能。但是在写这个程序的时候,它让我开始关注语言的每一句成分。首先,语言最基本的成分可以笼统的分为两类,语句(statement)和表达式(expression)。语句是执行完成后没有任何数值的产生,例如打印语句,转移语句,而表达式是有数值的产生的,算数操作,1+2 那么产生了3.

      第二,我然我了解到编程语言是怎么从文本变化到树状结构,如何对树状结构进行操作得到最后的结果。对编译器有了一个感性的了解。

      一下是代码:

    计算print的数量

    #ifndef MAXARGS_H_
    #define MAXARGS_H_
    #include "slp.h"
    int maxargs(A_exp) ;
    int maxargs(A_expList) ;
    int maxargs(A_stm a_stm) ;
    #endif
    #include "maxargs.h"
    #include "slp.h"
    
    int maxargs(A_stm a_stm) 
    {
        if (a_stm == NULL)
        {
            return 0 ;
        }
    
        switch(a_stm->kind)
        {
        case A_stm_::A_assignStm :
            return maxargs(a_stm->u.assign.exp) ;
        case A_stm_::A_printStm :
            return 1 + maxargs(a_stm->u.print.exps) ;
        case A_stm_::A_compoundStm:
            return maxargs(a_stm->u.compound.stm1) + maxargs(a_stm->u.compound.stm2) ;
        }
        return 0 ;
    }
    int maxargs(A_exp a_exp)
    {
        if (a_exp == NULL )
        {
            return 0 ;
        }
        switch(a_exp->kind)
        {
        case A_exp_::A_opExp:
            return maxargs(a_exp->u.op.left) + maxargs(a_exp->u.op.right) ;
        case A_exp_::A_eseqExp:
            return maxargs(a_exp->u.eseq.stm) + maxargs(a_exp->u.eseq.exp) ;
        }
        return 0 ;
    }
    int maxargs(A_expList a_explist)
    {
        if (a_explist == NULL)
        {
            return 0 ;
        }
        switch(a_explist->kind)
        {
        case A_expList_::A_pairExpList :
            return maxargs(a_explist->u.pair.head)+maxargs(a_explist->u.pair.tail) ;
        case A_expList_::A_lastExpList:
            return  maxargs(a_explist->u.last) ;
        }
        return 0 ;
    }

    将语言解释并且计算结果

    #ifndef INTERPRETES_H_
    #define INTERPRETES_H_
    #include "util.h"
    #include "slp.h"
    typedef struct table  *Table_ ;
    struct table
    {
      string id ;
      int value ;
      Table_ tail ;
    };
    typedef struct intAndTable_ *intAndTable ;
    struct intAndTable_
    {
        int i ;
        Table_ table ;
    };
    Table_ interStm(A_stm stm , Table_ t) ;
    intAndTable interExp(A_exp exp , Table_ t) ;
    intAndTable interExpList(A_expList expList , Table_ t) ;
    Table_ update(Table_, string ,int ) ;
    int  lookup(Table_ , string) ;
    #endif
    #include "interprets.h"
    #include "util.h"
    #include "slp.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    Table_ Table(string id ,  int value , Table_ *tail)
    {
        Table_ t = Table_(malloc( sizeof(*t)) );
        t->id = id ;
        t->value = value ;
        t->tail = t ;
        return t ;
    }
    
    Table_ interStm(A_stm stm , Table_ t)
    {
        if (stm == NULL )
        {
            return NULL ;
        }
        Table_ table ;
        intAndTable itable;
        A_expList tmpExplist ;
       switch(stm->kind)
       {
       case A_stm_::A_compoundStm:
         table = interStm(stm->u.compound.stm1 , t) ;
         return interStm(stm->u.compound.stm2 , table) ;
       case A_stm_::A_printStm:
           tmpExplist = stm->u.print.exps ;
           while(1)
           {
               if (tmpExplist->kind == A_expList_::A_lastExpList)
               {
                   itable = interExp(tmpExplist->u.last , t) ;
                   printf("   %d" , itable->i) ;
                   break ;
               }
               else
               {
                   itable = interExp(tmpExplist->u.pair.head , t) ;
                   printf("  %d" , itable->i) ;
                   tmpExplist = tmpExplist->u.pair.tail ;
               }
           }
         printf("
    " ) ;
         return itable->table ;
       case A_stm_::A_assignStm:
           itable = interExp(stm->u.assign.exp ,t) ;
           table = update(itable->table , stm->u.assign.id , itable->i) ;
           return table ;
       }
       return NULL ;
    }
    
    intAndTable interExpList(A_expList expList , Table_ t)
    {
        if (expList == NULL)
        {
            return NULL ;
        }
        intAndTable tmp ;
        switch(expList->kind)
        {
        case A_expList_::A_lastExpList:
         tmp = interExp(expList->u.last , t) ;
         return tmp ;
        case A_expList_::A_pairExpList:
            tmp = interExp(expList->u.pair.head , t) ;
            tmp = interExpList(expList->u.pair.tail , tmp->table) ;
            return tmp ;
         }
        return NULL ;
    }
    
    intAndTable interExp(A_exp exp , Table_ t)
    {
        if ( exp == NULL )
        {
            return NULL ;
        }
        intAndTable t1  =  intAndTable(malloc( sizeof(*t))) ;
        int tmp ;
       switch(exp->kind)
       {
       case A_exp_::A_idExp:
         t1->i = lookup(t , exp->u.id) ;
         t1->table = t ;
         return t1 ;
       case A_exp_::A_numExp:
           t1->i = exp->u.num ;
           t1->table = t ;
           return t1 ;
       case A_exp_::A_opExp:
          t1 = interExp(exp->u.op.left , t) ;
          tmp = t1->i ;
          t1 = interExp(exp->u.op.right , t1->table) ;
          switch(exp->u.op.oper)
          {
          case A_plus:
             tmp += t1->i ;
              break ;
          case A_minus:
              tmp -= t1->i ;
              break ;
          case A_times:
              tmp *= t1->i ;
              break ;
          case A_div:
              tmp /= t1->i ;
              break ;
          }
          t1->i = tmp ;
          return t1 ;
       case A_exp_::A_eseqExp:
              t = interStm(exp->u.eseq.stm , t) ;
              t1 = interExp(exp->u.eseq.exp , t) ;
              return t1 ;
       }
       return NULL ;
    }
    
    Table_ update(Table_ t, string s ,int v)
    {
        Table_ t1 = Table_(malloc( sizeof(*t1))) ;
        t1->id = s ;
        t1->tail = t ;
        t1->value = v ;
        return t1 ;
    }
    
    int lookup(Table_ t, string c)
    {
        Table_ tmp = t ;
        while(tmp)
        {
            if (tmp->id == c)
            {
                return tmp->value ;
            }
            tmp = tmp->tail ;
        }
        return -1 ;
    }

    这是主函数

    /* This file is intentionally empty.  You should fill it in with your
    solution to the programming exercise. */
    
    #include "prog1.h"
    #include "slp.h"
    #include "util.h"
    #include "interprets.h"
    #include "maxargs.h"
    void main()
    {
        A_stm p ;
        p = prog() ;
        int a = maxargs(p) ;
        printf("the print number is %d
    " , a) ;
        Table_ t = NULL ;
        t = interStm(p , t) ;
    }

    最后结果是 2   8  7  80

  • 相关阅读:
    redis集群的测试
    nginx+tomcat集群
    linux 端口占用查看 netstat -tunpl | grep 6379
    Openfire 的安装和配置
    openfire自定义发送消息
    druid+spring配置
    java Servlet Filter 拦截Ajax请求,统一处理session超时的问题
    Tomcat8安装, 安全配置与性能优化
    ssh 免密码登录【用】
    SSH-KeyGen 的用法
  • 原文地址:https://www.cnblogs.com/BlackWalnut/p/4420568.html
Copyright © 2011-2022 走看看