現代編譯原理--第零章(含代碼)


  《現代編譯原理》,俗稱,虎書。因為這本書對實踐的要求比較高,所以選擇了這本書來作為編譯原理的學習書籍,想一步一步的記錄下來,最終完成一個完整的編譯器。但是,一個人看書總是感覺很孤獨。今天看第一章的題目,看完了都不知道要干什么。無奈找了一本中文版的,翻譯的也不如人意,還不如看英文的。最后去晚上找了半天才找到別人寫的第一章作業運行后,才知道要實現什么功能。然后自己徒手開始寫,居然沒有邏輯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("\n" ) ;
     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\n" , a) ;
    Table_ t = NULL ;
    t = interStm(p , t) ;
}

最后結果是 2   8  7  80


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM