7

構文を使用して言語用の 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

これでいいですか?

4

1 に答える 1

6

文法では、単一のIDをプロダクションExpr ::= idまたはで一致させることができますExpr ::= id Expr*。言い換えれば、nullary関数アプリケーション(id Expr*プロダクションが関数アプリケーションと一致することになっていると仮定)と変数を区別する方法はありません。多分あなたはid Expr+代わりに意味しました(nullary関数適用を禁止します)。

既存のコードは問題ないように見えますが、不完全です。

exprタイプに文法を生成するためのコンストラクターがありませid Expr*ん。つまり、関数アプリケーションを表すコンストラクターがありません。evaluate1つ追加してから、そのケースも関数に追加する必要があります。

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

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

次に、定義のリストを取得し、変数と関数のマッピングを作成する関数を作成する必要があります。変数定義ごとに、右側の式を評価し、結果の値を変数マッピングに追加する必要があります。関数定義ごとに、関数型の値を関数マッピングに追加する必要があります。evaluate定義を処理した後、その式と引数として作成した2つのマッピングを使用して関数を呼び出し、最終的な式を評価する必要があります。

最後に、実際にプログラムを解析するためのコードはありませんが、それは意図的なものかもしれません。

于 2012-10-12T15:43:10.107 に答える