2012-10-12 16 views
7

は、誰かが私の構文を使用して言語のocamlの通訳を構築するいくつかの助けを与えることができます:OCamlのインタプリタ

Prog ::= Def* Expr 
Def ::= id id* = Expr 
Expr ::= int | id | Expr '+' Expr | Expr '*' Expr | id Expr* | if Expr then Expr else Expr 

は、これまでのところ、私はこれをしなかった:

type expr = I of int 
| Id of string 
| Add of expr * expr 
| Multiply of expr * expr 
| If of expr * expr * expr 

let rec evaluate = function 
| I n -> n 
| Add(e1,e2) -> evaluate e1 + evaluate e2 
| Multiply(e1,e2) -> evaluate e1 * evaluate e2 
| If(a,b,c) -> if evaluate a<>0 then evaluate b else evaluate c 

これは何かいいですか?

答えて

6

あなたの文法では、単一のIDは、生産Expr ::= idまたはExpr ::= id Expr*と一致させることができます。言い換えれば、nullary関数アプリケーション(関数アプリケーションと一致すると仮定した場合、id Expr*と仮定します)と変数を区別する方法はありません。たぶんid Expr+を意味していたかもしれません(無限機能アプリケーションを許可しない)。

あなたの既存のコードは正常に見えるが、それは不完全です:あなたは、機能のアプリケーションを表し、コンストラクタが欠落している、すなわち

あなたexprタイプは、文法のid Expr*生産のためのコンストラクタが欠落しています。 1つを追加して、それに対応するケースをevaluate関数に追加する必要があります。

Idコンストラクタの場合は、関数ではケースがありません。その場合は、識別子から値(int)へのマッピングで、指定された識別子の値を検索する必要があります。そのためには、evaluate関数は追加の引数としてそのようなマッピングをとるべきです。また、識別子から関数への別のマッピングを取る必要があります。このマッピングを使用して、関数アプリケーションの場合に関数名をループアップすることができます。

これらのマッピングについては、現在のところ、定義を表現または処理するコードはありません。定義を表す型と関数を表す型を考え出すべきです。後者の型には、関数パラメータの名前と本体がexprとして含まれている必要があります。

次に、定義のリストを取り、変数と関数のマッピングを作成する関数を記述する必要があります。各変数定義に対して、右側の式を評価し、結果の値を変数マッピングに追加する必要があります。各関数定義について、関数型の値を関数マッピングに追加する必要があります。定義を処理した後で、その式と作成した2つのマッピングを引数としてevaluate関数を呼び出すことによって、最終式を評価する必要があります。

最後に、実際にプログラムを解析するためのコードはありませんが、意図的である可能性があります。

+0

定義のプロセスを表すコードの例を教えてください。私は構文解析のためのコードは必要ありません。あなたが私に喜ばせることができれば、私は方法を知らなかったので、私はIdのコンストラクタを書いていませんでした。 – Spreadzz

+0

@Spreadzz型は 'type def = Def of string * string list * expr'のようなものか、変数と関数の定義を区別したい場合には' type def = VarDef of string * expression | FunDefの文字列*文字列リスト*式 '。 – sepp2k

+0

あなたは私の解釈にAddとMultiplyのタイプdefを見せてもらえますか? – Spreadzz