`
pf_miles
  • 浏览: 131563 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

虎书P8问题(2)——直线式程序解释器

阅读更多
《虎书》确实彪悍,绪论里就留给读者实践性这么强的问题,对于中文版第8页上的问题(2),我的答案如下:

p8q2.h:
#ifndef P8Q2_H
#define P8Q2_H

#include "util.h"
#include "slp.h"

typedef struct table* Table_;

struct table{string id; int value; Table_ tail;};

Table_ Table(string id, int value, Table_ tail);

Table_ interpStm(A_stm stm, Table_ t);

struct intAndTable{int value; Table_ t;};

typedef struct intAndTable* IntAndTable_;

IntAndTable_ IntAndTable(int value, Table_ t);

IntAndTable_ interpExp(A_exp exp, Table_ t);

#endif


p8q2.c:
#include "p8q2.h"
#include <stdio.h>
#include <stdlib.h>

Table_ update(string id, int value, Table_ t);
IntAndTable_ interpAndPrintExp(A_exp exp, Table_ t);

Table_ Table(string id, int value, Table_ tail){
    Table_ t = checked_malloc(sizeof(t));
    t->id = id;
    t->value = value;
    t->tail = tail;
    return t;
}

IntAndTable_ IntAndTable(int value, Table_ t){
    IntAndTable_ iat = checked_malloc(sizeof(iat));
    iat->value = value;
    iat->t = t;
    return iat;
}

Table_ interpStm(A_stm stm, Table_ t){
    Table_ t1;
    IntAndTable_ iat;
    if(stm->kind == A_compoundStm){
	t1 = interpStm(stm->u.compound.stm1, t);
	return interpStm(stm->u.compound.stm2, t1);
    }else if(stm->kind == A_assignStm){
	IntAndTable_ iat = interpExp(stm->u.assign.exp, t);
	return update(stm->u.assign.id, iat->value, iat->t);
    }else if(stm->kind == A_printStm){// To support one-by-one print, interprete exp-by-exp
	if(stm->u.print.exps->kind == A_lastExpList){
	    iat = interpAndPrintExp(stm->u.print.exps->u.last, t);
	    return iat->t;
	}else if(stm->u.print.exps->kind == A_pairExpList){
	    A_expList list = stm->u.print.exps;
	    while(list->kind == A_pairExpList){
		iat = interpAndPrintExp(list->u.pair.head, t);
		t = iat->t;
		list = list->u.pair.tail;
	    }
	    iat = interpAndPrintExp(list->u.last, t);
	    return iat->t;
	}else{
	    printf("Invalid print exps!\n");
	    exit(1);
	}
    }else{
	printf("Statement type error!\n");
	exit(1);
    }
}

IntAndTable_ interpExp(A_exp exp, Table_ t){
    int value1;
    IntAndTable_ iat1, iat2;
    Table_ t1;
    if(exp->kind == A_idExp){
	value1 = lookUp(exp->u.id, t);
	return IntAndTable(value1, t);
    }else if(exp->kind == A_numExp){
	return IntAndTable(exp->u.num, t);
    }else if(exp->kind == A_opExp){
	iat1 = interpExp(exp->u.op.left, t);
	iat2 = interpExp(exp->u.op.right, iat1->t);
	switch(exp->u.op.oper){
	    case A_plus:
		value1 = iat1->value + iat2->value;
		break;
	    case A_minus:
		value1 = iat1->value - iat2->value;
		break;
	    case A_times:
		value1 = iat1->value * iat2->value;
		break;
	    case A_div:
		value1 = iat1->value / iat2->value;
		break;
	    default: 
		printf("Invalid operator!\n");
		exit(1);
	}
	return IntAndTable(value1, iat2->t);
    }else if(exp->kind == A_eseqExp){
	t1 = interpStm(exp->u.eseq.stm, t);
	return interpExp(exp->u.eseq.exp, t1);
    }else{
	printf("Invalid operation type!\n");
	exit(1);
    }
}

Table_ update(string id, int value, Table_ t){
    return Table(id, value, t);
}

int lookUp(string key, Table_ t){
    while(t){// The initail table was a NULL
	if(strcmp(key, t->id) == 0){
	    return t->value;
	}
	t = t->tail;
    }
    return 0;// initial with 0
}

IntAndTable_ interpAndPrintExp(A_exp exp, Table_ t){
    IntAndTable_ iat = interpExp(exp, t);
    printf("%d ", iat->value);
    return iat;
}


main.c:
#include <stdio.h>
#include "util.h"
#include "prog1.h"
#include "slp.h"
#include "p8q1.h"
#include "p8q2.h"

int main(){
    interpStm(prog(), NULL);
    printf("\n");
    return 0;
}


输出结果:
8 7 80
分享到:
评论
1 楼 gatt 2008-10-06  
请问你还在研究这本书吗?这本书对我来说难度太大了,现在卡在活动记录,没办法继续读下去了

相关推荐

Global site tag (gtag.js) - Google Analytics