2012-10-12 22 views
7

Kann jemand mir etwas Hilfe eine ocaml Interpreter für die Sprache mit der Syntax Aufbau:ocaml Dolmetscher

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

bisher ich dies tat:

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 

Ist das gut?

Antwort

6

In Ihrer Grammatik kann eine einzelne ID entweder durch die Produktion Expr ::= id oder Expr ::= id Expr* abgeglichen werden. Mit anderen Worten, es gibt keine Möglichkeit, zwischen einer Nullfunktionsanwendung (vorausgesetzt, die id Expr* Produktion soll Funktionsanwendungen entsprechen) und Variablen zu unterscheiden. Vielleicht meinen Sie stattdessen id Expr+ (keine nullary-Funktion-Anwendungen ablehnen).

Ihre vorhandenen Code sieht gut aus, aber es ist unvollständig:

Ihr expr Typ einen Konstruktor für die id Expr* Produktion der Grammatik fehlt, das heißt Sie einen Konstruktor sind vermisst, die Funktion von Anwendungen darstellt. Sie sollten einen hinzufügen und dann einen Fall für die Funktion evaluate hinzufügen.

In Ihrer evaluate Funktion fehlt Ihnen ein Fall für den Id Konstruktor. Dieser Fall sollte den Wert des angegebenen Bezeichners in einer Zuordnung von Bezeichnern zu Werten (ints) nachschlagen. Zu diesem Zweck sollte Ihre evaluate Funktion eine solche Abbildung als zusätzliches Argument verwenden. Es sollte auch eine andere Zuordnung von Bezeichnern zu Funktionen geben, die Sie dann verwenden können, um Funktionsnamen für Anwendungsfälle zu kopieren.

Apropos diese Zuordnungen, Sie haben derzeit keinen Code, um Definitionen darzustellen oder zu verarbeiten. Sie sollten einen Typ zur Darstellung einer Definition und einen anderen zur Darstellung von Funktionen entwickeln. Der letztere Typ sollte den Namen der Funktionsparameter und den Körper als expr enthalten.

Dann sollten Sie eine Funktion schreiben, die eine Liste von Definitionen übernimmt und die Zuordnungen für Variablen und Funktionen erstellt. Für jede Variablendefinition sollte der Ausdruck auf der rechten Seite ausgewertet und die resultierenden Werte zu Ihrer Variablenzuordnung hinzugefügt werden. Für jede Funktionsdefinition sollten Sie der Funktionszuordnung einen Wert Ihres Funktionstyps hinzufügen. Nachdem Sie die Definitionen verarbeitet haben, sollten Sie den endgültigen Ausdruck durch Aufruf der Funktion evaluate mit diesem Ausdruck und den beiden Zuordnungen, die Sie als Argumente erstellt haben, auswerten.

Schließlich haben Sie keinen Code für die tatsächliche Analyse des Programms, aber ich denke, dass dies beabsichtigt sein könnte.

+0

Können Sie mir bitte ein Beispiel für einen Code zeigen, um den Definitionsprozess darzustellen? Ich brauche keinen Code zum Parsen, und ich habe den Id-Konstruktor nicht geschrieben, weil ich nicht wusste, wie, wenn Sie mir bitte zeigen können. – Spreadzz

+0

@Spreadzz Der Typ wäre nur etwas wie 'type def = Def von string * string list * expr' oder, wenn Sie zwischen Variablen- und Funktionsdefinitionen unterscheiden wollen,' type def = VarDef von string * Ausdruck | FunDef von string * string list * ausdruck'. – sepp2k

+0

Kannst du mir den Typ def von Add und Multiply in meinem Interpreter zeigen, damit ich voll verstehen kann? – Spreadzz