⚙️ Конвеєр компілятора
Дивіться, як код стає машинним: лексинг у токени, рекурсивно-низхідний парсинг в AST, генерація трьохадресного коду та оптимізація згортанням констант — введіть будь-який арифметичний вираз і крокуйте стадіями.
Про конвеєр компілятора
Компілятор — це програма, що перетворює вихідний код, написаний високорівневою мовою, на подання нижчого рівня — зазвичай машинний код або байт-код, — яке може виконати процесор чи віртуальна машина. Конвеєр — це послідовність чітко визначених етапів: лексер (токенізатор) розбиває потік символів на змістовні токени; парсер будує абстрактне синтаксичне дерево (AST), що відображає граматичну структуру; етап проміжного представлення (IR) видає незалежну від мови форму, придатну для аналізу; а генератор коду (codegen) створює цільові інструкції, часто з проходом оптимізації — наприклад, згортанням констант, яке обчислює вирази на етапі компіляції, щоб зменшити роботу під час виконання. Розуміння цього конвеєра є основоположним для розробки мов програмування, інструментів IDE та аналізу безпеки.
Введіть або вставте арифметичний вираз у редактор і спостерігайте, як кожен етап конвеєра оновлюється в реальному часі. Панель AST показує дерево розбору, побудоване рекурсивно-низхідним парсером; панель IR показує трьохадресний код; а панель оптимізації підсвічує константи, які було згорнуто. Поекспериментуйте з вкладеними дужками та великими літеральними значеннями, щоб побачити, як змінюються глибина дерева й довжина IR.
Часті запитання
Що робить лексер і що таке токен?
Лексер (також званий токенізатором або сканером) зчитує сирі символи вихідного коду по одному й групує їх у токени — найменші змістовні одиниці мови. Для простого арифметичного виразу «3 + 4 * x» токенами будуть NUMBER(3), PLUS, NUMBER(4), STAR, IDENT(x). Кожен токен має тип і часто значення, а пробіли зазвичай відкидаються на цьому етапі.
Що таке абстрактне синтаксичне дерево (AST)?
AST — це деревоподібна структура даних, що відображає граматичну структуру вихідного коду: кожен внутрішній вузол представляє оператор чи конструкцію, а кожен листовий вузол — операнд чи літерал. AST опускає синтаксичний шум, наприклад дужки й крапки з комою, зберігаючи лише семантичну структуру, потрібну для подальшого аналізу.
Що таке рекурсивно-низхідний парсер?
Рекурсивно-низхідний парсер реалізує граматику як набір взаємно рекурсивних функцій, по одній на кожне граматичне правило. Щоб розібрати вираз, він викликає функцію виразу, яка викликає функцію терма для множення, яка викликає функцію фактора для атомів — це безпосередньо відображає ієрархію пріоритетів операторів у стеку викликів.
Що таке трьохадресний код (TAC) і чому він використовується як IR?
Трьохадресний код (TAC) — це проміжне представлення, у якому кожна інструкція має щонайбільше один оператор і три операнди (два джерела й одне призначення): наприклад, t1 = a * b; t2 = t1 + c. Ця проста, уніфікована структура спрощує аналіз потоку даних — кожна тимчасова змінна визначається один раз, що полегшує перехід до форми статичного одноразового присвоєння (SSA).
У чому різниця між компілятором та інтерпретатором?
Компілятор заздалегідь (AOT) перетворює вихідний код на цільове представлення, створюючи артефакт — бінарник, байт-код або IR, — який може виконуватися незалежно від компілятора. Інтерпретатор зчитує вихідний код (або байт-код) і виконує його безпосередньо, інструкція за інструкцією, під час виконання. Багато сучасних систем поєднують обидва підходи.