Построение транслятора и интерпретатора языка программирования GBasic
1 Постановка задачи.
Написать программы для трансляции и интерпретации языка программирования GBasic.
2 Теоретические сведения.
Процесс создания работы включает в себя два этапа:
1) написание транслятора с получением некоторого объектного кода входной программы, написанной на языке программирования Gbasic;
2) написание интерпретатора, выполняющего программу из объектного файла.
В процессе трансляции формулировки входного языка анализи-руются и переводятся в элементы промежуточного представления, содержащие информацию, достаточную для составления выходной программы (в нашем случае - объектного файла).
Режим интерпретации характеризуется тем, что процессор, обрабатывая промежуточное представление, почти одновременно с чтением промежуточных форм выполняет соответствующие им машинные операции; при этом не вырабатывается выходной программы, подлежащей дальнейшему исполнению.
3 Транслятор.
Режим трансляции является детерминированным, с прерыванием работы при обнаружении ошибки с выдачей соответствующего сообщения.
Трансляция делится на четыре последовательных этапа:
1) Лексический анализ, на котором выделяются лексемы, составляется таблица переменных, проверяется допустимость входного алфавита;
2) Синтаксический и семантический анализ, на котором конструируется некоторый образ памяти, проверяются типы переменных и выражений, дополняется таблица переменных, подсчитывается количество выражений;
3) Преобразование встреченных во входной программе выражений в обратную польскую запись, предложенную польским математиком Яном Лукашевичем;
4) Вывод образа памяти, преобразованных выражений и таблицы переменных в объектный файл.
Чтение отдельной лексемы происходит посредством процедуры GetSym. В результате получаем новую лексему в переменной Ident : string и ее тип в переменной Symbol:TypeWords.
Множество типов лексем содержится в определении типа TypeWords, который имеет вид:
TypeWords = (TAbs, TDelete, TInkeyS, TLength, TRnd, TSqr, TStr, TVal, TBeep, TCall, TCls, TFor, TIf, TInk, TInput, TLet, TNext, TPaper, TPause, TPrint, TRandomize, TStop, TTo, TThen, TEnd, TEndIf, TLocate, TElse, TProc, TReturn, TVar_, TEndVar, SymNum, SymStr, SymVar, SymConst, Tbreak, SymUnknown, Snone, sAny, SymIdent, SymNumber, SymDvoetoch, SymEq, SymAdd, SymSub, SymMul, SymDiv, SymBolshe, SymMenshe, SymBolsheEq, SymMensheEq, SymNotEq, SymOpenSk, SymCloseSk, SymOpenSkKvadr, SymCloseSkKvadr, SymZap, TString, TInteger, TArray);
Синтаксический и семантический анализ входной программы реализован посредством рекурсивных процедур Prog (начальная процедура), Statements (операторы), Statement (оператор), Pri1 (для оператора PRINT), Operator_Compare (сравнение двух выражений), Expression (получение типа выражения), ExpressionInSk (вычисляет тип выражения для индекса массива), Stat (операнд).
При успешной идентификации лексемы происходит компоновка образа программы добавлением в вписок ячеек памяти новых элементов. Этим занимается процедура AddMem с параметром x, где
х=1 - добавить зарезервированное слово; х=2 - добавить указатель на переменную; х=3 - добавить код разделителя (для условного оператора); х=4 - добавить указатель на выражение
По завершении работы С&С Анализаторов необходимо получить список выражений. Этим занимается процедура GetExpressions.
Когда список выражений составлен, необходимо преобразовать их в обратную польскую запись.
Для этого написаны специальные процедуры: - MorfologExpression - стартовая процедура - Morf - собственно процедура преобразования выражения Пример: 1+a*r[6] После преобразования, выражение будет иметь следующий вид $!$$0$+%A%%R%$6$^*+ Здесь используются следующие обозначения: $<Число>$ - обозначение числа %<Имя>% - обозначение имени переменной "<Строка>" - обозначение строковой константы Операция ^ означает, что идет обращение к элементу массива (i-2) с индексом (i-1)
После завершения преобразований выражений происходит запись образа программы и другой вспомогательной информации согласно формату объектного файла, описанного ниже.
4 Интерпретатор.
Режим интерпретации программы из объектного файла также является детерминированным, с прерыванием выполнения работы программы и выдачей сообщения об ошибке.
Образ памяти представляется в виде двунаправленного списка, состоящего из элементов rMem. Элементы rMem определяются так:
Record Num : integer; - номер ячейки памяти Code : integer; - код команды, переменной или разделителя XCode : integer; -номер ячейки для указателя на выражение Lvl : integer; - уровень вложенности команды Next,Pred : ^rMem; - указатели на следующую и предыдущую ячейки памяти End
Счетчик команд IP:integer получает новое значение исходя из выполнения текущей команды.
Для вычисления значений выражений, представленных в обратной польской записи используется процедура Solve, для которой определены два параметра: S_IN:string и S_OUT:string : соответственно вход и выход. При вычислении используется програмно-реализуемый стек (статический массив).
Определены две глобальные переменные, содержащие информацию об адресе стартовой команды (не обязательно равной 1), и об адресе команды завершения программы. Как только счетчик команд попадет в ячейку памяти с номером завершающей ячейки, работа интерпретатора может считаться выполненной и прекращается.
Выражения размещаются в памяти в виде однонаправленного списка, имеющего следующую структуру элементов:
RExpr=^exprType; ExprType=Record Stroka : itring;- само выражение Num : integer; - порядковый номер выражения TypeExpr : integer; - тип выражения Next : rExpr - указатель на следующее выражение EndСписок зарезервированных типов слов аналогичен списку из раздела <<транслятор >>.
5 Описание языка Gbasic.
Данный язык является упрощенной версией языка программирования Basic for Spectrum48K. Отсутствует возможность работы с файлами, графикой, динамической памятью, строковыми массивами.
Типы переменных: Integer - целое число в диапазоне от -32500 до 32500 String - строка диною не более 80 символов Array - массив целых чисел Операторы языка: + Abs - абсолютная величина значения выражения присваивается переменной Abs <Выр1>:Int,<Имя>:Int + Beep - звуковой сигнал длительностью <Выр1> с частотой <Выр2> Beep <Выр1>:Int,<Выр2>:Int + Call - вызов процедуры Call <Имя процедуры> + Cls - заполнение текстового экрана цветом фона Cls + Delete - удаляет часть строки, начиная с индекса <Выр1> длиною <Выр2> Delete <Имя>:Str,<Выр1>:Int,<Выр2>:Int + For Next переменная для цикла не должна являться элементом массива For <Имя_ц>:Int=<Выр1>:Int to <Выр2>:Int: <Тело цикла>: Next <Имя_ц> + If Then Else EndIf if <Выр1><Сравнение><Выр2> then <Тело then> else <Тело else> endif + Ink - установка нового цвета текста (0..15) Ink <Выр1>:Int + Input - ввод информации с клавиатуры Input <Имя> + Lenght - длина строковой переменной Length <Имя>:Str,<Имя>:Int + Let - присвоение переменной значения выражения Let <Имя>=<Выр1> + Locate установка текстового курсора по координатам х=<Выр1> у=<Выр2> Locate <Выр1>:Int,<Выр2>:Int + Paper - установка нового фона для текста (0..7) Paper <Выр1>:Int + Pause - задержка выполнения программы на <Выр1> мс Pause <Выр1>:Int + Print - вывод на экран списка значений выражений Print <Выр1>,<Выр2>,..,<ВырN> + Proc - процедура Proc <Имя>: <Тело процедуры>: return + Randomize - инициализация генератора случайных чисел Randomize + Rnd - получение случайного числа в диапазоне 0..<Выр1> Rnd <Выр1>:Int,<Имя>:Int + Stop - насильственное завершение программы Stop + Sqr - вычисляет квадрат выражения с присвоением результата переменной Sqr <Выр1>:Int,<Имя>:Int + Str - преобразовывает результат числового выражения в строку Str <Выр1>:Int,<Имя>:Str + Val - преобразовывает строку в число Val <Выр1>:Str,<Имя>:Int Функции: В данной реализации языка функции отсутствуют.
Операция деления: Операция "/" производит целочисленное деление (аналог div в языке Turbo Pascal 7.0).
6 Формат объектного файла
GBasic OBJ-file [Program] N - Количество "ячеек памяти" [Start Point] N - Стартовый адрес программы [End Point] N - Адрес завершения программы [Memory] - блок представления памяти <1> <Имя команды> NN - код команды или переменной или выражения или операции сравнения MM - вспомогательный код KK - уровень вложенности <2> ... ... [Variables] - блок представления переменных N - Количество переменных <1> ZZ - Имя XX - тип <2> ... ... [Expressions] - блок представления выражений N - Количество выражений (В обратной польской записи) <1> WW - выражение EE - тип <2> ... ... [Arrays] - блок представления массивов ZZ - Количество массивов <1> WW - имя AA - левая граница BB - правая граница <2> ... ...
7 Инструкция по использованию.
Трансляция исходной программы с языка GBasic в объектный код: transl.exe <имя входного файла> (по умолчанию имя входного файла = "basic.in") Интерпретация объектного кода: interpr.exe <имя объектного файла> (по умолчанию имя объектного файла = "basic.obj") Работа с одномерными массивами (представлен только тип Integer); Запрещена вложенность массивов, т.е. let a[a[4]]=1 - это неправильно let i=a[4]: let a[i]=1 - это правильно.
8 Список литературы:
1) Н.Вирт "Алгоритмы+структуры данных=программы"
2) Ф.В.Вайнгартен "Трансляция языков программирования"
3) В.Н.Пинаев "Формальные методы описания языков програмирования и построение трансляторов"
9 Вместо заключения
Надеюсь, данная статья будет кому-нибудь полезной.
Delphi — это объектно-ориентированный язык программирования со строгой типизацией переменных. Он используется в основном для написания прикладных, пользовательских программ. Простота использования позволяет рекомендовать его в качестве языка для начального обучения программированию. Хотя, если смотреть на перспективу, работодатели мало интересуются работниками, программирующими на Delphi.
Интересные материалы на сайте:
Описание алгоритмов для программного нажатия на клавиши. Пригодится системным администраторам и всем, кто увлекается системными утилитами.
Статья о поисковой интересности сайта. Возможно, часть материалов уже устарела за 10 лет, но на некоторые моменты стоит обратить внимание.
Свой взгляд на проблему обмена гипер ссылками между сайтом донором и сайтами получателями.
Еще один лайф-хак. Обыгрываем нечестных игроков в игру "Балда". Большая база слов, которая с легкостью может быть расширена.