Scheme 如何创建方案定义以解析复合S表达式并将其转换为标准形式

Scheme 如何创建方案定义以解析复合S表达式并将其转换为标准形式,scheme,racket,mit-scheme,Scheme,Racket,Mit Scheme,给定一个形式为:*3+x y的表达式,我如何计算该表达式以使其形式为+*3 x*3 y?注:在一般情况下,3是任何常数,x或y可以是单变量项或其他s表达式,例如+2x 如何编写一个lambda表达式来递归计算原子项?在原始表达式中,确定它们是常数还是项?在一个术语的情况下,需要再次递归地对其求值,以确定该术语列表中每个项目的类型 同样,对我来说,问题的关键是定义的递归内核 很明显,我需要一个基本情况,一旦我到达表达式最深处的最后一个单原子,就可以确定。然后递归地进行备份,根据规则以适当的形式构建

给定一个形式为:*3+x y的表达式,我如何计算该表达式以使其形式为+*3 x*3 y?注:在一般情况下,3是任何常数,x或y可以是单变量项或其他s表达式,例如+2x

如何编写一个lambda表达式来递归计算原子项?在原始表达式中,确定它们是常数还是项?在一个术语的情况下,需要再次递归地对其求值,以确定该术语列表中每个项目的类型

同样,对我来说,问题的关键是定义的递归内核

很明显,我需要一个基本情况,一旦我到达表达式最深处的最后一个单原子,就可以确定。然后递归地进行备份,根据规则以适当的形式构建表达式


从java/C++背景来看,我很难理解如何在语法上做到这一点。

< p>你需要解决你的问题。首先,我将遵循HtDP www.HtDP.org方法。你的意见是什么?你能精确地说明它们吗?在这种情况下,这些输入将是自引用的

然后,指定输出表单。事实上,您上面的文本在这方面有点模糊:我想我知道您的输出形式是什么样子,但我不完全确定

接下来,编写一组测试。这些应基于输入术语的结构;从最简单的开始,然后从那里向上工作


一旦有了一组好的测试,实现函数应该非常简单。如果你陷入困境,我很乐意帮助你

你需要解决你的问题。首先,我将遵循HtDP www.HtDP.org方法。你的意见是什么?你能精确地说明它们吗?在这种情况下,这些输入将是自引用的

然后,指定输出表单。事实上,您上面的文本在这方面有点模糊:我想我知道您的输出形式是什么样子,但我不完全确定

接下来,编写一组测试。这些应基于输入术语的结构;从最简单的开始,然后从那里向上工作


一旦有了一组好的测试,实现函数应该非常简单。如果你陷入困境,我很乐意帮助你

让我们从最初的问题快速绕道到一些稍微相关的问题。假设您得到了以下条件:您想编写一个计算器,它接受像*3hello这样的字符串构建表达式,并将其计算为hellohello。我们希望使其发挥作用的其他例子包括

(+ "rock" (+ (* 5 "p") "aper"))     ==> "rockpppppaper"
(* 3 (+ "scis" "sors"))             ==> "scissorsscissorsscissors"
为了解决这样的问题,我们需要精确地指定输入的形状。本质上,我们想要描述一种数据类型。我们会说我们的输入是字符串表达式。让我们简称它们为str exprs。然后让我们定义str-expr的含义

str expr是:

+ * 通过这个符号,我们试图说str-expr都适合这三种形状中的一种

一旦我们对数据的形状有了很好的了解,我们就有了编写处理str-expr的函数的更好指南:它们必须对这三个备选方案进行案例分析

;; A str-expr is either:
;;      a plain string, or
;;     (+ str-expr str-expr), or
;;     (* number str-expr)

;; We want to write a definition to "evaluate" such string-expressions.

;; evaluate: str-expr -> string
(define (evaluate expr)
  (cond
    [(string? expr)
     ...]
    [(eq? (first expr) '+)
     ...]
    [(eq? (first expr) '*)
     ...]))
我们要填写的地方是“…”号

实际上,我们知道如何更多地填写“…”:我们知道在第二和第三种情况下,内部部分本身就是str expr。这些是可能再次发生的主要点:因为我们的数据是用自身的方式描述的,所以处理这些数据的程序也可能需要引用它们自己。简言之,处理str expr的程序几乎肯定会遵循以下形状:

(define (evaluate expr)
  (cond
    [(string? expr)
     ... expr 
     ...]
    [(eq? (first expr) '+)
     ... (evaluate (second expr))
     ... (evaluate (third expr))
     ...]
    [(eq? (first expr) '*)
     ... (second expr) 
     ... (evaluate (third expr))
     ...]))
这一切都不需要做任何实际工作:我们可以计算出这一部分,因为这是数据的形状告诉我们的。填充“…”的其余部分以使这一切都有效,事实上还不算太坏,特别是当我们也考虑我们已经做过的测试用例时。
这是一种标准的数据分析/案例分析,是你问题的核心,这是一个广泛涵盖的课程,如。这不是特定于Scheme或Racket的:您可以在Java中进行相同类型的数据分析,并且您可以在许多其他地方看到相同类型的方法。在Java中,用于案例分析的低级机制可能会有所不同,可能是使用动态分派,但核心思想都是相同的。你需要描述数据。一旦有了数据定义,就可以使用它来帮助您勾勒出处理该数据所需的代码外观。使用测试用例对如何填充草图进行三角剖分。

让我们从原始问题快速绕道到一些稍微相关的问题。假设你得到以下条件:你想写一个e 赋值器,它接受像*3hello这样的字符串构建表达式,并将其求值为hellohello。我们希望使其发挥作用的其他例子包括

(+ "rock" (+ (* 5 "p") "aper"))     ==> "rockpppppaper"
(* 3 (+ "scis" "sors"))             ==> "scissorsscissorsscissors"
为了解决这样的问题,我们需要精确地指定输入的形状。本质上,我们想要描述一种数据类型。我们会说我们的输入是字符串表达式。让我们简称它们为str exprs。然后让我们定义str-expr的含义

str expr是:

+ * 通过这个符号,我们试图说str-expr都适合这三种形状中的一种

一旦我们对数据的形状有了很好的了解,我们就有了编写处理str-expr的函数的更好指南:它们必须对这三个备选方案进行案例分析

;; A str-expr is either:
;;      a plain string, or
;;     (+ str-expr str-expr), or
;;     (* number str-expr)

;; We want to write a definition to "evaluate" such string-expressions.

;; evaluate: str-expr -> string
(define (evaluate expr)
  (cond
    [(string? expr)
     ...]
    [(eq? (first expr) '+)
     ...]
    [(eq? (first expr) '*)
     ...]))
我们要填写的地方是“…”号

实际上,我们知道如何更多地填写“…”:我们知道在第二和第三种情况下,内部部分本身就是str expr。这些是可能再次发生的主要点:因为我们的数据是用自身的方式描述的,所以处理这些数据的程序也可能需要引用它们自己。简言之,处理str expr的程序几乎肯定会遵循以下形状:

(define (evaluate expr)
  (cond
    [(string? expr)
     ... expr 
     ...]
    [(eq? (first expr) '+)
     ... (evaluate (second expr))
     ... (evaluate (third expr))
     ...]
    [(eq? (first expr) '*)
     ... (second expr) 
     ... (evaluate (third expr))
     ...]))
这一切都不需要做任何实际工作:我们可以计算出这一部分,因为这是数据的形状告诉我们的。填充“…”的其余部分以使这一切都有效,事实上还不算太坏,特别是当我们也考虑我们已经做过的测试用例时。
这是一种标准的数据分析/案例分析,是你问题的核心,这是一个广泛涵盖的课程,如。这不是特定于Scheme或Racket的:您可以在Java中进行相同类型的数据分析,并且您可以在许多其他地方看到相同类型的方法。在Java中,用于案例分析的低级机制可能会有所不同,可能是使用动态分派,但核心思想都是相同的。你需要描述数据。一旦有了数据定义,就可以使用它来帮助您勾勒出处理该数据所需的代码外观。使用测试用例对如何填写草图进行三角剖分。

非常好的解释。比你好多了。解释得很好。比你好多了。很好的参考资料。我去看看。非常感谢。很好的参考资料。我去看看。非常感谢。