Nauka pisania kompilatora [zamknięty]


699

Preferowane języki : C / C ++, Java i Ruby.

Szukam kilku pomocnych książek / samouczków na temat pisania własnego kompilatora w celach edukacyjnych. Najbardziej znam C / C ++, Java i Ruby, więc wolę zasoby, które dotyczą jednej z tych trzech, ale każdy dobry zasób jest akceptowalny.


ANTLR do końca. Wszystkie przedstawione poniżej zasoby wydają mi się przesadą. ANTLR jest zawsze najlepszym przyjacielem projektantów kompilatorów. A
A_Var,

Jeśli twoim głównym celem jest nauczenie się, jak ogólnie działają kompilowanie pomysłów - możesz sprawdzić i SICP skrót od Structured Interpretation programu komputerowego opartego na schemacie (lista), ale uczy ogólnych zasad. mitpress.mit.edu/sicp . Książkę tę polecił mi weteran, który pracuje dla firmy i wykonuje te kompilacje i interpretacje dla życia!
Nishant

Bezwstydna wtyczka: moja odpowiedź na podobne pytanie .
9000

Napisałem artykuł na temat tworzenia kompilatora na moim blogu: orangejuiceliberationfront.com/how-to-write-a-compiler. Koncentruje się na samych podstawach i jak zacząć, naprawdę. Jest tam wiele innych artykułów związanych z kompilatorem / codegen / parser / language design.
uliwitness

Odpowiedzi:


1084

Duża lista zasobów:

Legenda:

  • Link do pliku PDF
  • Link do drukowanej książki

22
Przeczytałem serię Let's Build a Compiler[ compilers.iecc.com/crenshaw/] , jest to naprawdę fajny napis i jest dobrym punktem wyjścia.
TheVillageIdiot

5
Myślę, że warto wspomnieć o kursie kompilatorów Coursera. Ma fajne filmy i prowadzi przez tworzenie java podobnego do języka / prostego kompilatora. Coursera Compilers Link
QuantumKarl

1
Chciałem, aby ta odpowiedź była jak najbardziej oryginalna, dlatego postanowiłem zamieścić tutaj tę informację: tutorialspoint.com/compiler_design/index.htm To, co podobało mi się w tej witrynie, to fakt, że nie bierze ona udziału w pisaniu kodu aby utworzyć kompilator, ale rozkłada go na części: fazy i etapy. Opisuje logikę i algorytmiczne podejście do projektowania bez określonego paradygmatu językowego, ponieważ wyraża zapisy dowolnego języka i alfabetu. Jest to szybki odczyt, ale zawiera koncepcje tego, co jest potrzebne do każdej części.
Francis Cugler,

70

Myślę, że to dość niejasne pytanie; tylko ze względu na głębię tematu. Kompilator można jednak rozłożyć na dwie oddzielne części; górna połowa i dolna część. Górna połowa ogólnie przyjmuje język źródłowy i konwertuje go na reprezentację pośrednią, a dolna połowa zajmuje się generowaniem kodu specyficznego dla platformy.

Niemniej jednak jednym pomysłem na łatwy sposób podejścia do tego tematu (przynajmniej tego, którego użyliśmy w mojej klasie kompilatorów) jest zbudowanie kompilatora w dwóch opisanych wyżej częściach. W szczególności dobrze zrozumiesz cały proces, po prostu budując górną połowę.

Samo wykonanie górnej połowy pozwala uzyskać doświadczenie pisania analizatora leksykalnego i parsera i przejść do generowania „kodu” (wspomnianej reprezentacji pośredniej). Więc zajmie twój program źródłowy i przekonwertuje go na inną reprezentację i przeprowadzi optymalizację (jeśli chcesz), która jest sercem kompilatora. Dolna połowa następnie przejmie pośrednią reprezentację i wygeneruje bajty potrzebne do uruchomienia programu na określonej architekturze. Na przykład dolna połowa zajmie twoją pośrednią reprezentację i wygeneruje plik wykonywalny PE.

Niektóre książki na ten temat, które uznałem za szczególnie pomocne, to Zasady i techniki kompilatorów (lub Księga smoków ze względu na uroczego smoka na okładce). Ma świetną teorię i zdecydowanie obejmuje gramatyki bezkontekstowe w naprawdę przystępny sposób. Ponadto do zbudowania analizatora leksykalnego i analizatora składni prawdopodobnie użyjesz narzędzi * nix lex i yacc. I, co ciekawe, książka o nazwie „ lex and yacczaczęła od miejsca, w którym skończyła się Księga Smoków.


55

