Bea*_*ear 1 scheme functional-programming racket
我是计划新手,在使用 car 和 cdr 方面遇到困难。我在 ast 中有一个 AST 字符串文字。
(define ast '(program
((assign (var i int) (call (func getint void int) ()))
(assign (var j int) (call (func getint void int) ()))
(while (neq (var i int) (var j int))
((if (gt (var i int) (var j int))
((assign (var i int) (minus (var i int) (var j int))))
((assign (var j int) (minus (var j int) (var i int)))))))
(call (func putint int void) ((var i int)))))
)
Run Code Online (Sandbox Code Playgroud)
我知道汽车返回ast的头。所以
(car ast)
Run Code Online (Sandbox Code Playgroud)
返回'程序。
我很困惑如何使用 car 和 cdr 从 ast 获取字符串,例如 'assign、'while、'if 和 'call。
您需要了解如何构建配对和列表,请参阅The Racket Reference:
一对恰好组合了两个值。第一个值通过 car 过程访问,第二个值通过 cdr 过程访问。对是不可变的。
列表是递归定义的:它要么是常量 null,要么是第二个值是列表的对。
基本上每对都由(x . y)
两个元素组成 -car
让我们得到 xcdr
得到我们 y。
请注意,x和y 都可以是对或列表本身,就像您的 AST 一样,即(来自相同的引用):
> (define lst1 (list 1 2 3 4))
>lst1
'(1 2 3 4)
Run Code Online (Sandbox Code Playgroud)
请注意,'(1 2 3 4)
实际上是:(1 . ( 2 . ( 3 . ( 4 . ())))
<-- 了解方案中的实现非常重要。
> (car lst1)
1
> (cdr lst1)
'(2 3 4)
> (car (cdr lst1))
2
Run Code Online (Sandbox Code Playgroud)
另一种链接 car 和 cdr 调用的方法(从右读): cadr 表示(cdr lst)
然后应用于car
答案 => (car (cdr lst))
==(cadr lst)
> (cdddr lst1)
'(4)
> (cadddr lst1)
4
> (define lst2 (list (list 1 2) (list 3 4)))
>lst2
'((1 2) (3 4))
Run Code Online (Sandbox Code Playgroud)
==( ( 1 . ( 2 . ()) ) . ( 3 . ( 4 . () )))
> (car lst2)
'(1 2)
>(cdr lst2)
'((3 4))
Run Code Online (Sandbox Code Playgroud)
这实际上是((3 . (4 . () ) ) . () )
====((3 4) . ())
((3 4))
您没有问,但我假设您将遍历树/列表。最终你将不得不使用递归进行遍历(除非使用现阶段不适合的高级方法,即准备好时检查 CPS),如下所示:
(define runner
(lambda (tree)
(if (null? tree)
null
(let ((first_element (car tree))
(rest_of_tree (cdr tree)))
;body:
;do some logic like:
;if first is list call runner on it:
;(runner rest_of_tree)
;possibly chain answer of logic and call together
;else check/return string is there (recognize tree root)
))))
Run Code Online (Sandbox Code Playgroud)
希望这对欢迎提问有所帮助。