Ich versuche, einen Shell-Sprache-Parser in Boost.Spirit zu schreiben. Ich bin jedoch über einige grundlegende Fragen in Bezug auf die Semantik von rule
s unklar.Kopiere oder referenziere Semantik von boost :: spirit's rule <>?
Mit Blick auf die Dokumentation gibt es Mitglieder r.alias()
und r.copy()
von rule
. IIUC sollten diese Mitglieder einen Verweis auf die Regel bzw. eine Kopie des Inhalts der Regel zurückgeben. Es ist jedoch nicht klar angegeben, was passiert, wenn ich die Regel nur in einer Definition einer anderen Regel verwende. Aus meinen Versuchen, fand ich beiden Seiten rekursive Regeln können definiert werden durch:
rule<Iter> r1, r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;
was darauf schließen läßt die Regeln getroffen werden, durch Bezugnahme innerhalb Parser Ausdrücke. Das Problem ist, was tut sie, wenn die Variable den Gültigkeitsbereich verlässt, zum Beispiel:
rule<Iter> r1;
{
rule<Iter> r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;
}
... // use r1
Auf die gleiche Note, würde von einem Parsing Ausdruck einer Regel Zuweisung eines rvalue vom Typ Regel Arbeit, die (r.copy()
wäre ein rvalue des Typs rule
auch, ist es nicht)? z.B.
rule<Iter> f() { return char_('a') << char_('b'); }
rule<Iter> r1 = ... << f();
Kann mir jemand auf die detaillierten Semantik von rule
‚s Kopien und Verweise, aufklären und möglicherweise irgendwelche Missverständnisse in diesem Beitrag nicht korrekt?
Danke für diese Antwort. Ich habe nur eine weitere Frage: Ist es irgendwie möglich, rvalues (provisories) von Parser-Ausdrücken eines Typs im Parser-Ausdruck zu verwenden, um Anweisungen wie 'r1 = r1 | zu erlauben string ("abc") oder Regeln in einer Funktion erzeugen? – jpalecek
Während der Ausdruck 'r1 = r1 | string ("abc") 'ist theoretisch möglich, es ist eine Linksrekursion, die zu einer unendlichen Rekursion führt, wenn Spirit rekursive Descent-Parser erzeugt. Aber der Ausdruck 'r1 = string ("abc") | r1 'wird wie erwartet funktionieren. Sie können eine Regel in einer Funktion generieren, wenn Sie sicherstellen, dass sie sich nicht auf eine andere Regel bezieht, die den Gültigkeitsbereich überschritten hat. In Spirit.Classic müssen Sie außerdem r.copy() von der Funktion zurückgeben. – hkaiser
'r1 = Zeichenfolge ("abc") | r1 'ist auch eine Links-Rekursion :) Aber was ich machen wollte, ist, dass r1 zu dem passt, was r1 früher gefunden hat und "abc". BTW wie kann ich eine Regel in einer Funktion erzeugen? Das funktioniert nicht für mich: http://pastebin.org/482764 – jpalecek