Содержание материала

СИНТАКСИЧЕСКИЙ АНАЛИЗАТОР

Теперь, когда мы прошли через процесс принятия решений, мы можем поспешить с разработкой синтаксического анализатора. Вы делали это со мной несколько раз до этого, поэтому вы знаете последовательность: мы начнем с новой копии Cradle и будем добавлять процедуры одна за другой. Так что давайте сделаем это.

Мы начинаем, как и в случае с арифметикой, работая с булевыми литералами а не с переменными. Это дает нам новый вид входного токена, поэтому нам также нужна новая программа распознавания и новая процедура для чтения экземпляров этого типа токенов. Давайте начнем, определив эти две новые процедуры:

Code:

{ Recognize a Boolean Literal }

function IsBoolean(c: char): Boolean;

begin

   IsBoolean := UpCase(c) in ['T', 'F'];

end;

 

{ Get a Boolean Literal }

function GetBoolean: Boolean;

var c: char;

begin

   if not IsBoolean(Look) then Expected('Boolean Literal');

   GetBoolean := UpCase(Look) = 'T';

   GetChar;

end;

 

Внесите эти подпрограммы в вашу программу. Вы можете протестировать их, добавив в основную программу оператор печати:

     WriteLn(GetBoolean);

Откомпилируйте программу и протестируйте ее. Как обычно пока не очень впечатляет но скоро будет.

Теперь, когда мы работали с числовыми данными, мы должны были организовать генерацию кода для загрузки значений в D0. Нам необходимо сделать то же самое и для булевых данных. Обычным способом кодирования булевых переменных является использование 0 для представления FALSE и какого-либо другого значения для TRUE. Многие языки, как например C, используют для его представления целое число 1. Но я предпочитаю FFFF (или -1) потому что побитовое NOT также возвратит логическое NOT. Итак, нам теперь нужно выдать правильный ассемблерный код для загрузки этих значений. Первая засечка на синтаксическом анализаторе булевых выражений (BoolExpression, конечно):

Code:

{ Parse and Translate a Boolean Expression }

procedure BoolExpression;

begin

   if not IsBoolean(Look) then Expected('Boolean Literal');

   if GetBoolean then

      EmitLn('MOVE #-1,D0')

   else

      EmitLn('CLR D0');

end;

 

 

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

Затем, конечно, мы должны расширить определение булевого выражения. У нас уже есть правило в БНФ:

     <b-expression> ::= <b-term> [<orop> <b-term>]*

Я предпочитаю Паскалевскую версию "orop" - OR  и  XOR. Но так как мы сохраняем одно-символьные токены, я буду кодировать их знаками '|' и  '~'. Следующая версия BoolExpression - почти полная копия арифметической процедуры Expression:

Code:

{ Recognize and Translate a Boolean OR }

procedure BoolOr;

begin

   Match('|');

   BoolTerm;

   EmitLn('OR (SP)+,D0');

end;

 

{ Recognize and Translate an Exclusive Or }

procedure BoolXor;

begin

   Match('~');

   BoolTerm;

   EmitLn('EOR (SP)+,D0');

end;

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

{ Parse and Translate a Boolean Expression }

procedure BoolExpression;

begin

   BoolTerm;

   while IsOrOp(Look) do begin

      EmitLn('MOVE D0,-(SP)');

      case Look of

       '|': BoolOr;

       '~': BoolXor;

      end;

   end;

end;

 

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить