2009-01-28 2 views
8

Ich habe mehrere Funktionen in meinem Programm, das wie folgt aussehen:Erstellen einer C++ App skript

void foo(int x, int y) 

Jetzt möchte ich mein Programm einen String nehmen, die wie folgt aussieht:

foo(3, 5) 

und führen Sie die entsprechende Funktion. Was ist der einfachste Weg dies zu implementieren?

Wenn ich geradlinig sage, meine ich einigermaßen erweiterbar und elegant, aber es sollte nicht zu lange dauern, um zu kodieren.

Edit:

Während einer echte Skriptsprache wäre natürlich mein Problem lösen verwenden, würde ich noch gerne wissen, ob es eine schnelle Art und Weise ist dies in reinen C++ zu implementieren.

Antwort

5

ich auch für die Skriptsprache Antwort gehen würde.

Mit reinem C++ würde ich wahrscheinlich einen Parser-Generator verwenden, der die Token- und Grammatikregeln erhält und mir C-Code liefert, der die gegebene Funktionsaufrufsprache genau parsen kann und mir einen Syntaxbaum von dieser Anruf. flex kann verwendet werden, um eine Eingabe zu token, und bison kann verwendet werden, um die Token zu analysieren und sie in einen Syntaxbaum zu transformieren.Alternativ zu diesem Ansatz kann Boost Spirit verwendet werden, um auch die Funktionsaufrufsprache zu analysieren. Ich habe noch nie eines dieser Tools benutzt, sondern habe an Programmen gearbeitet, die sie benutzen, daher weiß ich etwas, was ich verwenden würde, falls ich dieses Problem lösen müsste.

Für sehr einfachen Fällen, könnten Sie Ihre Syntax dies ändern:

func_name arg1, arg2 

Dann können Sie verwenden:

std::istringstream str(line); 
std::string fun_name; str >> fun_name; 
map[fun_name](tokenize_args(str)); 

Die Karte ein

std::map<std::string, boost::function<void(std::vector<std::string>)> > map; 

wäre Was würde mit den Funktionen am Anfang Ihres Programms gefüllt werden. tokenize_args würde nur die Argumente trennen und einen Vektor von ihnen als Zeichenfolgen zurückgeben. Natürlich ist das sehr primitiv, aber ich denke, es ist vernünftig, wenn Sie nur eine Möglichkeit haben wollen, eine Funktion aufzurufen (wenn Sie wirklich Script-Unterstützung wünschen, reicht dieser Ansatz natürlich nicht aus).

+0

Ich würde für boost :: spirit gehen, da Sie eine Menge über Parser und über Template-Metaprogrammierung lernen werden. – lothar

8

Sie können einen Blick auf Lua werfen.

+0

schau dir Lua an - was WAS ??? Diese Seite ist fast nutzlos, um zu beschreiben, wie man die Sprache einbindet. Sogar Seite 3 des Handbuchs (http://www.lua.org/manual/5.1/manual.html#3) näher, aber hilft dem OP nicht. – jim

+0

"Use lua" wird zu einer reflexartigen Reaktion auf ähnliche Fragen. – artificialidiot

10

Sie können Python ziemlich einfach einbetten, und das würde Ihnen eine wirklich leistungsfähige, erweiterbare Möglichkeit geben, Ihr Programm zu skripten. Sie können ganz einfach die folgenden verwenden (mehr oder weniger) Setzen Sie Ihre C++ Code zu Python:

ich persönlich Python verwenden Boost und ich bin glücklich mit ihm, aber Es ist langsam zu kompilieren und kann schwer zu debuggen sein.

+1

SWIG ist sehr gut und sehr flexibel. – vrdhn

3

Als Daniel sagte:

Skriptsprachen wie Lua und Python die am häufigsten verwendeten Skriptsprachen für die Bindung zusammen C++ Bibliotheken seien.

Sie müssen eine Skriptschnittstelle zu Ihrer C++ - Anwendung hinzufügen. Der Aufbau dieser Schnittstelle hängt natürlich davon ab, welche Skriptsprache Sie gewählt haben.

1

Wenn Sie eine Funktion nur über den Literalnamen aufrufen möchten, können Sie linkerspezifische Funktionen verwenden.

Auf POSIX-kompatiblen Betriebssystemen (wie Linux) können Sie dlopen() und dlsym() verwenden. Sie analysieren einfach die Eingabezeichenfolge und ermitteln den Funktionsnamen und die Argumente. Dann können Sie den Linker bitten, die Funktion anhand des Namens mithilfe von dlsym() zu finden.

Unter Windows sind diese Funktionen jedoch nicht verfügbar (es sei denn, es gibt eine POSIX-Umgebung wie Cygwin). Aber Sie können die Windows-API verwenden.

Sie können einen Blick hier für weitere Details über diese Dinge nehmen: http://en.wikipedia.org/wiki/Dynamic_loading

0

Muss Ihr System "eine Zeichenfolge aufnehmen"? Sie könnten COM- (oder CORBA- oder was auch immer) -Schnittstellen in Ihrer Anwendung verfügbar machen und alles, was diese Befehle generiert, direkt in Ihre Anwendung aufrufen.

1

C++ Reflection [2] von Fabio Lombardelli bietet eine vollständige Neudefinition für C++ durch Template Metaprogrammierungs-Techniken. Während es vollständig kompatibel mit den C++ Standards ist, bedarf es der Programmierer die Klassen, um

http://cppreflect.sourceforge.net/

ansonsten reflektierend sein forthem zu annotieren Sie einen Funktionszeiger Hash-Tabelle denke ich

2

CERN wollen würde stellt CINT bereit, einen C/C++ - Interpreter, der in Ihre Anwendung eingebettet werden kann, um Skriptfunktionen bereitzustellen.