Kiedy ludzie mówią, że „X nie komponuje”, to co rozumieją przez „komponować” tak naprawdę oznacza po prostu „razem”, a co i jak je łączysz, może być bardzo różne, w zależności od tego, czym dokładnie jest „X”.
Ponadto, gdy mówią „nie komponuje”, mogą oznaczać nieco inne rzeczy:
- Nie możesz w ogóle połączyć dwóch X, kropka.
- Państwo może umieścić dwa Xs razem, ale wynik może nie być X (IOW: X nie jest zamknięty pod kompozycją ).
- Możesz umieścić dwa X razem, ale wynikowy X może nie działać w oczekiwany sposób.
Przykładem # 1 są parsery ze skanerami / leksykonami. Możesz usłyszeć wyrażenie „skanery / leksykony nie tworzą”. To nie jest prawda. Chodzi im o to, że „parser, który używa osobnego etapu leksykalnego, nie tworzy”.
Dlaczego chcesz komponować parsery? Wyobraź sobie, że jesteś dostawcą IDE, takim jak JetBrains, Eclipse Foundation, Microsoft lub Embarcadero, i chcesz zbudować IDE dla środowiska sieciowego. W typowym tworzeniu stron internetowych często mieszamy języki. Masz pliki HTML z <script>
elementami zawierającymi ECMAScript i<style>
elementy zawierające CSS. Masz pliki szablonów zawierające HTML, język programowania i metasyntax języka szablonów. Nie chcesz pisać różnych wyróżników składni dla „Python”, „Python osadzony w szablonie”, „CSS”, „CSS w HTML”, „ECMASCript”, „ECMAScript w HTML”, „HTML”, „HTML w” szablon ”itd. itd. Chcesz napisać wyróżnienie składni dla Pythona, jedno dla HTML, jedno dla języka szablonów, a następnie skomponować trzy w wyróżnienie składni dla pliku szablonu.
Jednak lexer analizuje cały plik w strumień tokenów, co ma sens tylko w tym jednym języku. Analizator składni dla drugiego języka nie może współpracować z tokenami, które przekazuje mu leksykon. Na przykład, parsery Pythona są zwykle pisane w taki sposób, że leksykator śledzi wcięcia i wstrzykuje fałszywe INDENT
i DEDENT
tokeny do strumienia tokenu, dzięki czemu analizator składni może być pozbawiony kontekstu, nawet jeśli składnia Pythona tak naprawdę nie jest. Jednak leksykon HTML całkowicie ignoruje białe znaki, ponieważ nie ma to znaczenia w HTML.
Jednak parser bez skanera, który po prostu odczytuje znaki, może przekazywać strumień znaków do innego parsera, który może następnie oddać go z powrotem, co znacznie ułatwia komponowanie.
Przykładem # 2 są ciągi znaków z zapytaniami SQL. Możesz mieć dwa ciągi, z których każdy zawiera poprawne składniowo zapytanie SQL, ale jeśli połączysz oba ciągi, wynik może nie być poprawnym składniowo zapytaniem SQL. Właśnie dlatego mamy takie algebry zapytań ARel
, które się komponują.
Zamki są przykładem nr 3. Jeśli masz dwa programy z blokadami i łączysz je w jeden program, nadal masz program z blokadami, ale nawet jeśli dwa oryginalne programy były całkowicie poprawne, wolne od zakleszczeń i wyścigów, wynikowy program niekoniecznie ma to własność. Prawidłowe użycie blokad jest globalną właściwością całego programu i właściwością, która nie jest zachowywana podczas tworzenia programów. Różni się to na przykład od transakcji, które się składają. Program, który prawidłowo wykorzystuje transakcje, może zostać skomponowany z innym takim programem i da połączony program, który poprawnie wykorzystuje transakcje.