875 Shares 6943 views

Nadawca – jest … Rodzaje kompilatorów. Konwersja i nadawania programów

Programów, a także ludzi, aby tłumaczyć z jednego języka na inny potrzebuje tłumacza lub tłumacza.

podstawowe pojęcia

Program jest reprezentacją językowa obliczeń: I → P → P (i). Tłumacza to program, który jest dostarczany z programem wejściowym P i niektóre wejściowego x. Wykonuje się P x: I (P X) = P (x). Fakt, że istnieje tylko jeden tłumacz jest w stanie wykonać wszystkie możliwe programy (które mogą być reprezentowane w systemie formalnym) jest bardzo głębokie i istotne odkrycie Turinga.

Procesor jest interpreter programów w języku maszynowym. Ogólnie zbyt drogie, aby napisać tłumaczy dla języków wysokiego poziomu, więc przełożyć się na formularzu, który jest łatwiejszy do zinterpretowania.

Niektóre rodzaje tłumaczy mają bardzo dziwne nazwy:

  • Assembler tłumaczy programy asemblerze na język maszynowy.
  • Kompilator tłumaczy języka wysokiego poziomu do niższego języku.

Nadawca – to program, który przyjmuje jako dane wejściowe do programu w jakimś języku S i T produkuje programu w taki sposób, że obaj mają te same semantyki: P → X → Q. To znaczy, że ∀x. P (x) = P (x).

Jeśli transmitowany cały program w coś zinterpretować, nazywa kompilację przed wykonaniem lub AOT kompilacji. AOT kompilator może być stosowany w szeregu, z których ten ostatni często monter, na przykład:

Kod źródłowy kompilatora → (tłumacz) → → kod asemblera montaż (kompilator) kod → → maszyna CPU (interpreter).

Operacyjne lub dynamiczna kompilacja występuje, jeśli program jest nadawany, gdy są wykonywane przez inny skompilowany wcześniej części. JIT-kompilatory pamiętać, co już zrobione, tak aby nie znowu i znowu powtórzyć kod źródłowy. Mogą nawet produkować adaptacyjne kompilację i rekompilacji w oparciu o zachowanie środowiska wykonywania programu.

Wiele języków pozwalają na wykonanie kodu w czasie kompilacji i kompilacji nowego kodu w czasie wykonywania.

etap tłumaczenie

Broadcast obejmuje etapy analizy i syntezy:

Analizator kodu źródłowego → → → koncepcyjne generator reprezentacja (syntezator) → kodu docelowego.

Wynika to z następujących powodów:

  • Każdy inny sposób nie jest odpowiedni. tłumaczenie słowo po prostu nie działa.
  • Dobrym rozwiązaniem inżynierii: jeśli chcesz napisać do tłumaczenia języków M i N źródłowych ukierunkowanych musi napisać tylko M + N prostych programów (polukompilyatorov) zamiast kompleksu M x N (łączne tłumaczy).

Jednak w praktyce, koncepcyjne widzenia bardzo rzadko na tyle wyrazisty i wystarczająco silne, aby objąć wszystkich możliwych języków źródłowych i docelowych. Chociaż niektórzy byli w stanie zbliżyć się do tego.

Prawdziwe kompilatory przejść przez wiele etapów. Tworząc własny kompilator nie trzeba powtarzać całą ciężką pracę, że ludzie mają zrobić, aby tworzyć reprezentacje i generatorów. Można przetłumaczyć język bezpośrednio w JavaScripcie lub C i skorzystać z istniejącej Javascript silnika i kompilatora C zrobić resztę. Można również użyć istniejącej reprezentacji pośredniej i maszyn wirtualnych.

rekord tłumacz

Nadawca – to program lub sprzęt, który uczestniczy w trzech językach: źródło, cel i podstawy. Mogą być napisane w kształcie litery T, umieszczania oryginału lewo, w prawo i docelową bazę poniżej.

Istnieją trzy rodzaje kompilatory:

  • Nadawca – jest samokompilyator jeśli odpowiada ona podstawowym języku źródłowym.
  • Kompilator języka docelowego, który jest bazowy, zwany samorezidentnym.
  • Nadawca – cross-kompilator, gdyby ukierunkowane i podstawowe różne języki.

Dlaczego to jest ważne?

Nawet jeśli nigdy mieć rzeczywisty kompilator, dobrej znajomości technologii jego utworzenia, ponieważ pojęcie stosowane do tego celu są powszechnie używane, na przykład:

  • formatowanie tekstu;
  • Zapytania językowe do baz danych;
  • Zaawansowana architektura komputer;
  • uogólnione problemów optymalizacyjnych;
  • GUI;
  • języków skryptowych;
  • kontrolerów;
  • maszyn wirtualnych;
  • Tłumaczenie maszynowe.

Ponadto, jeśli chcesz napisać preprocesorów, łączniki, ładowarki, debuggery i profilarek, trzeba przejść przez te same kroki jak przy pisaniu kompilatora.

Można również nauczyć się pisać lepsze programy, ponieważ stworzenie tłumacza języka oznacza lepszego zrozumienia jego zawiłości i niejasności. Badanie ogólnych zasad nadawania pozwala również, aby stać się dobrym językiem projektant. Więc to ma znaczenie, jak strome języka, jeśli nie mogą być skutecznie realizowane?

kompleksowa technologia

Technologia kompilator obejmuje wiele różnych dziedzin informatyki:

  • formalna teoria języka: gramatyka, analizowania, obliczalności;
  • Architektura komputera. zestawy instrukcji CISC, RISC lub, niepotokowych cykli zegara rdzenia przetwarzanie, etc;
  • koncepcje językach programowania, na przykład, wykonując kontrolę sekwencji, wykonanie warunkowa, iteracji rekurencji, dekompozycji funkcjonalnej, modułowość, synchronizacja, meta-programowania, zakres, stałe podtypy, szablony, typ wyjścia, prototypy, adnotacje, przepływu, monady, skrzynki pocztowe, nadal , symbole wieloznaczne, wyrażenie regularne, pamięć transakcyjna, dziedziczenie, polimorfizm, ustawienia trybu, i tak dalej itp..;
  • abstrakcyjne języki i maszyny wirtualne;
  • Algorytmy i struktury danych: wyrażenia regularne, analizowania algorytmów, algorytmy grafika, programowanie dynamiczne, szkolenia;
  • języki programowania: składnia, semantyka (statyczne i dynamiczne), paradygmaty wsparcia (strukturalne, OOP, funkcjonalne, logiczne, stos, równoległość, meta-programowanie);
  • oprogramowania do tworzenia (kompilatorów, zwykle dużymi i złożonymi) lokalizacji, buforowanie componentize interfejsy API, wielokrotnego użytku, do synchronizacji.

projekt kompilatora

Niektóre z problemów w rozwoju prawdziwego tłumacza:

  • Problemy z języka źródłowego. Czy łatwo jest go skompilować? Czy istnieje preprocesor? Jak są rodzaje? Czy jest biblioteka?
  • Grupowanie przechodzi kompilatora: jedno- lub wielo-way?
  • Stopień optymalizacji pożądane. Szybko i nieczyste programy nadawane z małym lub żadnym optymalizacji może być normalne. Over-optymalizacja kompilator będzie powolny, ale lepiej kodu w czasie wykonywania może być warto.
  • Wymagany stopień wykrywania błędów. Czy tłumacz po prostu zatrzymać się na pierwszym błędzie? Kiedy należy go zatrzymać? Czy zaufać korekcję błędów kompilator?
  • Dostępność narzędzi. Jeśli oryginalny język nie jest bardzo małe, są wymagane analizatory skaner i generatorów. Istnieją również generatory, generatory kodu, ale nie są one tak powszechne.
  • Rodzaj kodu docelowego mają zostać wygenerowane. Być wybrany z czystej uzupełnione lub wirtualnego kodu maszynowego. Lub po prostu napisać część wpisu, który tworzy popularny reprezentacji pośrednich, takich jak LLVM, RTL czy JVM. Lub dokonać tłumaczenie oryginału w kodzie źródłowym w C lub JavaScript.
  • Format kodu docelowego. Można wybrać się asemblera, przenośny kod maszynowy, pamięć kodu maszynowego obraz.
  • Przekierowywanie. Gdy zestaw generatorów dobrze jest mieć wspólną część wlotową. Z tego powodu najlepiej jest mieć jednego generatora do wprowadzania wielu części.

Kompilator Architektura: Komponenty

Są to główne elementy funkcjonalne kompilatora, który generuje kod natywny (jeśli program wyjście to program w C lub na maszynie wirtualnej, nie musisz tak wiele etapów):

  • Program wejściowy (znaki Flow) jest podawany do skanera (analizator leksykalny), który przekształca ją w strumieniu tokenów.
  • Parser (parser) konstruowania jedno drzewo składniowe.
  • analizator semantyczny rozkłada informacje semantyczne i sprawdza węzły drzewa dla błędów. W rezultacie, zbudowany semantycznej wykres – drzewo składniowe z dodatkowymi właściwościami i ustalonych linki.
  • Generator kodu pośredni buduje wykres przepływu (krotki są pogrupowane w główne bloki).
  • Maszyna niezależny kod optymalizator prowadzi zarówno lokalnych (w jednostce bazowej) i globalne (do wszystkich bloków) optymalizacji zasadzie pozostały wewnątrz rutyny. Zmniejsza nadmiarowy kod i upraszcza obliczenia. Wynikiem jest zmodyfikowany wykres przepływu.
  • Generator wiąże kod docelowy podstawowe bloki do prostoliniowego kod kontroli transmisji, tworzenia pliku Przedmiotem asemblera rejestrami wirtualnymi (prawdopodobnie nieefektywny).
  • Maszyna zależne optymalizator, łącznik przydziela pamięć między rejestrami i sprawia, że planowanie zespołów. Wykonuje program konwersji w asemblerze w tym zespole z dobrym wykorzystaniu potoku.

Ponadto, korzystanie z menedżera podsystemu wykrywania błędów i tabel symboli.

Analiza Leksykalne (skanowanie)

Skaner przetwarza strumień znaków źródłowych w strumieniu tokenów, usuwanie białych znaków, komentarze i rozszerzanie makr.

Skanery często napotykają na problemy, takie jak, czy nie wziąć pod uwagę przypadek, marginesy, podziały wiersza i osadzone komentarze.

Błędy, które mogą wystąpić podczas skanowania, zwany leksykalne i obejmują:

  • znaków, które nie są w alfabecie;
  • Nadwyżka liczby znaków w słowie lub linii;
  • nie zamkniętą znak lub ciąg dosłowny;
  • koniec pliku w komentarzu.

Dekodowaniu (analizowania)

Parser przetwarza ciąg tokenów do w drzewo składniowe. Każdy węzeł w drzewie jest przechowywana jako obiekt z wymienionych dziedzin, z których wiele sami są węzły drzewa. Na tym etapie nie ma żadnych cykli. Podczas tworzenia parser należy zwrócić uwagę na poziom skomplikowania gramatyki (LL lub LR) i dowiedzieć się, czy są jakieś przepisy ujednoznacznienie. Niektóre języki wymagają analizy semantycznej.

Błędy znalezione na tym etapie są nazywane składnia. Na przykład:

  • K = 5 * (7 – y;
  • J = / 5;
  • 56 = X * 4.

analiza semantyczna

Podczas analizy semantycznej sprawdzenia dopuszczalności zasad i części stowarzyszony parsowania drzewa (umożliwiające nazwy odniesienia dla operacji wstawiania ukrytych konwersji typu, i tak dalej. D.) do formowania semantycznej wykres.

Oczywiście zestaw dopuszczalności zasad w różnych językach różnych. Jeśli kompilacji języka Java-like, kompilatory mogą znaleźć:

  • stwardnienie deklaracja zmiennej w jej zakres;
  • odniesienie do zmiennej przed jej deklaracją;
  • odniesienia do nazwy z nierejestrowanej;
  • naruszenie praw patentowych;
  • nadmierna lub niedostateczna liczba argumentów w wywołaniu metody;
  • Rodzaj niedopasowanie.

generacja

Pośredni generowania kodu generuje wykres przepływu składa się z krotki pogrupowano podstawowych bloków.

generowanie kodu wywołuje prawdziwy kod maszynowy. W tradycyjnych kompilatorów dla RISC maszyn na pierwszym etapie tworzenia asemblera z nieskończonej liczby rejestrów wirtualnych. Na maszynach CISC prawdopodobnie nie nastąpi.