现代编译原理 第一章

时间:2021-03-02 01:29:43

入门小练习:


找出给定语句内任意子表达式的print函数的最大参数个数


#include"slp.h"
#include"prog1.h"
#include<stdio.h>
int maxargs(A_stm stm);
int maxargsexlst(A_expList expList);
int maxargsex(A_exp exp);
int countargs(A_expList expList);
int max(int temp1, int temp2)
{
	return temp1 > temp2 ? temp1 : temp2;
}

int maxargsexlst(A_expList expList)
{
	switch (expList->kind)
	{
	case A_pairExpList:
	{
						  int temp1 = maxargsexlst(expList->u.pair.tail);
						  int temp2 = maxargsex(expList->u.pair.head);
						  return max(temp1, temp2);
	}
	case A_lastExpList:
		return maxargsex(expList->u.last);
	default:
		return 0;
	}
}
int maxargsex(A_exp exp)
{
	switch (exp->kind)
	{
	case A_opExp:
	{
					int temp1 = maxargsex(exp->u.op.left);
					int temp2 = maxargsex(exp->u.op.right);
					return max(temp1, temp2);
	}
	case A_eseqExp:
	{

					  int temp3 = maxargsex(exp->u.eseq.exp);
					  int temp4 = maxargs(exp->u.eseq.stm);
					  return max(temp3, temp4); 
	}
	default:
		return 0;
	}
}

int maxargs(A_stm stm)
{
	switch (stm->kind)
	{
	case A_compoundStm:
	{
						  int temp1 = maxargs(stm->u.compound.stm1);
						  int temp2 = maxargs(stm->u.compound.stm2);
						  return max(temp1, temp2);
	}
	case A_assignStm:
	{
		A_exp tempExp = stm->u.assign.exp;
		return maxargsex(tempExp);
	}
	case A_printStm:
		return max(maxargsexlst(stm->u.print.exps), countargs(stm->u.print.exps));
	default:
		return 0;
	}
}

int countargs(A_expList expList)
{
	if (expList->kind == A_pairExpList)
	{
		return 1 + countargs(expList->u.pair.tail);
	}
	else
		return 1;
}
/**********************************************************/
int main()
{
	A_stm stm = prog();
	printf("%d",maxargs(stm));
	//system("pause");
	return 0;
} 

直线式程序语言的解释可以利用语法抽象的方法,理解程序短语可以抽象为树这种数据结构来分析。利用树结构的递归性去设计解释方法。

countargs是对A_printStm参数个数的分析

maxargs    maxargsex    maxargsexlst 是查找A_printStm





写一个函数
void interp(A_stm);

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

typedef struct IntAndTable{
	int i;
	Table_ t;
}*IntAndTable_;

Table_ Table(Table_ t, string id, int value);
int lookUp(Table_ t, string id);
Table_ updateTable(Table_ t, string id, int newResult);
void interp(A_stm stm);
Table_ interpStm(A_stm stm, Table_ t);
int getOpResult(int x, int y, int kind);
IntAndTable_ interpExp(A_exp exp, Table_ t);
IntAndTable_ intAndTable(int i, Table_ t);
IntAndTable_ interpAndPrint(A_expList expLst, Table_ t);


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

//返回id 所对应的值
int lookUp(Table_ t, string id)
{
	Table_ curr = t;
	while (curr != NULL)
	{
		if (curr->id == id)
			return curr->value;
		curr = curr->tail;
	}
	assert(!curr);
	return 0;
}
//将变量的值插入在表的开头
Table_ updateTable(Table_ t, string id, int newResult)
{
	Table_ temp = Table(t, id, newResult);
	return temp;
}


void interp(A_stm stm)
{
	interpStm(stm,NULL);
}

Table_ interpStm(A_stm stm,Table_ t)
{
	if (stm != NULL)
	{
		switch (stm->kind)
		{
		case A_compoundStm:
			t = interpStm(stm->u.compound.stm1, t);
			t = interpStm(stm->u.compound.stm2, t);
			break;
		case A_assignStm:
		{
			IntAndTable_ intTable = intAndTable(0, t);
			intTable = interpExp(stm->u.assign.exp, t);
			t=updateTable(t, stm->u.assign.id, intTable->i);
			break;
		}
		case A_printStm:
			interpAndPrint(stm->u.print.exps,t);
			break;
		}
	}
	return t;
}
//解释并打印表达式结果
IntAndTable_ interpAndPrint(A_expList expLst, Table_ t)
{
	assert(expLst);
	IntAndTable_ intTable = intAndTable(0,t);
	while (expLst->kind == A_pairExpList)
	{
		intTable = interpExp(expLst->u.pair.head, intTable->t);
		expLst = expLst->u.pair.tail;
	}
	intTable = interpExp(expLst->u.last, intTable->t);  
	printf("%d\n", intTable->i);
}

IntAndTable_ intAndTable(int i, Table_ t)
{
	IntAndTable_ temp = (IntAndTable_)checked_malloc(sizeof(*temp));
	temp->i = i;
	temp->t = t;
	return temp;
}

IntAndTable_ interpExp(A_exp exp, Table_ t)
{
	if (exp == NULL)
	{
		return NULL;
	}
	else
	{
		IntAndTable_ intTable = intAndTable(0, t);
		switch (exp->kind)
		{
		case A_idExp:
			intTable->i = lookUp(t, exp->u.id);
			break;
		case A_numExp:
			intTable->i = exp->u.num; 
			break;
		case A_opExp:
			intTable= interpExp(exp->u.op.left, t);
			int i = intTable->i;
			intTable = interpExp(exp->u.op.right, intTable->t);
			int j = intTable->i;
			intTable->i = getOpResult(i,j,exp->u.op.oper);
			break;
		case A_eseqExp:
			t = interpStm(exp->u.eseq.stm,t);
			intTable = interpExp(exp->u.eseq.exp, t);
			break;
		}
		return intTable;
	}
}

int getOpResult(int x, int y,int kind)
{
	switch (kind)
	{
	case A_plus:return x + y;
	case A_minus:return x - y;
	case A_div:return x / y;
	case A_times:return x*y;
	}
}

interpExp(A_exp exp,Table_ t) 是对exp的解释 返回表达式的值并更新映射表

为了在赋值语句的解释中不产生其他副作用,赋值语句将不对已有变量做修改 而是利用updateTable将新值更新到映射表