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

Обратите внимание на новую процедуру IsOrOp, которая также является копией, на этот раз IsAddOp:

Code:

{ Recognize a Boolean Orop }

function IsOrop(c: char): Boolean;

begin

   IsOrop := c in ['|', '~'];

end;

 

ОК, переименуйте старую версию BoolExpression в BoolTerm, затем наберите код, представленный выше. Откомпилируйте и протестируйте эту версию. К этому моменту выходной код начинает выглядеть довольно хорошим. Конечно, нет большого смысла от булевой алгебры над постоянными значениями, но скоро мы расширим булевы типы, с которыми мы работаем.

Возможно вы уже предположили, какой будет следующий шаг: булевская версия Term.

Переименуйте текущую процедуру BoolTerm в NotFactor, и введите следующую новую версию BoolTerm. Заметьте, что она намного более простая, чем числовая версия, так как здесь нет эквивалента деления.

Code:

{ Parse and Translate a Boolean Term }

procedure BoolTerm;

begin

   NotFactor;

   while Look = '&' do begin

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

      Match('&');

      NotFactor;

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

   end;

end;

 

 

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

Code:

{ Parse and Translate a Boolean Factor with NOT }

procedure NotFactor;

begin

   if Look = '!' then begin

      Match('!');

      BoolFactor;

      EmitLn('EOR #-1,D0');

      end

   else

      BoolFactor;

end;

 

 
 

 

И переименуйте предыдущую процедуру в BoolFactor. Теперь испытайте компилятор. К этому времени синтаксический анализатор должен обрабатывать любое булево выражение, которое вы позаботитесь ему подкинуть. Работает? Отлавливает ли он неправильно сформированные выражения?

Если вы следили за тем, что мы делали в синтаксическом анализаторе для математических выражений вы знаете что далее мы расширили определение показателя для включения переменных и круглых скобок. Мы не должны делать это для булевого показателя, потому что об этих маленьких вещах позаботится наш следующий шаг. Необходима только одна дополнительная строка в BoolFactor, чтобы позаботиться об отношениях:

Code:

{ Parse and Translate a Boolean Factor }

procedure BoolFactor;

begin

   if IsBoolean(Look) then

      if GetBoolean then

         EmitLn('MOVE #-1,D0')

      else

         EmitLn('CLR D0')

      else Relation;

end;

 

 
 

 

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

Конечно, понадобится некоторый код для Relation. Однако, я не чувствую себя комфортно, добавляя еще код, не проверив с начала тот, который мы уже имеем. Так что давайте сейчас просто напишем фиктивную версию Relation, которая ничего не делает за исключением того, что съедает текущий символ и выводит небольшое сообщение:

Code:

{ Parse and Translate a Relation }

procedure Relation;

begin

   WriteLn('<Relation>');

   GetChar;

end;

 

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

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

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

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


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