pf_miles 发表于 2013-1-27 05:11:50

虎书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-expif(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 NULLif(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]
查看完整版本: 虎书P8问题(2)——直线式程序解释器