Myślę, że Modern Implementation Compiler in ML jest najlepszym wprowadzającym tekstem do pisania kompilatorów. Istnieje również wersja Java i wersja C , z których każda może być bardziej dostępna, biorąc pod uwagę twoje języki. Książka zawiera wiele przydatnych podstawowych materiałów (skanowanie i parsowanie, analiza semantyczna, rekordy aktywacji, wybór instrukcji, generowanie natywnego kodu RISC i x86) oraz różne „zaawansowane” tematy (kompilacja OO i języków funkcjonalnych, polimorfizm, odśmiecanie, optymalizacja i pojedynczy statyczny formularz przypisania) na stosunkowo mało miejsca (~ 500 stron).

Wolę implementację nowoczesnego kompilatora niż książkę Dragon, ponieważ implementacja nowoczesnego kompilatora bada mniej pola - zamiast tego ma naprawdę solidne omówienie wszystkich tematów, które trzeba napisać poważny, przyzwoity kompilator. Po przeczytaniu tej książki będziesz gotów bezpośrednio zająć się dokumentami badawczymi, aby uzyskać więcej informacji, jeśli zajdzie taka potrzeba.

Muszę przyznać, że mam poważną słabość do kompilatora Niklausa Wirtha . Jest dostępny online w formacie PDF. Uważam, że estetyka programowania Wirtha jest po prostu piękna, jednak niektórzy uważają, że jego styl jest zbyt minimalny (na przykład Wirth preferuje parsery zejścia rekurencyjnego, ale większość kursów CS koncentruje się na narzędziach generatora parserów; projekty językowe Wirtha są dość konserwatywne.) Konstrukcja kompilatora jest bardzo zwięzłą destylacją podstawowych pomysłów Wirtha, więc czy podoba ci się jego styl, czy nie, gorąco polecam przeczytanie tej książki.



Gorąco polecam przeciwko wersji C Compiler „Nowoczesne Realizacji”, to sparaliżowana przez szczegółów niskopoziomowych powodu C. całkowicie zaśmiecanie książkę. Java 1st nie jest zbyt dobra, ponieważ jej konstrukcja OO jest słaba, Java 2nd ed nie dotyczy już języka Tiger. Zdecydowanie więc zalecam ML: nie trzeba biegle władać ML, aby to zrozumieć. ML jest zdecydowanie odpowiedni do tego zadania.
akim

44

Zgadzam się z odniesieniem do Dragon Book; IMO jest ostatecznym przewodnikiem po budowie kompilatora. Przygotuj się jednak na hardkorową teorię.

Jeśli chcesz książki o mniejszej teorii, lepszym rozwiązaniem może być Game Scripting Mastery . Jeśli jesteś całkowicie początkującym w teorii kompilatorów, zapewnia to łagodniejsze wprowadzenie. Nie obejmuje bardziej praktycznych metod parsowania (wybranie nieprzewidywalnego rekurencyjnego zejścia bez omawiania analizy LL lub LR) i, jak pamiętam, nawet nie omawia żadnej teorii optymalizacji. Ponadto zamiast kompilować do kodu maszynowego, kompiluje się do kodu bajtowego, który powinien działać na maszynie wirtualnej, którą również zapisujesz.

To wciąż przyzwoita lektura, szczególnie jeśli możesz ją kupić tanio na Amazon. Jeśli chcesz tylko łatwego wprowadzenia do kompilatorów, Game Scripting Mastery nie jest złą drogą. Jeśli chcesz zagrać hardcorowo z przodu, powinieneś zadowolić się tylko Dragon Book.


1
Game Scripting Mastery to świetny zasób do nauki, ponieważ gdy skończysz, będziesz mieć grywalną, skryptowalną grę przygodową 2D. To sprawia, że ​​każde ćwiczenie koncentruje się na określonym celu i motywuje czytelnika.
Dour High Arch

1
Dragon jest nieco nadmiernie skoncentrowany na analizie gramatycznej. Jeśli nie próbujesz analizować czegoś tak niemożliwego, jak C ++ lub mniej więcej przy użyciu generatorów analizatora składni, ale możesz użyć np. Ręcznie opracowanej gramatyki LL, możesz poszukać czegoś, co traktuje pola procentowe kompilatora inne niż transformacja gramatyczna i sprawdzanie
Marco van de Voort

27

„Zbudujmy kompilator” jest niesamowite, ale jest trochę przestarzałe. (Nie twierdzę, że czyni to nawet trochę mniej ważnym).

Lub sprawdź SLANG . Jest to podobne do „Zbudujmy kompilator”, ale jest znacznie lepszym zasobem, szczególnie dla początkujących. W zestawie znajduje się samouczek pdf, który obejmuje 7 kroków w nauce kompilatora. Dodanie łącza quora, ponieważ zawiera łącza do wszystkich różnych portów SLANG, w C ++, Java i JS, również interpreterów w Pythonie i Javie, pierwotnie napisanych przy użyciu C # i platformy .NET.


