Перевод поста Writing a Simple DSL Compiler with Delphi (1. The Language).
Эта статья представляет собой неформальное описание простого языка (далее я называю его "Язык") для которого я пишу компилятор. Если вы только начинаете читать эту серию, то я бы рекомендовал вам начать с этого поста.
Давайте начнём с простого примера который вычисляет i-тое число Фибоначчи
1 2 3 4 5 6 7 |
fib(i) { if i < 3 { return 1 } else { return fib(i-2) + fib(i-1) } } |
Код довольно прост. Первые два числа в последовательности Фибоначчи это единицы, а последующие являются суммой двух предыдущих числе в последовательности.
Следующие правила описывают язык (более или менее):
- Язык относится к категории C-подобных языков.
- Пробелы игнорируются.
- Только один тип данных — целое число (
integer
) - Только три оператора:
+
,-
, и<
. a < b
возвращает1
если a меньше чемb
, и0
в противоположном случае.- Только два оператора if и return.
- Оператор if выполняет блок then если условное выражение не равно 0 и выполняет блок else в противном случае. Блок else обязателен.
- Оператор return только устанавливает результат функции и не прерывает поток управления.
- Нет оператора присваивания.
- Каждая функция возвращает
integer
. - Параметры всегда передаются по значению.
- Функции без оператора return возвращают 0.
- Функции могут вызывать другие функции (или себя рекурсивно).
Как вы можете видеть, Язык ужасно ограничен, но в нем достаточно функционала для простых примеров. Язык также является функциональным, в терминах computer science. Мы будем использовать это в наших интересах намного позже в этой серии.
Немного более формальное (но всё ещё очень неформальное) описание синтаксиса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/// 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 } ] ")" |