方案的简单步进代码
simple stepper code for scheme
我正在使用带有列表缩写的初级语言。
我已经在以下工作了 3 天,但无济于事。
我需要编写一个名为 step 的函数来消耗
以 AExp 的形式设计表达式 (ex),并生成一个 AExp,表示 ex
的跟踪中的下一步
示例:
如果 (ex) ex1 是
(+ 5 (* (+ 1 2 3) 2 (* 4 1)) 7)
然后(步骤 ex1)产生:
(+ 5 (* 6 2 (* 4 1)) 7).
到目前为止,这就是我所做的:
(define (step ex)
(cond [(number? ex) (list ex)]
[else
(cond
[(symbol=? (ainode-op ex) '+)
(cons(ainode-op ex)
(list-eval1 (ainode-args ex)))]
[(symbol=? (ainode-op ex) '*)
(cons(ainode-op ex)
(list-eval2 (ainode-args ex)))])]))
(define (list-eval1 exlist)
(cond [(empty? exlist)(list 0)]
[else (append(step (first exlist))
(list-eval1 (rest exlist)))]))
(define (list-eval2 exlist)
(cond [(empty? exlist)(list 0)]
[else (append(step (first exlist))
(list-eval2 (rest exlist)))]))
但是我的功能没有按我想要的方式工作。
有帮助吗?
这是一个提示。首先你应该注意,当一个表达式只包含一个符号和一个或多个数字时,它可以被评估。所以你可以定义一个辅助函数 evaluable?
当它的参数是一个可以计算的表达式时 returns 为真。例如:
(define (evaluable? exp)
(cond ((null? exp) #t)
((list? (car exp)) #f)
(else (evaluable? (cdr exp)))))
然后您可以定义 step
来计算第一个(子)表达式的可计算值并重建表达式的其余部分。在伪代码中,是这样的:
(define (step exp)
(cond ((number? exp) exp)
((evaluable exp) (evaluate exp))
(else (... make a recursive descent in the current expression by rebuilding the external expression...))))
当然 evaluate
应该评估包含运算符和数字操作数的列表。
编辑
如何下楼? step
的最后一行可能是这样的:
(else (cons (car exp) (step-operands (cdr exp))))))
注意,我们使用cons
来重建与car
相同的结构,并通过函数step-operands
处理操作数的结果,找到第一个可以重写的表达式的操作数。由于这是作业,我只会给你一个这样的函数的草图(注意我假设列表 operands
至少有一个元素,不检查表达式的正确性):
(define (step-operands operands)
(cond ((number? (car operands)) (cons (car operands) (... (cdr operands))))
(else (cons (... (car operands))(cdr operands)))))
您只需用适当的函数填充点(并思考发生了什么!)
我正在使用带有列表缩写的初级语言。 我已经在以下工作了 3 天,但无济于事。
我需要编写一个名为 step 的函数来消耗 以 AExp 的形式设计表达式 (ex),并生成一个 AExp,表示 ex
的跟踪中的下一步示例:
如果 (ex) ex1 是
(+ 5 (* (+ 1 2 3) 2 (* 4 1)) 7)
然后(步骤 ex1)产生: (+ 5 (* 6 2 (* 4 1)) 7).
到目前为止,这就是我所做的:
(define (step ex)
(cond [(number? ex) (list ex)]
[else
(cond
[(symbol=? (ainode-op ex) '+)
(cons(ainode-op ex)
(list-eval1 (ainode-args ex)))]
[(symbol=? (ainode-op ex) '*)
(cons(ainode-op ex)
(list-eval2 (ainode-args ex)))])]))
(define (list-eval1 exlist)
(cond [(empty? exlist)(list 0)]
[else (append(step (first exlist))
(list-eval1 (rest exlist)))]))
(define (list-eval2 exlist)
(cond [(empty? exlist)(list 0)]
[else (append(step (first exlist))
(list-eval2 (rest exlist)))]))
但是我的功能没有按我想要的方式工作。 有帮助吗?
这是一个提示。首先你应该注意,当一个表达式只包含一个符号和一个或多个数字时,它可以被评估。所以你可以定义一个辅助函数 evaluable?
当它的参数是一个可以计算的表达式时 returns 为真。例如:
(define (evaluable? exp)
(cond ((null? exp) #t)
((list? (car exp)) #f)
(else (evaluable? (cdr exp)))))
然后您可以定义 step
来计算第一个(子)表达式的可计算值并重建表达式的其余部分。在伪代码中,是这样的:
(define (step exp)
(cond ((number? exp) exp)
((evaluable exp) (evaluate exp))
(else (... make a recursive descent in the current expression by rebuilding the external expression...))))
当然 evaluate
应该评估包含运算符和数字操作数的列表。
编辑
如何下楼? step
的最后一行可能是这样的:
(else (cons (car exp) (step-operands (cdr exp))))))
注意,我们使用cons
来重建与car
相同的结构,并通过函数step-operands
处理操作数的结果,找到第一个可以重写的表达式的操作数。由于这是作业,我只会给你一个这样的函数的草图(注意我假设列表 operands
至少有一个元素,不检查表达式的正确性):
(define (step-operands operands)
(cond ((number? (car operands)) (cons (car operands) (... (cdr operands))))
(else (cons (... (car operands))(cdr operands)))))
您只需用适当的函数填充点(并思考发生了什么!)