Bulid Own Lisp chapter7 C语言项目练习笔记

本文是关于Bulid Own Lisp项目的C语言实践笔记,重点讲解第七章的内容——Evaluation。介绍了如何理解解析结构mpc_ast_t,计算表达式节点总数,以及如何通过递归求解算式的值(涉及加减乘除操作)。在实现过程中,利用了atoi()、strstr()和strcmp()等库函数,根据节点标签判断表达式类型,进行相应计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Bulid Own Lisp C语言项目练习笔记

chapter 7 Evaluation

前六章的学习主要围绕C语言的基础语法以及一个mpc库文件的使用,编写了一个简单的pasring.c文件实现Polish Notation语法解析。第七章实现表达式的计算。

认识解析结构 mpc_ast_t
typedef struct mpc_ast_t{
	char* tag;
	char* contents
	mpc_state_t state;
  	int children_num;
  	struct mpc_ast_t** children;
} mpc_ast_t;
获取总结点个数(类似于求树的总结点数)
int getChildNums(Tree* p){
	if(p->childNums == 0)	return 1;
	if(p->childNums >= 1){
		int thisTotal = 1;
		for(int i = 0; i < childNums; i ++){
			thisTotal += getChildNums(p->child[i]);
		}
		return thisTotal;
	}
	//给定程序出口,确保程序的健壮性
	return 0;
}
Evaluation 递归求解算式的值(+ - * /)

引入三个库函数 atoi(), strstr(), strcmp()
如果所属标签含有“number”,直接将字符串转化为数字
如果该标签含有“expr”又不是“number” 则一定是一个(< operator > < expr >)的结构,此时第一个孩子child[0]一定是char类型的左括号,我们直接读取第二个孩子child[1]进行递归调用,依次类推,然后逐次计算,最后得到表达式的值。

long eval(mpc_ast_t* t) {

  /* If tagged as number return it directly. */
  if (strstr(t->tag, "number")) {
    return atoi(t->contents);
  }

  /* The operator is always second child. */
  char* op = t->children[1]->contents;

  /* We store the third child in `x` */
  long x = eval(t->children[2]);

  /* Iterate the remaining children and combining. */
  int i = 3;
  while (strstr(t->children[i]->tag, "expr")) {
    x = eval_op(x, op, eval(t->children[i]));
    i++;
  }

  return x;
}

其中的eval_op函数就是如下的一个四则运算函数。

long eval_op(long x, char* op, long y) {
  if (strcmp(op, "+") == 0) { return x + y; }
  if (strcmp(op, "-") == 0) { return x - y; }
  if (strcmp(op, "*") == 0) { return x * y; }
  if (strcmp(op, "/") == 0) { return x / y; }
  return 0;
}

运行效果如下

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值