5
Zgadzam się, że ta seria jest nieco przestarzała, choć nadal jest przydatna. Jednak moim największym problemem jest fakt, że próbuje on wypisywać bezpośrednio na język asemblera zamiast budować dowolny typ drzewa parsowania, co oznacza (w przeciwieństwie do tego, co podano w pierwszym artykule), że nie jest bardzo przydatny do pisania tłumacz.
a_m0d

23

Jeśli chcesz użyć potężnych narzędzi wyższego poziomu, zamiast budować wszystko samemu, przejrzenie projektów i odczytów tego kursu jest całkiem dobrą opcją. Jest to kurs językowy autora silnika parsera Java ANTLR. Książkę do kursu możesz otrzymać w formacie PDF od Pragmatic Programmers .

Kurs omawia standardowe elementy kompilatora kompilatora, które można zobaczyć gdzie indziej: parsowanie, sprawdzanie typów i typów, polimorfizm, tabele symboli i generowanie kodu. Prawie jedyne, czego nie obejmuje, to optymalizacje. Ostateczny projekt jest programem, który kompiluje podzbiór C . Ponieważ używasz narzędzi takich jak ANTLR i LLVM, możliwe jest napisanie całego kompilatora w ciągu jednego dnia (mam na to dowód istnienia, chociaż mam na myśli ~ 24 godziny). Jest ciężki w praktycznej inżynierii przy użyciu nowoczesnych narzędzi, nieco lżejszy w teorii.

Nawiasem mówiąc, LLVM jest po prostu fantastyczny. W wielu sytuacjach, w których normalnie można skompilować aż do złożenia, lepiej byłoby zamiast tego skorzystać z pośredniej reprezentacji LLVM . Jest na wyższym poziomie, między platformami, a LLVM jest dość dobry w generowaniu zoptymalizowanego zestawu z niego.


Pierwszy link jest martwy.
Lynn

20

Jeśli masz mało czasu, polecam „Kompilator budowy” Niklausa Wirtha (Addison-Wesley. 1996) , małą książeczkę, którą możesz przeczytać w ciągu jednego dnia, ale wyjaśnia ona podstawy (w tym sposób implementacji leksykonów, parserów rekurencyjnych, oraz własne maszyny wirtualne oparte na stosie). Po tym, jeśli chcesz głęboko zanurzyć się, nie ma mowy o książce Dragon, jak sugerują inni komentatorzy.


Jeśli nie masz dużo czasu, nie pisz kompilatora.
Ingo

17

Możesz zajrzeć do Lex / Yacc (lub Flex / Bison, jakkolwiek chcesz je nazwać). Flex to analizator leksykalny, który przeanalizuje i zidentyfikuje komponenty semantyczne („tokeny”) twojego języka, a Bison zostanie użyty do zdefiniowania, co się stanie, gdy każdy token zostanie przeanalizowany. Może to być, ale zdecydowanie nie jest ograniczone do drukowania kodu C, dla kompilatora, który skompiluje się do C, lub dynamiczne uruchamianie instrukcji.

Często zadawane pytania powinny ci pomóc, a ten samouczek wygląda całkiem przydatny.


17

Ogólnie rzecz biorąc, nie ma pięciominutowego samouczka dla kompilatorów, ponieważ jest to skomplikowany temat, a napisanie kompilatora może zająć miesiące. Będziesz musiał przeprowadzić własne wyszukiwanie.

Python i Ruby są zwykle interpretowane. Być może chcesz zacząć od tłumacza ustnego. Jest to ogólnie łatwiejsze.

Pierwszym krokiem jest napisanie formalnego opisu języka, gramatyki języka programowania. Następnie musisz przekształcić kod źródłowy, który chcesz skompilować lub zinterpretować zgodnie z gramatyką, w abstrakcyjne drzewo składniowe, wewnętrzną formę kodu źródłowego, który komputer rozumie i na którym może operować. Ten krok jest zwykle nazywany analizowaniem składni, a oprogramowanie analizujące kod źródłowy nazywa się analizatorem składni. Często analizator składni jest generowany przez generator analizatora składni, który przekształca gramatykę formalną w kod źródłowy maszyny. Dla dobrego, niematematycznego wyjaśnienia parsowania polecam techniki parsowania - praktyczny przewodnik. Wikipedia ma porównanie generatorów parserów, z których możesz wybrać ten, który jest odpowiedni dla Ciebie. W zależności od wybranego generatora analizatora składni,

Napisanie parsera dla twojego języka może być naprawdę trudne, ale zależy to od twojej gramatyki. Proponuję więc zachować prostą gramatykę (w przeciwieństwie do C ++); dobrym tego przykładem jest LISP.

W drugim etapie abstrakcyjne drzewo składniowe jest przekształcane ze struktury drzewa w liniową reprezentację pośrednią. Jako dobry przykład tego kodu bajtowego Lua często się powołuje. Ale pośrednia reprezentacja naprawdę zależy od twojego języka.

Jeśli budujesz tłumacza, będziesz musiał po prostu zinterpretować reprezentację pośrednią. Możesz go również skompilować na czas. Polecam LLVM i libjit do kompilacji just-in-time. Aby język był użyteczny, będziesz musiał także dołączyć funkcje wejścia i wyjścia oraz być może małą standardową bibliotekę.

Jeśli zamierzasz skompilować język, będzie to bardziej skomplikowane. Będziesz musiał napisać backendy dla różnych architektur komputerowych i wygenerować kod maszynowy z pośredniej reprezentacji w tych backendach. Polecam LLVM do tego zadania.

Jest kilka książek na ten temat, ale nie mogę polecić żadnej z nich do ogólnego użytku. Większość z nich jest zbyt akademicka lub zbyt praktyczna. Nie ma „Naucz się pisać kompilator za 21 dni”, dlatego będziesz musiał kupić kilka książek, aby dobrze zrozumieć cały ten temat. Jeśli przeszukasz Internet, znajdziesz kilka książek online i notatek z wykładów. Może w pobliżu znajduje się biblioteka uniwersytecka, w której można wypożyczyć książki na kompilatorach.

Polecam również dobrą wiedzę podstawową z zakresu teoretycznej informatyki i teorii grafów, jeśli chcesz poważnie potraktować swój projekt. Pomocny będzie także stopień naukowy z informatyki.


++ Masz rację, że dobrze jest wiedzieć wszystkie te rzeczy i może to być świetna robota, ale nauczyłem się również od niektórych ekspertów, jak nie robić z tego wielkich rzeczy. Dobrze jest wiedzieć rzeczy, a jeszcze lepiej wiedzieć, kiedy ich nie używać, co jest przez większość czasu.
Mike Dunlavey


11

Jedną książką, która nie została jeszcze zasugerowana, ale bardzo ważna jest „Linkers and Loaders” Johna Levine'a. Jeśli nie korzystasz z zewnętrznego asemblera, będziesz potrzebować sposobu na wyjście pliku obiektowego, który można połączyć z końcowym programem. Nawet jeśli używasz zewnętrznego asemblera, prawdopodobnie będziesz musiał zrozumieć relokacje i jak działa cały proces ładowania programu, aby stworzyć działające narzędzie. Ta książka zbiera wiele losowych informacji na temat tego procesu dla różnych systemów, w tym Win32 i Linux.


10

Dragon Book to zdecydowanie książka „kompilatory budowlane”, ale jeśli twój język nie jest tak skomplikowany jak obecna generacja języków, możesz spojrzeć na wzorzec interpretera z Wzorów projektowych .

Przykład w książce projektuje język podobny do wyrażenia regularnego i jest dobrze przemyślany, ale jak mówią w książce, dobrze jest przemyśleć cały proces, ale jest skuteczny tylko w małych językach. Jednak o wiele szybciej jest napisać tłumacza dla małego języka z tym wzorcem niż uczyć się o wszystkich różnych typach parserów, yacc i lex, i tak dalej ...


10

Jeśli chcesz korzystać z LLVM, sprawdź to: http://llvm.org/docs/tutorial/ . Uczy, jak pisać kompilator od zera za pomocą frameworka LLVM i nie zakłada, że ​​masz wiedzę na ten temat.

Samouczek sugeruje napisanie własnego parsera i leksykera itp., Ale radzę zajrzeć do bizona i flex, gdy tylko wpadniesz na ten pomysł. Ułatwiają życie.


Ale dokumentacja konfiguracji Visual Studio jest źle napisana i nie ma przykładów
SpicyWeenie

10

Znalazłem książkę o smokach zbyt trudną do przeczytania ze zbyt dużym naciskiem na teorię języka, która tak naprawdę nie jest wymagana do napisania kompilatora w praktyce.

Dodałbym książkę Oberona, która zawiera pełne źródło niezwykle szybkiego i prostego kompilatora Oberona Project Oberon .

Tekst alternatywny


10

Pamiętam, jak zadałem to pytanie około siedem lat temu, kiedy byłem raczej nowy w programowaniu.

Byłem bardzo ostrożny, kiedy zapytałem i, co zaskakujące, nie spotkałem się z taką krytyką, jak tutaj. Wskazali mi jednak na „ Dragon Book ”, która moim zdaniem jest naprawdę świetną książką, która wyjaśnia wszystko, co musisz wiedzieć, aby napisać kompilator (oczywiście będziesz musiał opanować jeden lub dwa języki. Im więcej języki, które znasz, tym lepiej.).

