Ответы пользователя по тегу Трансляторы
  • На какие слои должен (может) разделяться ЯП и его компилятор?

    SerafimArts
    @SerafimArts Автор вопроса
    Senior Notepad Reader
    Итак, корректный ответ на поставленный вопрос:

    Для начала, стоит понимать, что задача компилятора - взять сырец на X языке и перегнать его на Y язык. В современной жизни устоялась терминология "транслятора" и процесс "транслитерации", дабы не путать перегон в машинный код и на другой язык.

    В классическом варианте этапы следующие:
    1) Лексический анализ: Используя правила разбивает сырец на набор токенов (терминалов)
    2) Синтаксический анализ: Используя правила и набор токенов структурирует их в AST
    3) Семантический анализ: Проверяет корректность данных внутри AST (какого фига семантический анализ на этом этапе, а не позже, я, признаться хз).
    4) Генерация промежуточного кода: В частности, трёхадресного и этот этап имеет смысл при реализации императивных языков. Трёхадресный код так же можно заменить на опкод, байткод или прочие "заменители" промежуточного кода.
    5) Оптимизатор кода.
    6) Результат (генерация в конечный код)
    Во время всех процессов активно используется "таблица символов", грубо говоря "словарь".

    Ориентируясь на эти данные я сделал несколько выводов и перестроил архитектуру следующим образом:
    1) Парсинг (лексер + синтаксис)
    2) Построение таблицы символов в немного фривольном формате: Имя + Тип + Адрес/Позиция в исходном документе + Метаданные (AST и проч.)
    3) Билдер промежуточного кода (Reflection API)
    4) Приведение типов
    5) Валидация (вместо проверки корректности семантики из AST мне показалось удобнее оперировать высокоуровневым API, применяя некий паттерн матчинг, т.к. каждый тип проходит эту стадию сборки от 1 до 8).
    6) Экстенды (есть спец.тип в GralphQL, который занимается манкипатчингом) -> после него переход к п.3
    7) Рантайм (вызовы функций и проч) -> после него переход к п.3
    8) Выходной результат (Reflection API)

    Ключевым моментом становится метод а-ля рекурсивного спуска по этапам сборки от 1 до 8. Таким образом в самом рантайме (т.е. во время прохода по фазам их выполнению) можно дополнять данные в любую другую фазу. Пока хз как будет выглядеть на практике, но идея мне нравится.

    Крайне рекомендую к прочтению:
    1) Тут много инфы человеческим языком https://ps-group.github.io/compilers/ особенно вот эта статья понравилась: https://ps-group.github.io/compilers/fsm которая рассказывает о построении таблицы переходов в синтаксическом анализаторе.
    2) И вот эта книжеца: https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D... Довольно сложная для понимания для неподготовленного читателя, но позволяет уточнить некоторые нюансы и ответить на вопросы.
    Ответ написан
    2 комментария