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

       

ОПЕРАТОР WHILE


Следующий вид оператора должен быть простым, так как мы уже имеем опыт. Синтаксис, который я выбрал для оператора WHILE следующий:

WHILE <condition> <block> ENDWHILE

Знаю, знаю, мы действительно не нуждаемся в отдельных видах ограничителей для каждой конструкции... вы можете видеть, что фактически в нашей одно-символьной версии 'e' используется для всех из них. Но я также помню множество сессий отладки в Паскале, пытаясь отследить своенравный END который по мнению компилятора я хотел поместить где-нибудь еще. По своему опыту знаю, что специфичные и уникальные ключевые слова, хотя они и добавляются к словарю языка, дают небольшую защиту от ошибок, которая стоит дополнительной работы создателей компиляторов.

Теперь рассмотрите, во что должен транслироваться WHILE:

     L1:  <condition>

          BEQ L2

          <block>

          BRA L1

     L2:

Как и прежде, сравнение этих двух представлений дает нам действия, необходимые на каждом этапе:

     WHILE          { L1 = NewLabel;

                      PostLabel(L1) }

     <condition>    { Emit(BEQ L2) }



     <block>

     ENDWHILE       { Emit(BRA L1);

                      PostLabel(L2) }

Код выходит непосредственно из синтаксиса:

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

{ Parse and Translate a WHILE Statement }

procedure DoWhile;

var L1, L2: string;

begin

   Match('w');

   L1 := NewLabel;


   L2 := NewLabel;

   PostLabel(L1);

   Condition;

   EmitLn('BEQ ' + L2);

   Block;

   Match('e');

   EmitLn('BRA ' + L1);

   PostLabel(L2);

end;

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

Так как мы получили новый оператор, мы должны добавить его вызов в процедуру Block:

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

{ Recognize and Translate a Statement Block }

procedure Block;

begin

   while not(Look in ['e', 'l']) do begin

      case Look of

       'i': DoIf;

       'w': DoWhile;

       else Other;

      end;

   end;

end;

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

Никаких других изменений не требуется.

Хорошо, протестируйте новую программу. Заметьте, что на этот раз код <condition> находится внутри верхней метки, как раз там, где нам надо. Попробуйте несколько вложенных циклов. Испробуйте циклы внутри IF и IF внутри циклов. Если вы немного напутаете то, что вы должны набирать, не смущайтесь:  вы пишите ошибки и в других языках, не правда ли?  Код будет выглядеть более осмысленным, когда мы получим полные ключевые слова.

Я надеюсь, что к настоящему времени вы начинаете понимать, что это действительно просто. Все, что нам необходимо было сделать для того, чтобы создать новую конструкцию, это разработать ее синтаксически-управляемый перевод. Код возникает из него, и это не влияет на другие подпрограммы. Как только вы почувствуете это, вы увидите, что можете добавлять новые конструкции почти также быстро, как вы можете их придумывать.


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







Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий