Лекции по построению компилятора на Pascal

       

ИНИЦИАЛИЗАТОРЫ


Пока мы работали с объявлениями данных, меня беспокоила одна вещь - то, что Pascal не позволяет инициализировать данные в объявлении. Эта возможность по общему признанию является своего рода излишеством, и ее может не быть в языке, который считается минимальным языком. Но ее также настолько просто добавить, что было бы позором не сделать этого. БНФ становится:

     <var-list> ::= <var> ( <var> )*

     <var> ::= <ident> [ = <integer> ]

Измените Alloc как показано ниже:

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

{ Allocate Storage for a Variable }

procedure Alloc(N: char);

begin

   Write(N, ':', TAB, 'DC ');

   if Look = '=' then begin

      Match('=');

      WriteLn(GetNum);

      end

   else

      WriteLn('0');

end;

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

Вот оно: инициализатор в шесть дополнительных строк Pascal.

Испытайте эту версию TINY и проверьте, что вы действительно можете задавать начальное значение переменных.

Ей богу, он начинает походить на настоящий компилятор! Конечно, он все еще ничего не делает, но выглядит хорошо, не так ли?

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

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

{ Get a Number }

function GetNum: integer;

var Val: integer;

begin

   Val := 0;

   if not IsDigit(Look) then Expected('Integer');


   while IsDigit(Look) do begin

      Val := 10 * Val + Ord(Look) - Ord('0');

      GetChar;

   end;

   GetNum := Val;

end;

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

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

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

{ Allocate Storage for a Variable }

procedure Alloc(N: char);

begin

   if InTable(N) then Abort('Duplicate Variable Name ' + N);

   ST[N] := 'v';

   Write(N, ':', TAB, 'DC ');

   if Look = '=' then begin

      Match('=');

      If Look = '-' then begin

         Write(Look);

         Match('-');

      end;

      WriteLn(GetNum);

      end

   else

      WriteLn('0');

end;

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

Теперь у вас есть возможность инициализировать переменные отрицательными и/или многозначными значениями.


Содержание раздела