I tak, wiele osób mówi, że czytanie tej książki jest szalone i niczego się z niej nie nauczysz, ale całkowicie się z tym nie zgadzam.

Wiele osób twierdzi również, że pisanie kompilatorów jest głupie i bezcelowe. Istnieje wiele powodów, dla których warto tworzyć kompilatory:

  • Bo to zabawne.
  • Jest to edukacyjne, gdy uczysz się pisać kompilatory, nauczysz się dużo o informatyce i innych technikach przydatnych podczas pisania innych aplikacji.
  • Gdyby nikt nie napisał kompilatorów, istniejące języki nie poprawiłyby się.

Nie napisałem od razu własnego kompilatora, ale po zapytaniu wiedziałem, od czego zacząć. A teraz, po nauczeniu się wielu różnych języków i przeczytaniu Dragon Book, pisanie nie stanowi większego problemu. (Studiuję także atm inżynierii komputerowej, ale większość tego, co wiem o programowaniu, jest samoukiem).

Podsumowując, The Dragon Book to świetny „tutorial”. Ale poświęć trochę czasu na opanowanie języka lub dwóch, zanim spróbujesz napisać kompilator. Nie oczekuj jednak, że będziesz guru kompilatora w ciągu najbliższej dekady.

Książka jest również dobra, jeśli chcesz nauczyć się pisać parsery / tłumaczy.


9

„... Zbudujmy kompilator ...”

Po drugie: http://compilers.iecc.com/crenshaw/ autor: @sasb . Zapomnij o kupowaniu na razie kolejnych książek.

Dlaczego? Narzędzia i język.

Wymaganym językiem jest Pascal i jeśli dobrze pamiętam, oparty jest na Turbo-Pascal. Tak się dzieje, jeśli wejdziesz na http://www.freepascal.org/ i pobierzesz kompilator Pascal, wszystkie przykłady działają bezpośrednio ze strony ~ http://www.freepascal.org/download.var Piękna rzecz o Free Pascal jest w stanie używać go prawie na każdym procesorze lub systemie operacyjnym, na którym Ci zależy.

Po opanowaniu lekcji wypróbuj bardziej zaawansowaną Dragon Book ~ http://en.wikipedia.org/wiki/Dragon_book


9

Patrzę na tę samą koncepcję i znalazłem ten obiecujący artykuł Joela Pobara,

Utwórz kompilator językowy dla .NET Framework - nie jestem pewien, dokąd to poszło

Utwórz kompilator językowy dla .NET Framework - kopia pdf oryginalnego dokumentu w formacie pdf

omawia koncepcję kompilatora na wysokim poziomie i zaczyna wymyślać swój własny język dla frameworka .Net. Chociaż jego celem jest .NET Framework, wiele z tych koncepcji powinno być możliwe do odtworzenia. Artykuł obejmuje:

  1. Definicja Langauge
  2. Skaner
  3. Parser (nieco mnie to interesuje)
  4. Celowanie w .NET Framework
  5. Generator kodów

są inne tematy, ale masz rację.

Jest skierowany do osób rozpoczynających działalność, napisanych w C # (niezupełnie Java)

HTH

kości


Co oznacza „niezupełnie Java”?
Hejazzman

haha, przepraszam, miałem na myśli napisany dla .Net, który zasadniczo jest podobny do Java. Oba są w stylu JIT. :)
dbones

8

Prostym sposobem na utworzenie kompilatora jest użycie bison i flex (lub podobnego), zbudowanie drzewa (AST) i wygenerowanie kodu w C. Generowanie kodu C jest najważniejszym krokiem. Generując kod C, Twój język będzie automatycznie działał na wszystkich platformach, które mają kompilator C.

Generowanie kodu C jest tak proste, jak generowanie HTML (wystarczy użyć print lub odpowiednika), co z kolei jest znacznie łatwiejsze niż napisanie parsera C lub parsera HTML.


8

Z kompilatora często zadawanych pytań :

„Programowanie komputera osobistego” Per Brinch Hansen Prentice-Hall 1982 ISBN 0-13-730283-5

Ta niestety zatytułowana książka wyjaśnia projektowanie i tworzenie środowiska programowania dla pojedynczego użytkownika dla mikr, z wykorzystaniem języka podobnego do Pascala, zwanego Edison. Autor przedstawia cały kod źródłowy i objaśnienia dotyczące krok po kroku implementacji kompilatora Edison i prostego wspierającego systemu operacyjnego, wszystkie napisane w samym Edison (z wyjątkiem małego wspierającego jądra napisanego w asemblerze symbolicznym dla PDP 11/23; kompletne źródło można również zamówić dla komputera IBM PC).

