semantische Aktionsparameter des Geistes verstärken
in diesem Artikel über boost Geist semantische Aktionen es wird erwähnt, dass
Gibt es eigentlich 2 mehr Argumente
übergeben werden: der parser-Kontext und ein
Verweis auf eine bool 'Treffer'
parameter. Die parser-Kontext ist
nur sinnvoll, wenn die semantische Aktion
befestigt ist irgendwo auf der rechten Seite
Seite der Regel. Wir werden sehen, mehr
Informationen dazu in Kürze. Die
boolean-Wert kann auf false gesetzt werden
innerhalb der semantischen Aktion ungültig
das Spiel in der Retrospektive, so dass die
parser fehl.
Alles in Ordnung, aber ich habe versucht zu finden ein Beispiel ist die übergabe einer Funktion ein Objekt als semantische Aktion verwendet, die andere Parameter (parser-Kontext und trifft boolean), aber ich habe keine gefunden. Ich würde gerne sehen, ein Beispiel anhand von regulären Funktionen oder funktionsobjekte, als ich kaum noch kann grok die phoenix voodoo
InformationsquelleAutor der Frage lurscher | 2010-06-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese eine wirklich gute Frage (und auch eine Dose Würmer), weil er an der Schnittstelle von qi und phoenix. Ich habe nicht gesehen, ein Beispiel, so werde ich verlängern Sie die Artikel ein wenig in diese Richtung.
Ist, wie du sagst, Funktionen für semantische Aktionen können bis zu drei Parameter
Match flag
Wie der Artikel sagt, der zweite parameter ist nicht sinnvoll, es sei denn, der Ausdruck ist Teil einer Regel, also lasst uns beginnen mit der Dritten. Ein Platzhalter für den zweiten parameter noch benötigt wird, obwohl für diese Verwendung
boost::fusion::unused_type
. So eine modifizierte Funktion aus dem Artikel ist der Dritte parameter ist:welche Ausgänge:
Alle in diesem Beispiel schaltet sich das match zu einer nicht-übereinstimmung, die sich in der parser-Ausgabe. Nach hkaiser, im boost 1.44 und bis Einstellung der match-flag auf false gesetzt ist, wird verursachen, das Spiel nicht in der normalen Weise. Wenn alternativen definiert sind, wird der parser wieder ansetzen und versuchen, passen Sie an, wie man erwarten würde. Jedoch im boost<=1.43 Geist bug verhindert backtracking, die bewirkt, dass seltsame Verhalten. Um dies zu sehen, hinzufügen phoenix gehören
boost/spirit/include/phoenix.hpp
und ändern Sie den AusdruckWürden Sie erwarten, dass, wenn das qi::int parser fehlschlägt, wird die alternative qi::Ziffer an den Anfang des Eingangs auf "1", aber die Ausgabe ist:
Den
6
ist die erste Ziffer die zweite int in der Eingabe, die angibt, die alternative wird mit dem skipper und ohne backtracking. Beachten Sie auch, dass das match gilt als erfolgreich, auf der Grundlage der alternative.Einmal boost 1.44 heraus ist, wird der match-flag wird nützlich sein, für die Anwendung mit den Kriterien übereinstimmen, könnte sonst schwer werden, zu Ausdrücken, die in einer parser-Sequenz. Beachten Sie, dass die match-flag manipuliert werden können, in phoenix Ausdrücke mit den
_pass
Platzhalter.Context-parameter
Interessanter parameter ist die zweite, enthält der qi-phoenix-Schnittstelle, oder im qi Sprachgebrauch, der Zusammenhang von der semantischen Aktion. Um dies zu verdeutlichen, untersuchen Sie zuerst eine Regel:
Den context-parameter verkörpert das Attribut, Arg1, ... ArgN, und qi::locals template-Parameter, verpackt in einem boost::spirit::Rahmen-Vorlage geben. Dieses Attribut unterscheidet sich von der Funktion parameter: die Funktion parameter-Attribut wird der Analysierte Wert, während dieses Attribut ist der Wert der die Regel selbst. Eine semantische Aktion zugeordnet sein müssen, die ersteren an den letzteren. Hier ist ein Beispiel für eine mögliche Kontext-Typ (phoenix-Ausdruck-äquivalente angegeben):
Hinweis: return-Attribut-argument-Liste in form einer lisp-Liste "Stil" (a Nachteile-Liste). Der Zugriff auf diese Variablen innerhalb einer Funktion, Zugriff auf die
attribute
oderlocals
Mitglieder dercontext
struct template mit fusion::<>(). Zum Beispiel für eine Kontext-variablecon
Ändern Sie den Artikel. B. mit dem zweiten argument, ändern Sie die definition der Funktion und phrase_parse Aufrufe:
Dies ist ein sehr einfaches Beispiel, das nur Karten der Analysierte Wert für das output-Attribut-Wert, aber Erweiterungen sollte ziemlich offensichtlich. Stellen Sie einfach die context-struct template-Parameter passt die Regel-Ausgabe, - Eingabe und lokale Typen. Beachten Sie, dass diese Art der eine direkte übereinstimmung zwischen den analysierten Typ/Wert-zu-Ausgang-Typ/- Wert kann automatisch getan werden, mithilfe der automatischen Regeln, mit einem
%=
statt einer=
bei der Definition der Regel:IMHO, schreiben eine Funktion für jede Aktion wäre ziemlich langweilig, im Vergleich zu den kurzen und lesbaren phoenix-Ausdruck-äquivalente. Ich sympathisiere mit dem voodoo-Sicht, aber wenn Sie die Arbeit mit phoenix für eine kleine Weile, der Semantik und der syntax sind nicht sehr schwierig.
Bearbeiten: der Zugriff auf die Regel-Rahmen w/Phoenix
Kontext-variable ist nur definiert, wenn der parser ist Teil einer Regel. Denken Sie an einen parser als einen Ausdruck, der verbraucht Eingang, wo in der Regel übersetzt der parser Werte (qi::_1) in der Regel ein Wert (qi::_val). Der Unterschied ist oft nicht trivial, zum Beispiel beim qi::val hat eine Klasse-type, die muss aufgebaut werden aus POD-Werte analysiert. Unten ist ein einfaches Beispiel.
Lassen Sie uns sagen, ein Teil unserer Eingabe ist eine Sequenz von drei CSV-Ganzzahlen (
x1, x2, x3
), und interessieren wir uns nur eine arithmetische Funktion dieser drei Ganzzahlen (f = x0 + (x1+x2)*x3 ), wo x0 ein Wert, den man erhält anderswo. Eine Möglichkeit ist das Einlesen in die ganzen zahlen und berechnen Sie die Funktion, oder verwenden Sie alternativ phoenix, beides zu tun.In diesem Beispiel verwenden Sie eine Regel mit einem output-Attribut (mit der Funktion Wert) und input (x0), und eine lokale (zum übergeben von Informationen zwischen den einzelnen Parser-Regel). Hier ist das komplette Beispiel.
Alternativ, alle ints könnte analysiert werden, wie ein Vektor, und die Funktion bewertet mit einem einzigen semantischen Aktion (die
%
unten ist die Liste der Betreiber und die Elemente des Vektors zugegriffen werden mit: phoenix::):Für die oben genannten, wenn die Eingabe falsch ist (zwei int-Werte anstelle von drei), bad etwas passieren könnte während der Laufzeit, so wäre es besser, geben Sie die Anzahl der geparsten Werte explizit, so parsing-Fehler für eine schlechte Eingabe. Die unten verwendet
_1
_2
und_3
Verweis auf die erste, zweite und Dritte match-Wert:Dies ist ein erfundenes Beispiel, aber sollte Ihnen die Idee. Ich habe festgestellt, phoenix semantischen Aktionen, die wirklich hilfreich in der Konstruktion von komplexen Objekten direkt aus Eingang; dies ist möglich, da können Sie Aufrufe von Konstruktoren und member-Funktionen innerhalb der semantischen Aktionen.
InformationsquelleAutor der Antwort academicRobot