解析并定义文字

时间:2014-03-15 18:27:30

标签: algorithm stored-procedures scheme racket

我有一个由这个方法定义的文字:

  (define right-hand-rule-prg
      '(
        (procedure start
          ( turn-right
            (if wall?
               ( turn-left
                 (if wall?
                     (turn-left
                         (if wall?
                            turn-left
                            step
                         )
                     )
                     step
                  )
               )
               step  
            )
            put-mark
            start
          )
        )   
        (procedure turn-right (turn-left turn-left turn-left turn-left turn-left))
      )
    )

我必须解析并定义过程startturn-right

我设法通过名称使用此方法获取过程:

(define (get-procedure procedure program)
  (if (null? program)
      '(procedure-not-found)
      (if (eq? procedure (cadar program))
          (caddar program)
          (get-procedure procedure (cdr program))
          )
      )  
  )

所以在打电话后我得到了:

(get-procedure 'turn-right right-hand-rule-prg)
'(turn-left turn-left turn-left turn-left turn-left)

但不知何故,我必须设法找到所有程序名称并定义此程序,如下所示:

(define (name-of-procedure) (get-procedure name-of-procedure-program))

我该怎么做?

1 个答案:

答案 0 :(得分:2)

我不确定我理解动机/背景,你在这里想做什么。但是你所勾勒出来的东西似乎“正在削减粮食”。

在Scheme和Racket中,函数是一流的对象 - 您可以将它们放在列表中,传递它们,等等。它会更简单,并且“用粒度切割”来翻转它:像往常一样定义函数,并使right-hand-rule-prg成为函数的list

(define (turn-left)
  ...)

(define (turn-right)
  ...)

(define (start)
  ...)

(define right-hand-rule-prg
  (list start turn-right))

要执行right-hand-rule-prg,您可以执行以下操作来运行列表中的过程:

(for ([f (in-list right-hand-rule-prg)])
  (f))

请注意right-hand-rule-prg之类的内容是list,可以在运行时构建或修改。所以你可以让...用户修改它,或从文件中读取它。然而,构建块 - 像startturn-right这样的原语 - 通常是定义的函数。

如果真正需要在运行时定义基元,那么可以在用户提供的s-expression上使用eval。但这是最不可取的选择。您应该尽量避免使用eval。如果您希望用户在运行时提供任意Racket功能,最好使用dynamic-require之类的功能。或者更好的是,反转控件 - 您的代码是用户程序的库(而不是您在运行时使用用户代码的代码)。