Najciekawsze w tej książce są: 1) jej zdolność do zademonstrowania, jak stworzyć kompletny, samodzielny, samowystarczalny, użyteczny kompilator i system operacyjny, oraz 2) interesująca dyskusja na temat problemów z projektowaniem i specyfikacją języka oraz handlu offs w rozdziale 2.

„Brinch Hansen o kompilatorach Pascala” Per Brinch Hansen Prentice-Hall 1985 ISBN 0-13-083098-4

Inna lekka teoria, wymagająca od pragmatyki, to książka z kodem. Autor przedstawia projekt, implementację i pełny kod źródłowy kompilatora i interpretera kodu p dla Pascal- (Pascal „minus”), podzbiór Pascala z typami logicznymi i liczbami całkowitymi (ale bez znaków, liczb rzeczywistych, podrzędnych lub wyliczonych) , definicje stałych i zmiennych oraz typy tablic i rekordów (ale bez typów spakowanych, wariantów, zestawów, wskaźników, bezimiennych, o zmienionych nazwach lub typach plików), wyrażenia, instrukcje przypisania, definicje procedur zagnieżdżonych z parametrami wartości i zmiennych, jeśli instrukcje, instrukcje while, oraz bloki początku-końca (ale bez definicji funkcji, parametrów proceduralnych, instrukcji i etykiet goto, instrukcji case, instrukcji powtórzeń, instrukcji i instrukcji).

Kompilator i interpreter są napisane w Pascal * (Pascal „star”), podzbiorze Pascal rozszerzonym o niektóre funkcje w stylu Edisona do tworzenia systemów programistycznych. Kompilator Pascal * na komputer IBM jest sprzedawany przez autora, ale łatwo jest przenieść kompilator Pascal na książkę na dowolną wygodną platformę Pascal.

Ta książka ułatwia projektowanie i implementację kompilatora. Szczególnie podoba mi się sposób, w jaki autor zajmuje się jakością, niezawodnością i testowaniem. Kompilator i interpreter mogą być łatwo wykorzystane jako podstawa dla bardziej zaangażowanego języka lub projektu kompilatora, szczególnie jeśli jesteś zmuszony szybko coś uruchomić.


8

Powinieneś sprawdzić „ ichbiny ” Dariusa Bacona , który jest kompilatorem małego dialektu Lisp, atakującego C, na nieco ponad 6 stronach kodu. Przewaga nad większością kompilatorów zabawkowych polega na tym, że język jest na tyle kompletny, że kompilator jest w nim napisany. (Plik tarball zawiera również tłumacza do ładowania rzeczy.)

Jest więcej rzeczy na temat tego, co uważam za przydatne w nauce pisania kompilatora na mojej stronie Ur-Scheme .


8
  1. To rozległy temat. Nie lekceważ tego punktu. I nie lekceważ mojego punktu, aby go nie lekceważyć.
  2. Słyszę Księgę Smoków to (?) Miejsce na rozpoczęcie, wraz z wyszukiwaniem. :) Bądź lepszy w wyszukiwaniu, w końcu będzie to twoje życie.
  3. Budowanie własnego języka programowania jest absolutnie dobrym ćwiczeniem! Ale wiedz, że nigdy nie zostanie on ostatecznie wykorzystany do żadnego praktycznego celu. Wyjątki od tego są nieliczne i bardzo dalekie.

4
Jeśli nie czytałeś książki o smokach. Proszę nie polecać tego. Czy kiedykolwiek zaimplementowałeś kompilator?

Tak, jak sama nazwa wskazuje, Dragon Book to potwór. Bardzo dogłębne, ale mimo to bardzo dobre zasoby. Nie poleciłbym go jednak początkującym ...
Zachary Murray,

2
@Neil: Nie przeszukiwałeś mnie, prawda? lol. blog.280z28.org Ale nie, nie przeczytałem tej książki.
Sam Harwell,

Czytam ją obecnie (książkę o smokach), a jednocześnie Lex / Yacc, uważam, że książka jest całkiem dobra. Osobiście.
Simeon Pilgrim

1
Aby być uczciwym, poprzedziłem go słowem „Słyszę ...”. :) # 1 i # 3 są punktami, które uważam za niezwykle ważne, aby wiedzieć, w których się wchodzisz, ale nie są wymieniane tak często.
Sam Harwell,

8

Kompilator LCC ( wikipedia ) ( strona projektu ) ( github.com/drh/lcc ) Frasera i Hansona opisano w ich książce „A Retargetable C Compiler: Design and Implementation”. Jest dość czytelny i wyjaśnia cały kompilator, aż do generowania kodu.


Wydaje się, że to bardzo dobry zasób dzięki.
gideon

7

