0

balanced文字列を取り、文字列内のかっこのバランスが取れている場合にのみ true を返す再帰関数を定義しようとしています。

私が書いた elisp コードは、Odersky によって Coursera クラスのために私が書いた Scala コードに基づいています。

  ;; check if expr (list of chars of some expression) is balanced
  (defun balanced (expr)
    (defvar lparen (string-to-char "("))
    (defvar rparen (string-to-char ")"))

    (defun is-open (c) (eq lparen c))
    (defun is-close (c) (eq rparen c))
    (defun is-empty (ls) (eq ls nil))
    (defun is-matching (l r) (and (is-open l) (is-close r)))

    (defun is-balanced (list stack)
      (cond ((is-empty list) (is-empty stack))

      ((is-open (car list))
       (is-balanced (cdr list) ;; 'push' open-paren onto stack
        (cons (car list) stack)))

      ((is-close (car list))

       (if (is-empty stack) nil
         (and 
          (is-balanced (cdr list) (cdr stack))
          (is-matching (car stack) (car list)))))

      (is-balanced (cdr list) (cdr stack))))
  is-balanced

私は Lisp 対話モードなので、Ctrl-J を使用して上記のdefunステートメントを評価しました。

次に、これを評価しようとすると:

  (balanced "(balanced nil nil)")

void 変数エラーが発生します。

Debugger entered--Lisp error: (void-variable is-balanced)
    balanced("(balanced nil nil)")
    (progn (balanced "(balanced nil nil)"))
    eval((progn (balanced "(balanced nil nil)")) t)
    eval-last-sexp-1(t)
    eval-last-sexp(t)
    eval-print-last-sexp()
    call-interactively(eval-print-last-sexp nil nil)
    recursive-edit()
    debug(error (void-variable is-balanced))
    balanced("(balanced nil nil)")
    (progn (balanced "(balanced nil nil)"))
    eval((progn (balanced "(balanced nil nil)")) t)
    eval-last-sexp-1(t)
    eval-last-sexp(t)
    eval-print-last-sexp()
    call-interactively(eval-print-last-sexp nil nil)
    recursive-edit()

関数はそれ自体を認識していないようです。何が間違っていますか?

4

2 に答える 2

3

関数を実行すると、次(balanced ...)のようになります。

  1. 最初に 2 つのグローバル変数を定義します
  2. 他の 5 つの関数を定義します。
  3. 変数にアクセスしますis-balanced

ステップ 3. の終了直後に発生し(defun is-balanced (list stack) ... ))))ます。

(defun balanced (expr)
    ...

    (defun is-balanced (list stack)
      ...
      (is-balanced (cdr list) (cdr stack))))
  is-balanced ;; <= here!

しかし、そのような変数を定義していません。同じ名前の関数を定義しましたが、Emacs Lisp の変数であるかのように関数オブジェクトにアクセスできません。こちらもご覧ください。という名前の変数がないis-balancedため、エラー メッセージが表示されます。

(とは言っても、コードの残りの部分については批判すべきことがたくさんあります。まず、defuns の中にs を入れることで、を呼び出すたびに関数defunを再定義していることに注意してください。同様に、defvar はグローバル変数を定義しているので、おそらく関数本体の外に移動したいでしょう. それとも、代わりに使用するつもりでしたか? 本当にグローバル値が必要な場合は、その方が適切かもしれません.)is-*(balanced ...)(let ...)(defconst...)

于 2012-11-04T03:47:07.047 に答える
-1

問題は、式の最後の要素が...condでラップされていないことです:(t)

正しくない:

    (is-balanced (cdr list) (cdr stack))

正しい

    (t (is-balanced (cdr list) (cdr stack)))

これが必要な理由は、最後の式が当てはまるはずだからelseです。

于 2012-11-03T23:42:20.093 に答える