2016-04-06 5 views
0

Ich versuche, eine grundlegende Sprache zu definieren, um Ausdrücke zu erstellen, die ich selbst aus Code bewerten werde. Solche Ausdrücke werden zur Laufzeit rekursiv definiert. Sie können dies als boolesche Ausdrücke mit elementaren Ausdrücken wie True und False betrachten und auch komplexe Ausdrücke wie die Negation eines Ausdrucks und die Disjunktion und Konjunktion zweier beliebiger Ausdrücke.Kombinieren heterogener rekursiver Typen, um eine Subsprache zu definieren

Wie bereits erwähnt, sind solche Ausdrücke rekursiv und werden zur Laufzeit erstellt, also denke ich, Vorlagen sind keine Wahl. Was ist der geeignetste Weg, Typisierung und eine Evaluierungsfunktion in C++ 2011 zu diesem Zweck zu implementieren?

Alle Kommentare sind willkommen, da meine Kenntnisse über C++ - Muster und -Funktionen leider noch nicht weit sind.

Beispiel arbeitsfreien Code, was die Tatsache zeigt, dass ich keine externe Darstellung für Ausdrücke (als Strings) benötigen:

struct basic { 
    bool val; 
}; 
struct complex_neg { 
    expression exp; 
}; 
struct complex_and { 
    expression exp1, exp2; 
}; 
struct expression : basic, complex_neg, complex_and { 
    bool eval() { 
     if (dynamic_cast<basic*>(this)) return this->val; 
     else if (dynamic_cast<complex_neg*>(this)) return !this->eval(); 
     else return this->eval() && this->eval(); 
    } 
}; 
+0

Vielen Dank für Ihre frühen Antworten. Ich habe vergessen zu erwähnen, dass die Verwendung von Drittanbieter-Bibliotheken keine Option ist, die ich mir leisten kann, da der Code für eine Handy-App bestimmt ist. – jvier

+0

Beachten Sie, dass Header-only-Bibliotheken (wie Boost.Spirit, die unten erwähnt werden) kein Problem sind, da sie über keine binäre Datei verfügen, die Sie dem Benutzer bereitstellen müssen. – Quentin

+0

Danke, aber ich glaube immer noch, mein Problem ist viel einfacher und sollte keine externe Bibliothek benötigen. Ich habe weitere Informationen hinzugefügt, um meine Frage ausführlicher zu machen. – jvier

Antwort

1

Ein guter Start ist ein Baum/gerichteten Graphen Ihrer Ausdrücke zu bauen und Terminals. Siehe Abstract syntax tree.

Und dann bewerten, dass Ausdrucksbaum.

In C++ ist eine der bequemsten Möglichkeiten zum Erstellen eines AST so zu verwenden Boost Spirit, see a good introduction.

+0

Danke. Ich bin mit grundlegenden Datenstrukturen vertraut, habe aber bisher keine Ahnung, wie man es in C++ so einfach wie möglich implementieren kann. – jvier

+0

@jvier Die Dokumentation des Reading Spirits wird Ihnen die Dinge viel klarer machen. Es gibt leider keine Abkürzung. –

1

Die einfachste Sache, die Sie versuchen könnten, ist Shunting-yard algorithm mit inverser polnischer Notation.

Die meisten professionellen, was Sie tun können, ist boost spirit

Die bad-ass Sie tun können, zu verwenden ist, um sich einen ll-Parser für Ihre spezifische Grammatik zu implementieren. Aber Sie müssen eine Theorie über Sprachparser wissen.

+0

Danke. Die Grammatik, die ich brauche, gilt nicht für benutzerlesbare Darstellungen wie Strings. Meine Frage bezieht sich darauf, wie C++ - Typisierung und andere Funktionen verwendet werden können, um eine solche rekursive Syntax (d. H. Klassenvererbung) zu definieren. – jvier

+0

@jvier Es ist sehr unklar, was du meinst. Sprechen Sie über Ausdrucksvorlagen? – grisumbras

+0

Das könnte in der Tat eine Wahl sein. Ich werde etwas Code zur Veranschaulichung hinzufügen. – jvier

Verwandte Themen