Андрей Невский

Введение в разработку собственного языка и компилятора. Создаем на Rust!


Скачать книгу

= {X = Y, Y = int, Z = int}

      Далее, рассматривая типы Y и int, мы применяем замену [int/Y]. После применения этой замены множество уравнений становится:

      E = {X = int, Y = int, Z = int}

      Теперь мы можем сделать вывод, что тип переменной x (то есть X) – это int.

      В языке, который мы проектируем, алгоритм Мартелли и Монтанари может быть использован для расширения системы вывода типов, особенно при обработке более сложных выражений, включающих несколько переменных и операций. Хотя наш язык ограничивается типами int и bool, этот подход позволит нам автоматически определять типы переменных и выражений, таких как x+y или x == (1+2), минимизируя необходимость явного указания типов. Такой механизм обеспечит строгую типизации и упростит разработку компилятора, который мы реализуем в последующих главах .

      Алгоритм Мартелли и Монтанари, будучи улучшенной версией алгоритма Робинсона, предлагает более эффективное решение для работы с системами уравнений, что делает его ценным инструментом для нашего языка. Для более глубокого изучения можно обратиться к оригинальной работе Мартелли и Монтанари, где описаны детали оптимизации и примеры применения в системах программирования.

      1.2 Синтаксис

      До сих пор мы рассматривали семантику языка, который мы создаём. Теперь давайте подумаем, какой синтаксис будет достаточно хорош для того, чтобы выразить эту семантику.

      Здесь мы будем определять синтаксис для нашего языка, рассматривая различные способы его описания и определяя структуру синтаксиса.

      1.2.1 Определение синтаксиса

      Давайте начнем с определения синтаксиса для языка, который мы собираемся создать.

      Элементы, которые мы хотим реализовать, это: сложение, вычитание, умножение, деление, сравнение на равенство*¹, присваивание, оператор if с ветками then и else, а также оператор print.

      Что касается сложения, вычитания, умножения и деления, то здесь нет необходимости сильно углубляться. Для двух выражений просто используем операторы +, -, * или / как инфиксные операторы.

      Оператор if в большинстве языков позволяет создавать блоки и помещать несколько инструкций внутри одного оператора if. Но для нашего языка мы примем более простое решение: if будет принимать выражение и одну инструкцию для ветки then, а также опциональную инструкцию для ветки else, если она указана.

      Пример синтаксиса:

      if 1 == 1 then print 1 else print 0.

      Оператор print уже был упомянут, и для него мы примем синтаксис, который принимает одно выражение.

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

      Пример программы на созданном языке

      a = 1 +2 * 3

      if a == 6 then print 6 else print 0

      Вот так будет выглядеть синтаксис, правильно?

      1.2.2 Методы определения синтаксиса

      Итак, как же нам определить синтаксис, о котором мы говорили до сих пор?

      Для того чтобы программа могла быть разобрана компилятором, синтаксис должен быть определён достаточно строго, чтобы его можно было обработать компьютером. В этой книге мы будем использовать Extended Backus-Naur Form (расширенная