Czytanie i oglądanie tej prezentacji:
http://boost-spirit.com/home/2011/06/12/ast-construction-with-the-universal-tree/
Odkryłem to stwierdzenie - w zasadzie sugerujemy, aby nie używać akcji semantycznych.
Muszę przyznać, że już coś takiego czułem: gramatyki z działaniami semantycznymi faktycznie wyglądają trochę brzydko. i kiedy musiałem je rozszerzyć / zmienić, wymagało to "mikromanagementu" dokładnie z akcjami semantycznymi. Podejście z gramatyką atrybutów, przedstawione w prezentacji, wydaje się dużo bardziej eleganckie i obiecujące.
Chciałbym zapytać: czy to jest "oficjalny" punkt? Czy powinienem nauczyć się pracy z gramatyką atrybutów i bardziej szczegółowo omijać działania semantyczne? Jeśli tak - chciałbym poprosić o kilka podstawowych (może nawet banalnych) przykładów, demonstrujących takie podejście - tłumacz LISP jest zbyt skomplikowany, abym mógł go przeżuć ...
Jestem pewien, że Hartmut odpowie w ciągu sekundy. Do tego czasu to moje zdanie:
Nie to nie jest oficjalna kwestia.
Działania semantyczne mają pewne wady
Najprostszy niekorzyść działań semantycznych jest stylistycznym pojęciem rozdzielenie obaw. Chcesz wyrazić składnia w jednym miejscu, i semantyka winnym. Pomaga to w utrzymaniu sprawności (zwłaszcza w odniesieniu do długich czasów kompilacji dla kompilacji Spirit Grammars)
Bardziej skomplikowane konsekwencje, jeśli mają skutki uboczne (co często ma miejsce). Wyobraź sobie cofanie się z przeanalizowanego węzła, gdy akcja semantyczna miała efekt uboczny: status parsera zostanie przywrócony, ale efekty zewnętrzne nie.
W pewnym sensie, używając atrybutów tylko jest jak używanie deterministycznych, czystych funkcji w programie funkcjonalnym, łatwiej jest wnioskować o poprawności programu (lub w tym przypadku gramatyka automat stanowy), gdy jest opanowany tylko z czystych funkcji.
Działania semantyczne mają tendencję (ale niekoniecznie musi) do wprowadzania większego kopiowania według wartości; to, w połączeniu z ciężkim powrotem, może zmniejszyć wydajność. Oczywiście, jeśli działanie semantyczne jest "ciężkie", samo w sobie będzie to przeszkadzało w przeprowadzaniu analizy.
Działania semantyczne są dobre dla różnych celów. W rzeczywistości, jeśli chcesz analizować nietrywialne gramatyki z wrażliwością kontekstu, nie możesz ich uciec.
Rozważ użycie qi::locals<>
i odziedziczone atrybuty (kod z Mini XML - ASTs!
próba) - wiążą się z działaniami semantycznymi:
xml =
start_tag [at_c<0>(_val) = _1]
>> *node
>> end_tag(at_c<0>(_val)) // passing the name from the
// ... start_tag as inherited attribute
;
Lub jeden używający qi :: locals:
rule<char const*, locals<char> > rl;
rl = alpha[_a = _1] >> char_(_a); // get two identical characters
test_parser("aa", rl); // pass
test_parser("ax", rl); // fail
IMO, te działania semantyczne zwykle stanowią mniejszy problem, ponieważ kiedy zostaną wycofane, następnym razem, gdy egzekucja przejdzie (ta sama) akcja semantyczna, lokalny zostaną po prostu nadpisane przez nową, poprawną wartość.
Ponadto niektóre zadania są naprawdę "szybkie i brudne" i nie gwarantują ich użycia utree lub ręcznie zwijany typ AST:
qi::phrase_parse(first, last, // imagine qi::istream_iterator...
intesting_string_pattern // we want to match certain patterns on the fly
[ log_interesting_strings ], // and pass them to our logger
noise_skipper // but we skip all noise
);
Tutaj semantyczną czynnością jest rdzeń funkcji parsera. Działa, ponieważ na poziomie węzłów z działaniami semantycznymi nie występuje sprzężenie zwrotne.
Działania semantyczne są lustrzanym odbiciem działań semantycznych w Duchowej Karmie, gdzie zwykle stanowią mniej problemów niż w Qi; więc nawet jeśli chodzi o spójność interfejsu / API, działania semantyczne są "rzeczą dobrą" i zwiększają użyteczność Boost Spirit jako całości.