Инструменты: ANTLR и LLVM

Свой компилятор полезно написать руками, но в индустрии используют готовые инструменты — познакомимся с двумя главными.

Генератор парсеров — инструмент, который по описанию грамматики автоматически создаёт код лексера и парсера, избавляя от ручного написания рекурсивного спуска.

Мы написали лексер и парсер вручную — это отлично для понимания. Но для большого языка делать всё руками утомительно и чревато ошибками. Индустрия давно автоматизировала эти этапы. Разберём два знаковых инструмента.

ANTLR: генератор парсеров

ANTLR принимает грамматику в нотации, похожей на EBNF, и генерирует готовый лексер с парсером на Java, Python, C# и других языках. Вы описываете правила — ANTLR пишет код.

// грамматика ANTLR для арифметики (фрагмент)
grammar Expr;

expr  : term (('+' | '-') term)* ;
term  : factor (('*' | '/') factor)* ;
factor: NUMBER | '(' expr ')' ;

NUMBER: [0-9]+ ;
WS    : [ \t\r\n]+ -> skip ;

Узнаёте? Это ровно наша грамматика expr → term → factor, только в синтаксисе ANTLR. Строка WS ... -> skip говорит: пробелы пропускать — то, что наш лексер делал вручную. ANTLR сам построит AST и даже сгенерирует заготовки visitor-методов для обхода.

LLVM: инфраструктура back-end

LLVM — набор инструментов и библиотек для построения back-end компилятора: оптимизаций и генерации машинного кода поверх единого промежуточного представления (LLVM IR).

Если ANTLR помогает с front-end (анализом), то LLVM закрывает back-end (кодогенерацию). Вы порождаете LLVM IR — а LLVM сам его оптимизирует и скомпилирует под x86, ARM и десятки других архитектур. На LLVM построены компиляторы Clang (C/C++), Rust, Swift.

; LLVM IR для функции, складывающей два числа (фрагмент)
define i32 @add(i32 %a, i32 %b) {
  %sum = add i32 %a, %b
  ret i32 %sum
}

Как работает под капотом

Эти инструменты опираются на то, что вы уже знаете. ANTLR внутри строит парсер по грамматике (часто разновидность рекурсивного спуска) и формирует дерево. LLVM IR — это то самое промежуточное представление из нашего раздела, только индустриального уровня, с типами и оптимизирующими проходами. Разделение front-end/back-end через общий IR, о котором мы говорили, — буквально архитектура LLVM.

ИнструментЗонаЧто даёт
ANTLRfront-endлексер + парсер из грамматики
LLVMback-endоптимизация + машинный код из IR

Когда писать руками, а когда брать готовое

Ручной рекурсивный спуск оправдан для небольших языков, конфигов, простых калькуляторов и когда важны идеальные сообщения об ошибках (многие промышленные компиляторы, например GCC и Clang, используют рукописные парсеры именно ради качества диагностики). Готовые инструменты выигрывают, когда грамматика большая и часто меняется, а сроки важнее тонкого контроля.

Частые ошибки

Первое заблуждение — что инструмент избавляет от понимания теории. Наоборот: чтобы написать грамматику для ANTLR без конфликтов или отладить LLVM IR, нужно понимать приоритеты, неоднозначность и фазы — всё, что мы прошли. Инструмент ускоряет, но не заменяет знание.

Второе — тащить тяжёлый LLVM туда, где хватило бы интерпретатора на дереве. Для DSL, который считает формулы, наш calc из проекта проще и быстрее в разработке, чем полноценная компиляция в машинный код.

Итог

  • ANTLR генерирует лексер и парсер из грамматики — это автоматизированный front-end.
  • LLVM даёт back-end: оптимизации и кодогенерацию поверх единого LLVM IR.
  • Оба инструмента опираются на пройденные понятия: грамматики, AST, IR, фазы.
  • Ручной парсер хорош для малых языков и качественных ошибок; инструменты — для больших грамматик.
Проверьте себя
1. Что делает ANTLR?
AГенерирует машинный код
BПо грамматике автоматически создаёт лексер и парсер
CОптимизирует байткод
DЗапускает виртуальную машину
2. Какую часть компилятора закрывает LLVM?
AFront-end: лексер и парсер
BBack-end: оптимизации и генерацию машинного кода из IR
CТолько обработку ошибок
DТолько лексический анализ
3. Верно ли, что инструменты избавляют от знания теории компиляции?
AДа, теория больше не нужна
BНет: чтобы писать грамматики и IR без ошибок, нужно понимать приоритеты, AST и фазы
CИнструменты работают без грамматик
DТеория нужна только для лексера