Pomimo tego, że są tak różnorodni, istnieje kilka wspólnych koncepcji, które dzielą wszystkie poważne, nowoczesne języki programowania. Dwa z nich stanowią rdzeń odpowiedzi na powyższe pytania.
Jakie kroki zdarzają się między naciśnięciem przycisku Enter a kodem maszynowym wygenerowanym z mojego kodu python wykonywanego na moim CPU?
Kod jest analizowany, analizowany i wprowadzany do interpretera. Chodzi o bardzo ważny obszar informatyki zwany teorią kompilatora . Kompilator to program, który tłumaczy kod z jednego języka (kodu źródłowego) na inny język (zazwyczaj kod maszynowy, chociaż istnieją „transpilatory”, które tłumaczą z jednego języka wysokiego poziomu na inny). To naprawdę ogromny temat, który możesz poświęcić lat na badania, ale oto podstawowa wersja:
Kompilator zaczyna się od parsera , procedury, która odczytuje kod źródłowy i stosuje do niego reguły składniowe języka, aby dowiedzieć się, czy ma on sens jako poprawny kod Pythona (w twoim przypadku). Jeśli tak się nie stanie, analizator składni wyrzuci błąd, a kompilator wyskoczy, ale jeśli tak, analizator wyśle to, co jest znane jako abstrakcyjne drzewo składni, lub w skrócie AST. AST jest drzewną strukturą danych, której każdy z węzłów zawiera element składni. Na przykład, jeśli powiesz x = 5
, możesz skończyć z BinaryExpression
węzłem o operator
wartości =
, Left
wartości ReferenceExpression(x)
i Right
wartości IntegerLiteralExpression(5)
. Twój cały program może być reprezentowany przez takie wielkie drzewo.
Gdy parser wytworzy AST, drugą fazą jest analiza semantyczna . Mówiąc wprost, oznacza to „dowiedzieć się, co oznacza ten AST”. Sprawdza AST, aby ustalić, czy zrobiłeś coś, co jest nielegalne, mimo że jest to poprawna analiza (na przykład próba wywołania funkcji 1-argumentowej z 3 argumentami), i jeśli to zrobisz, wywołuje błędy. W przeciwnym razie analizuje AST i dokonuje edycji, aby ułatwić zrozumienie maszyny.
Trzecią fazą jest generowanie kodu. Po w pełni przeanalizowanym, uproszczonym, poprawnym AST, podajesz go do generatora, który prowadzi AST i generuje kod w języku wyjściowym. To jest twój gotowy produkt.
W Pythonie używa interpretera, a nie kompilatora. Interpreter działa dokładnie tak samo jak kompilator, z jedną różnicą: zamiast generowania kodu ładuje dane wyjściowe do pamięci i wykonuje je bezpośrednio w systemie. (Dokładne szczegóły tego, jak to się dzieje, mogą się znacznie różnić między różnymi językami i różnymi tłumaczami.)
A jak to się ma do systemu wykonawczego Python i / lub biblioteki?
Wszystkie języki oprócz najprostszych są wyposażone w zestaw predefiniowanych funkcji, które są ważne dla dużego odsetka użytkowników i byłoby trudne dla użytkowników do samodzielnego wdrożenia z tego czy innego powodu. Ich kod może wywoływać te funkcje bez potrzeby korzystania z bibliotek stron trzecich. (Na przykład w Pythonie masz print
, który wysyła dane wyjściowe stdout
. Powodzenia we wdrażaniu go samodzielnie!) Ten zestaw funkcji jest na ogół gromadzony we wspólnej bibliotece, do której kod może wywoływać w czasie wykonywania, dlatego jest znany jako biblioteka środowiska wykonawczego języka lub po prostu „środowisko wykonawcze” w skrócie.