Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Pascal_Unkn.doc
Скачиваний:
8
Добавлен:
03.11.2018
Размер:
1.63 Mб
Скачать

Добавление записей

Конечно, заполнение таблицы напрямую - довольно плохая практика и она не сможет хорошо нам послужить в будущем. То, что нам нужно, это процедура, добавляющая записи в таблицу. В то же самое время мы знаем, что нам будет необходимо тестировать таблицу для проверки, что мы не объявляем повторно переменную, которая уже используется (что легко может случиться при наличии всего 26 вариантов!). Для поддержки всего это введите следующие новые процедуры:

{--------------------------------------------------------------}

{ Report Type of a Variable }

function TypeOf(N: char): char; begin    TypeOf := ST[N]; end;

{--------------------------------------------------------------} { Report if a Variable is in the Table }

function InTable(N: char): boolean; begin    InTable := TypeOf(N) <> '?'; end;

{--------------------------------------------------------------} { Check for a Duplicate Variable Name }

procedure CheckDup(N: char); begin    if InTable(N) then Abort('Duplicate Name ' + N); end;

{--------------------------------------------------------------} { Add Entry to Table }

procedure AddEntry(N, T: char); begin    CheckDup(N);    ST[N] := T; end;

{--------------------------------------------------------------}

Теперь измените три строки в основной программе следующим образом:

    AddEntry('A', 'a');

    AddEntry('P', 'b');

    AddEntry('X', 'c');

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

Распределение памяти

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

    <data decl> ::= VAR <identifier>

Снова, мы можем вытащить массу кода из предыдущих программ. Следующий код - это урезанные версии тех процедур. Они значительно упрощены, так как я удалил такие тонкости как списки переменных и инициализаторы. Обратите внимание, что в процедуре Alloc новый вызов AddEntry будет также заботиться о проверке двойных объявлений:

{--------------------------------------------------------------}

{ Allocate Storage for a Variable }

procedure Alloc(N: char); begin    AddEntry(N, 'v');    WriteLn(N, ':', TAB, 'DC 0'); end;

{--------------------------------------------------------------} { Parse and Translate a Data Declaration }

procedure Decl; var Name: char; begin    Match('v');    Alloc(GetName); end;

{--------------------------------------------------------------} { Parse and Translate Global Declarations }

procedure TopDecls; begin    while Look <> '.' do begin       case Look of         'v': Decl;       else Abort('Unrecognized Keyword ' + Look);       end;       Fin;    end; end;

{--------------------------------------------------------------}

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]