Написание простого DSL компилятора на Delphi (1. Язык) | Way23

Написание простого DSL компилятора на Delphi (1. Язык)

Перевод поста Writing a Simple DSL Compiler with Delphi (1. The Language)open in new window.

Эта статья представляет собой неформальное описание простого языка (далее я называю его "Язык") для которого я пишу компилятор. Если вы только начинаете читать эту серию, то я бы рекомендовал вам начать с этого постаopen in new window.

Давайте начнём с простого примера который вычисляет i-тое число Фибоначчи

 fib(i) {
   if i < 3 {
     return 1
   } else {
     return fib(i-2) + fib(i-1)
   }
 }
1
2
3
4
5
6
7

Код довольно прост. Первые два числа в последовательности Фибоначчи это единицы, а последующие являются суммой двух предыдущих числе в последовательности.

Следующие правила описывают язык (более или менее):

  • Язык относится к категории C-подобных языков.
  • Пробелы игнорируются.
  • Только один тип данных — целое число (integer)
  • Только три оператора: +, -, и <.
  • a < b возвращает 1 если a меньше чем b, и 0 в противоположном случае.
  • Только два оператора if и return.
  • Оператор if выполняет блок then если условное выражение не равно 0 и выполняет блок else в противном случае. Блок else обязателен.
  • Оператор return только устанавливает результат функции и не прерывает поток управления.
  • Нет оператора присваивания.
  • Каждая функция возвращает integer.
  • Параметры всегда передаются по значению.
  • Функции без оператора return возвращают 0.
  • Функции могут вызывать другие функции (или себя рекурсивно).

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

Немного более формальное (но всё ещё очень неформальное) описание синтаксиса:

/// program = {function}
///
/// function = identifier "(" [ identifier { "," identifier } ] ")" block
///
/// block = "{" statement {";" statement} [";"] "}"
///
/// statement = if
///           | return
///
/// if = "if" expression block "else" block
///
/// return = "return" expression
///
/// expression = term
///            | term operator term
///
/// term = numeric_constant
///      | function_call
///      | identifier
///
/// operator = "+" | "-" | "<"
///
/// function_call = identifier "(" [expression { "," expression } ] ")"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Последниее изменение: 03.04.2022, 12:50:42