现代编译原理--第零章(含代码)

时间:2022-05-24 01:30:25

  《现代编译原理》,俗称,虎书。因为这本书对实践的要求比较高,所以选择了这本书来作为编译原理的学习书籍,想一步一步的记录下来,最终完成一个完整的编译器。但是,一个人看书总是感觉很孤独。今天看第一章的题目,看完了都不知道要干什么。无奈找了一本中文版的,翻译的也不如人意,还不如看英文的。最后去晚上找了半天才找到别人写的第一章作业运行后,才知道要实现什么功能。然后自己徒手开始写,居然没有逻辑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