Python jest dostarczany z kompilatorem napisanym w Pythonie. Możesz zobaczyć kod źródłowy, który obejmuje wszystkie fazy, od parsowania, abstrakcyjnego drzewa składni, emitowania kodu itp. Włam go.


7

Niestety, jest w języku hiszpańskim, ale jest to bibliografia kursu „Compiladores e Intérpretes” (Kompilatorzy i Tłumacze) w Argentynie.

Kurs obejmował teorię języka formalnego i budowę kompilatora, a oto tematy, które trzeba zbudować, co najmniej prosty kompilator:

  • Projektowanie kompilatorów w C.
    Allen I. Holub

    Prentice-Hall. 1990.

  • Compiladores. Teoría y Construcción.
    Sanchís Llorca, FJ, Galán Pascual, C. Redakcja Paraninfo. 1988.

  • Budowa kompilatora.
    Niklaus Wirth

    Addison-Wesley. 1996.

  • Lenguajes, Gramáticas y Autómatas. Un enfoque práctico.
    Pedro Isasi Viñuela, Paloma Martínez Fernández, Daniel Borrajo Millán. Addison-Wesley Iberoamericana (España). 1997.

  • Sztuka projektowania kompilatora. Teoria i praktyka.
    Thomas Pittman, James Peters.

    Prentice-Hall. 1992.

  • Budowa kompilatora zorientowana obiektowo.
    Jim Holmes.
    Prentice Hall, Englewood Cliffs, NJ 1995

  • Compiladores. Conceptos Fundamentales.
    B. Teufel, S. Schmidt, T. Teufel.

    Addison-Wesley Iberoamericana. 1995.

  • Wprowadzenie do teorii automatów, języków i obliczeń.

    John E. Hopcroft. Jeffref D. Ullman.
    Addison-Wesley. 1979.

  • Wprowadzenie do języków formalnych.
    György E. Révész.

    Mc Graw Hill. 1983.

  • Techniki parsowania. Praktyczny przewodnik.
    Dick Grune, Ceriel Jacobs.
    Impreso por los autores. 1995
    http://www.cs.vu.nl/~dick/PTAPG.html

  • Yacc: Yet Another Compiler-Compiler.
    Stephen C. Johnson
    Computing Science Raport techniczny nr 32, 1975. Bell Laboratories. Murray Hill, New
    Jersey.

  • Lex: Generator analizatora leksykalnego.
    ME Lesk, E. Schmidt. Computing Science Technical Report nr 39, 1975. Bell Laboratories. Murray Hill, New Jersey.

  • Lex & Yacc.
    John R. Levine, Tony Mason, Doug Brown.
    O'Reilly & Associates. 1995.

  • Elementy teorii obliczeń.
    Harry R. Lewis, Christos H. Papadimitriou. Segunda Edición. Prentice Hall. 1998.

  • Algoritmo Eficiente para la Construcción del Grafo de Dependencia de Control.
    Salvador V. Cavadini.
    Trabajo Final de Grado para obtener el Título de Ingeniero en Computación.
    Facultad de Matemática Aplicada. UCSE 2001.


6

Nie książka, ale artykuł techniczny i niezwykle zabawne doświadczenie edukacyjne, jeśli chcesz dowiedzieć się więcej o kompilatorach (i metakompilatorach) ... Ta strona internetowa poprowadzi Cię przez proces tworzenia całkowicie samodzielnego systemu kompilatora, który może się kompilować w innych językach:

Samouczek: Metakompilatory Część 1

Wszystko to opiera się na niesamowitym 10-stronicowym dokumencie technicznym:

Val Schorre META II: Kompilator zorientowany na składnię

od uczciwego boga w 1964 roku. Nauczyłem się budować kompilatory z tego w 1970 roku. Jest niesamowity moment, kiedy w końcu zastanawiasz się, jak kompilator może się zregenerować ...

Znam autora strony z czasów studenckich, ale nie mam z nią nic wspólnego.


Jak mówią inni, jest WIELKI argument, myślę, że sushi to zadanie końcowe dla kawalera, wymaga znajomości wielu pojęć z matematyki, informatyki i tak dalej.
ingconti

Jeśli nie znasz tych tematów, nie powinieneś naprawdę próbować budować poważnego kompilatora. Jeśli jednak masz 2-3-letnie studia informatyczne (programowanie, struktury danych, język asemblera), praca MetaII będzie dla ciebie odpowiednia.
Ira Baxter

5

Podobał mi się również samouczek Crenshaw , ponieważ absolutnie jasne jest, że kompilator jest tylko kolejnym programem, który odczytuje niektóre dane wejściowe i zapisuje niektóre z nich.

Przeczytaj to.

Pracuj, jeśli chcesz, ale spójrz na kolejne odniesienie, jak naprawdę napisane są większe i bardziej kompletne kompilatory.

