当前位置: 首页 > 网络应用技术

我去世后,伯克利·耶德斯(Berkeley Yyds),在Python上写一位LISP口译员(4)

时间:2023-03-07 21:56:30 网络应用技术

  大家好,我死了,我是liang tang。这篇文章在公共帐户中开始

  让我们继续肝脏伯克利CS61A的计划项目,这是该项目的第四部分。如果遗漏了先前的内容,您可以翻转历史记录。

  课程

  项目原始文档

  github

  在上一篇文章中,我们完全意识到了方案解释器的功能。在本文中,我们使用刚刚开发的口译员来解决一些问题。

  我们可以注意到,不仅方案解释器本身是递归过程,而且在处理其他递归问题方面也非常灵活。您将实现文件中的接下来的几个问题

  尽管您已经完成了计划解释器的开发,但可能会有潜在的错误。因此,建议先使用通用Sheme解释器,然后使用新开发的解释器进行测试以确保您的代码可以正常运行。

  在实施过程中,它收到一个并返回二进制。

  该二进制中的每个元素都已解决并值得组合,例如:

  开发完成后,测试:

  答案中也有一个周期语法,如果使用周期,它将更简单。但是,教师讲座的内容不包括周期,因此我们只能使用递归进行处理。

  如果您想递归处理,您将不可避免地会找到一个问题,即,该功能的功能只是一个列表,输出必须提出上下竞标。但是问题是我们无法获得当前变量当我们恢复时。因此,我们可以认为只能解决一个参数递归,并且至少需要两个参数。

  没有更改原始函数的签名,唯一的方法是使用高级别函数。在函数中定义了一个函数,然后我们调用此函数。

  递归的逻辑并不困难。您可以参考代码,只需重复即可。

  给定的实施过程表示总金额,表明我们的面值和面值是按顺序排序的。我们希望返回所有方式以形成总面值。

  例如,10,是(25、10、5、1),然后答案是:

  另一个示例是5,是(4、3、2、1),答案是:

  在实施过程中,您需要使用辅助函数:。要实现函数,需要构建的过程。接种元素和列表,将此元素插入列表中的每个元素作为开始。

  例如:

  开发后测试:

  答案是首先实现,此功能逻辑并不复杂。

  遍历的每个元素,然后缝制元素。主题提醒我们我们可以使用构建-in。此过程将对列表的所有元素应用一定的过程。

  因此,显然,我们只需要实现一个可以将其缝合到元素的函数,然后称其为元素,并且不需要递归即可。

  在这个问题之前,我们已经在作业4中写了类似于Python。我不知道您是否有印象。

  但是,当时需要所有可能的数量,而面额的极限略有不同。它不是固定的几种类型,而是给定的仪表M,所有面部值小于相等的面部值,当时代码:

  我们对此进行了一些更改,并编写Python的版本:

  我需要做的下一步是将上述Python代码转换为LISP以实现。实际上,只要可以写Python,LISP就是相同的。尽管语法不同,但核心原理是相同的。

  由于LISP也参与了参数的计算,因此它看起来将非常非常漫长。因此,在这里,我们使用语句来简化代码的写作。

  在方案语言中,源代码也是一个数据。每个非本地表达式可以写为方案列表。因此,我们可以实现一个过程,并且可以生成其他程序,例如方案列表。

  重写代码非常有用。例如,我们只能实现解释器的核心功能,然后将其他功能转换为解释器支持的核心组件以运行。这可以简化解释器的开发。我不知道这是否是LISP语言设计逻辑的一部分,但这对我来说确实很棒。这个设计想法真的很聪明。

  例如,陈述等同于表达式,它们将根据当前环境创建新的语句。您可以在问题15中回顾语法的定义。

  这两个表达式可以在以下图中表示:

  通过此规则实施该过程,它将将特殊类型转换为表达式。

  如果我们有一个表达并将其传递到这个过程中,那么我们将获得等效的表达,例如:::

  如果要实现该函数,则必须能够感知方案语法。由于方案表达式是递归嵌套的,因此它也必须是递归的。

  实际上,结构和函数相似,但它们以方案语言实现。提示:单位元素包括数字,布尔,尼尔和符号。

  提示:您需要首先实施该过程,该过程非常有帮助

  在编码之前,首先回答问题,以确保问题理解正确

  编码后,测试:

  答案是首先查看该过程。该方法的输入是n x2的两个维度列表。结果我们返回的结果是2 x n的两个维列表。它等同于制定数据等同。

  因此,我们要做的是取出每行中的第一和第二元素以形成两个列表,然后将这两个列表串在一起。

  如果没有使用该周期,就会感觉无法开始。不幸的是,我们提醒我们可以使用它。

  代码显示如下:

  在那之后

  这个问题老师为我们建立了一个框架,并列出了我们需要考虑的所有情况。我们只需要依次实现每种情况的处理方法,这被认为可以减少我们的困难。

  让我们看一下这些情况:

  (atom?expr)表达式是一个,即数字,符号,零或布尔,它不再是评估的结果,您可以直接返回。

  (引用?expr)表达是一个陈述,它与这个问题无关。您无需进行任何处理,并直接返回。

  (或(lambda?expr)(定义?expr))表达式是lambda或define语句,不能直接确定它是否是相关的。由于定义和lambda语句都可以进一步嵌套,因此嵌套语句可能包含LET语句,因此我们必须恢复嵌套的部分。

  老师使用该句子来提取我们,并且。

  (让?expr)我们必须处理的核心键,其中有两个部分,一个是另一个。LET看陈述的语法。它首先定义了某些符号和价值的映射,然后定义了符号的计算方法。我们要做的是将符号和值提取为正式和lambda过程的参数,而主体为正文lambda过程。

  但是,这三个之间可能存在嵌套更麻烦,因此我们需要使用递归。

  否则是其他情况。由于我们只判断,我们需要继续调用递归并判断后来的内容。在这里,我直接使用该过程

  更多详细信息参考代码:

  在这一点上,这三个问题已经完成。

  尽管只有三个问题,但这确实很大。不仅仅是计划的语言,而且口译员的项目进一步加深了印象。可以说,它充满了收获。这次,大作业确实是非凡的,因此建议每个人都尝试。

  原始:https://juejin.cn/post/7096374133377728520