Войти
ПрограммированиеСтатьи

Написание интерпретатора скриптов на С++. Часть 1: Обзор.

Автор: Маньшин В.Э. aka Skeef


От автора:

Тянулся нудный осенний вечер; делать как всегда было нечего... И вдруг, ни с того ни с сего, пришла мне в голову идея написать статью по созданию интерпретатора. «Делать тебе нечего... – иди лучше к коллоквиуму по вышке готовься», - раздался внутренний голос. И я уже было потянулся к розетке, чтобы вырубить мой компьютер, но внезапно вспомнил. Вспомнил, как я сам писал систему обработки сценариев. Вспомнил, сколько времени, усилий и нервов было впустую затрачено на поиск исчерпывающей информации по этой теме. Вспомнил бессонные ночи, проведенные за отладкой. И еще много чего вспомнил, а потом... послал свой внутренний голос и принялся за работу.

Введение:

Этот цикл статей предназначен, прежде всего, для читателя, не имеющего опыта работы в области написания интерпретаторов. Я постараюсь рассмотреть этот процесс настолько подробно, на сколько позволяют мои знания и опыт. Итак:

Тема работы: написание системы обработки сценариев на С++.

Цель работы:
1) ознакомление читателя с темой;
2) создание работоспособного интерпретатора с нуля;
3) его «внедрение» в какое-либо приложение.

Приборы и оборудование: базовые навыки владения С++, ООП и STL.

Ход  работы:

Постановка задачи:

Написание полноценного интерпретатора какого-либо языка – дело сверхтрудоемкое и для меня непосильное. Поэтому я ограничил скриптовый язык подмножеством языка Си и, следуя принципу «достижения результатов наименьшими усилиями» внес в это подмножество кое-какие изменения. Итак, вот что получилось:


Элементы языка  Название  Типы данных  Ветвление  Циклы  Операторы  Другое 
Описание элементов языка
а как же без этого?:) Я назвал свое творение (хм...громко сказано!) ESL (Embedded Script Language)
int, bool (то же, что и int; введен для удобства), string
организуется посредством операторов if и else
операторы for и while
арифметические: +, -, *, \ (или /)
сравнения:            >, <, ~ (оператор «равно»), ! (оператор «не равно»)
логические:          | («или»), & («и»)присваивания:      =
end    – этим ключевым словом должен завершаться каждый скрипт
break – досрочный выход из скрипта

Возможности языка

Корректная обработка скобочных выражений Возможность вызова функций из использующей ESL программы Корректная обработка рекурсий Возможность инициализации при объявлении Кэширование откомпилированных скриптов для ускорения их последющего выполнения Возможность передачи неограниченного числа параметров в скрипт Возможность возврата результата скриптом Другие возможности, которые я забыл упомянуть, но они непременно будут рассмотрены далее.

По существу, наша система обработки сценариев состоит из следующих основных компонентов:
- Lexer – преобразует входные данные (обычно, файл) в поток лексем (таких как ключевые слова, операторы и т.д.);
- Generator – генерирует байт код для последующего выполнения виртуальной машиной;
- Executor – выполняет байт код.

А вот наглядное изображение взаимодействия этих компонентов:

Изображение

Термины и понятия:

Ниже я привожу словарь терминов и понятий, которые будут периодически использоваться в последующих статьях цикла. Все нижеперечисленные определения рассматриваются в контексте скриптов ESL.

  аргумент (или параметр) – это значение, передаваемое в функцию. Например в случае вызова функции IntToStr(123) аргументов является число 123.

  выражение – это то, что приводит к некоторому значению. Например, как простая переменная, так и формула (x*n-1)/y2k являются выражениями. Любое выражение можно превратить в инструкцию, добавив после него «;». Операции присваивания также являются выражениями. Примеры выражений: x, y = x, func1(), y = func1().

  идентификатор – это имя, определенное в скрипте. Любое слово в программе (за исключением комментариев и ключевых слов) является идентификатором. Все имена стандартных и игровых функций также являются идентификаторами.

  инструкция – базовый элемент скрипта. Пример: for(...), if(...), a = b;.

  ключевое слово – это имя, определенное в самом ESL. Сюда не включаются имена стандартных и программных функций, которые являются идентификаторами. Примеры: if, for, end.

  комментарии – строки (или части строк), содержащие игнорируемый лексером текст. Комментарии введены для пояснения скриптов. Комментарием считается текст, заключенный между «%» и концом строки. Например:
  <код>%это комментарий, находящийся справа от кода
  %это комментарий, находящийся в новой строке
  <код>

  операнд – это подвыражение, которое при помощи операторов комбинируется в более сложное выражение. Например, в выражении x + y оператор «+» имеет два операнда x и y.

  оператор – символ, определенный в ESL, при помощи которого подвыражения (операнды) комбинируются в более сложные выражения. Например +,-,*.

  определение – создание новой переменной.

  переменная – именованный фрагмент памяти для хранения данных.  Названия переменных не должны совпадать с ключевыми словами и функциями и могут состоять из латинских или русских букв, цифр и символа подчеркивания. Пример: a, _string1_.

  составная инструкция – группа инструкций, заключенных в фигурные скобки. Пример: {int a = 5; string str = IntToStr(a);}

  строка (string) – тип переменной в ESL,  представляющий собой совокупность символов.

  управляющая структура – это инструкция, имеющая возможность изменять ход выполнения программы на основе каких-либо условий. Управляющими структурами в ESL являются if-else, while и for.

  функция – группа инструкций, исполняемая как единое целое и предназначенная для выполнения некоторых действий или получения значения. В ESL имеются стандартные (встроенные в исходный код программы ESL) и внешние (встроенные в исходный код вызывающей программы) функции. Возможность создания новых функций в скриптах (пока) отсутствует.

Заключение:

Уфф...кажется все. Первая, думаю самая сложная для написания, статья готова. Теперь читатель ознакомлен с общими принципами языка ESL, поэтому, следующие части будут посвящены более интересным вопросам - непосредственно реализации системы сценариев.

Готов выслушать все вопросы, предложения и критику.

8 ноября 2003

Комментарии [60]