I przeczytaj On Trusting Trust , aby uzyskać wskazówki na temat nieoczywistych rzeczy, które można zrobić w tej domenie.


5

Jeśli interesuje Cię napisanie kompilatora dla języka funkcjonalnego (zamiast języka proceduralnego), Simon Peyton-Jones i David Lester „ Implementacja języków funkcjonalnych: samouczek ” jest doskonałym przewodnikiem.

Podstawy koncepcyjne działania oceny funkcjonalnej opierają się na przykładach w prostym, ale potężnym języku funkcjonalnym zwanym „rdzeniem”. Dodatkowo, każda część kompilatora języka Core jest objaśniona przykładami kodu w Mirandzie (czysty język funkcjonalny bardzo podobny do Haskell).

Opisano kilka różnych typów kompilatorów, ale nawet jeśli będziesz postępować zgodnie z tak zwanym kompilatorem szablonów dla Core, będziesz doskonale rozumiał, co sprawia, że ​​funkcjonalne programowanie działa.


5

Możesz używać BCEL przez Apache Software Foundation. Za pomocą tego narzędzia możesz generować kod podobny do asemblera, ale jest to Java z API BCEL. Możesz dowiedzieć się, jak wygenerować kod języka pośredniego (w tym przypadku kod bajtowy).

Prosty przykład

  1. Utwórz klasę Java za pomocą tej funkcji:

    public String maxAsString(int a, int b) {
        if (a > b) {
            return Integer.valueOf(a).toString();
        } else if (a < b) {
            return Integer.valueOf(b).toString();
        } else {
            return "equals";
        }
    }
    

Teraz uruchom BCELifier z tą klasą

BCELifier bcelifier = new BCELifier("MyClass", System.out);
bcelifier.start();

Możesz zobaczyć wynik na konsoli dla całej klasy (jak zbudować kod bajtowy MyClass.java). Kod funkcji jest następujący:

private void createMethod_1() {
  InstructionList il = new InstructionList();
  MethodGen method = new MethodGen(ACC_PUBLIC, Type.STRING, new Type[] { Type.INT, Type.INT }, new String[] { "arg0", "arg1" }, "maxAsString", "MyClass", il, _cp);

  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load first parameter to address 1
  il.append(InstructionFactory.createLoad(Type.INT, 2)); // Load second parameter to adress 2
    BranchInstruction if_icmple_2 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPLE, null); // Do if condition (compare a > b)
  il.append(if_icmple_2);
  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load value from address 1 into the stack
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_13 = il.append(InstructionFactory.createLoad(Type.INT, 1));
  il.append(InstructionFactory.createLoad(Type.INT, 2));
    BranchInstruction if_icmpge_15 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null); // Do if condition (compare a < b)
  il.append(if_icmpge_15);
  il.append(InstructionFactory.createLoad(Type.INT, 2));
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_26 = il.append(new PUSH(_cp, "equals")); // Return "equals" string
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  if_icmple_2.setTarget(ih_13);
  if_icmpge_15.setTarget(ih_26);
  method.setMaxStack();
  method.setMaxLocals();
  _cg.addMethod(method.getMethod());
  il.dispose();
}

5

Jest tu wiele dobrych odpowiedzi, więc pomyślałem, że dodam jeszcze jedną do listy:

Ponad dziesięć lat temu dostałem książkę Project Oberon, która zawiera bardzo dobrze napisany tekst na kompilatorze. Książka naprawdę wyróżnia się tym, że źródło i wyjaśnienia są bardzo praktyczne i czytelne. Pełny tekst (wydanie z 2005 r.) Został udostępniony w formacie pdf, więc możesz go pobrać już teraz. Kompilator omówiono w rozdziale 12:

http://www.ethoberon.ethz.ch/WirthPubl/ProjectOberon.pdf

Niklaus Wirth, Jürg Gutknecht

(Leczenie nie jest tak obszerne jak jego książka o kompilatorach)

Przeczytałem kilka książek o kompilatorach i mogę poprzeć smoczą książkę, czas poświęcony na tę książkę jest bardzo opłacalny.


4

Jak dotąd tej listy nie ma na liście:

Podstawy projektowania kompilatorów (Torben Mogensen) (z wydziału informatyki Uniwersytetu w Kopenhadze)

Interesuję się również poznawaniem kompilatorów i planuję wejść do tej branży w ciągu najbliższych kilku lat. Ta książka jest idealną książką teoretyczną do nauki kompilatorów, o ile widzę. Kopiowanie i reprodukowanie jest BEZPŁATNE, czyste i starannie napisane, a także daje ci prosty angielski bez kodu, ale nadal przedstawia mechanikę za pomocą instrukcji i schematów itp. Warto zobaczyć imo.


Dodałem go do listy dzięki :)
Anton
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.