2012-02-19 8 views
4

(3 + 5)のようなユーザー式を読み込んで実行する再帰的な定義を作成しようとしています。算術記号の1つの問題を除いて、すべてが機能しています。ユーザー入力から式を評価する際の問題

私は単純な例では、エラーを再現するために管理:

(define v '(1 + 3)) 

((cadr v) 2 4) 

(cadr v)+シンボルですが、いくつかの理由のために手順が続く二つの引数で実行することはできません。何か不足していますか?

+2

シンボル「+」は関数 '+'と同じではありません。 OscarとSoulcheckの説明のように 'eval'を使って、後者を後者に変えてください。 –

+1

「eval」は正しい選択ではないと思います。 –

答えて

3

は、私はそれがだと思うので

(cadr v) 

戻り'+ない+(リテラル+ない+機能)。

引数に適用する前に評価する必要があります。

これは動作するはずです:

((eval (cadr v)) 2 4) 
^evaluates the '+ to + 

編集 これは、対話モードでラケットで働いていました。

(スクリプト)私は、違いは何本当にわからないんだけど、それはラケットにR5RSモードで働かせた:

#lang r5rs 

;required by r5rs 
(define user-initial-environment (scheme-report-environment 5)) 

(define v '(1 + 2)) 

;eval expects a quoted expression 
;(it seems that if it's a function it has to have arguments too) 
;and evaluation environment. 
((eval (cadr v) user-initial-environment) 2 4) 
+0

私はevalを使ってみましたが、期待通りに動作しません。私は自分の言語をR5RSに設定しているのでしょうか? –

+0

私は新しいエラーが発生しました。プロシージャのmeval:2つの引数が必要です。1:+ –

+0

@OrieStoneごめんなさいラケットとクロージャーで試してみました。 evalはそこでは異なった働きをします。 – soulcheck

0

試してみてくださいこの:

(define v '(1 + 3)) 

(let ((operator (eval (cadr v))) 
     (operand1 (car v)) 
     (operand2 (caddr v))) 
    (apply operator (list operand1 operand2))) 
0

あなたはそれこれを行うことができますガイルでevalと方法:

(define (infix-eval v) 
    (eval (list (cadr v)(car v)(caddr v)) 
     (interaction-environment))) 

> (infix-eval '(1 + 2)) 
3 

よりもむしろinteraction-environmentを使用して、あなたは別のenvを供給できます標準化されたSchemeにはない他のシンボルを定義することもできます。(7 % 3)(2^6)のような式も使えます。

1

他の人が指摘しているように、問題は、作成したリストに関数plusではなくシンボルplusが含まれていることです。

これは、 '(a b)がアンバインドされた識別子エラーを通知するのではなく、2つのシンボルのリストを返すのと同じ理由です。引用符は、データ識別子ではなく、正当な識別子がシンボルとして解釈される「データ言語」で始まります。

もちろん、あなたがそれについて何をすべきかという疑問があります。ここでは「eval」の使用を提案しています。 Matthew Flattがhis blog post on the topicにエレガントに取り込むと思う理由のため、これはおそらく悪い考えです。

代わりに、単純なマッピング関数を記述してください。ここで私はそれを書く方法です。あなたが私のコードを割り当てに使用する場合は、私に信用してください:)。

#lang racket 

;; a mapping from symbols to operators 
(define operator-hash 
    (hash '+ + 
     '- - 
     '* *)) 
;; ... and whatever other operators you want. 

;; example of using it: 
(hash-ref operator-hash '+) ;; ==> +