Próbuję napisać parser języka powłoki w Boost.Spirit. Jednak nie mam pewności co do podstawowych problemów dotyczących semantyki rule
s.Skopiuj lub odwołaj się do semantyki reguły boost :: spirit <>?
Patrząc na dokumentację, są tam członkowie: r.alias()
i r.copy()
z rule
. IIUC, członkowie ci powinni zwracać odwołanie do reguły i kopii zawartości reguły, odpowiednio. Jednak nie jest jasno określone, co się dzieje, gdy po prostu używam reguły w definicji innej reguły. Z moich doświadczeń, znalazłem wzajemnie rekurencyjne zasady może być zdefiniowana przez:
rule<Iter> r1, r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;
co sugeruje reguły podejmowane są przez odniesienie wewnątrz wyrażeń parsera. Problemem jest to, co on robi, gdy zmienna wychodzi z zakresu, na przykład:
rule<Iter> r1;
{
rule<Iter> r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;
}
... // use r1
Na tej samej notatki, to przypisanie do przepisu z wyrażeniem analizowania zawierającym rvalue pracy reguła typu (r.copy()
byłoby rura typu rule
też nie jest? na przykład.
rule<Iter> f() { return char_('a') << char_('b'); }
rule<Iter> r1 = ... << f();
Czy ktoś może mnie oświecić w sprawie szczegółowych semantyki kopii i odniesień rule
„s, i ewentualnie skorygować ewentualne nieporozumienia w tym poście?
Dziękuję za tę odpowiedź. Mam tylko pytanie uzupełniające: Czy jest możliwe używanie wartości rvalues (tymczasowych) wyrażeń parsera jakiegoś typu w wyrażeniu analizatora składni, aby zezwalać na takie instrukcje jak "r1 = r1 | ciąg ("abc") "lub generowanie reguł w funkcji? – jpalecek
Podczas gdy wyrażenie "r1 = r1 | string ("abc") "jest teoretycznie możliwe, że jest lewą rekursją, co spowoduje nieskończoną rekurencję, gdy Spirit generuje parser rekursywny. Ale wyrażenie "r1 = string (" abc ") | r1 "zadziała zgodnie z oczekiwaniami. Możesz wygenerować regułę w funkcji, jeśli upewnisz się, że nie odnosi się ona do żadnej innej reguły, która wykracza poza zakres. Dodatkowo w Spirit.Classic musisz zwrócić r.copy() z funkcji. – hkaiser
'r1 = ciąg ("abc") | r1 'to też lewa rekurencja :) Ale to, co chciałem zrobić, to sprawić, żeby r1 pasowało do r1 dopasowanego wcześniej i "abc". BTW jak mogę wygenerować regułę w funkcji? To nie działa dla mnie: http://pastebin.org/482764 – jpalecek