"Давайте создадим компилятор!" - читать интересную книгу автора (Креншоу Джек)Оператор LOOPМы могли бы остановиться на этом и иметь работающий язык. Много раз было показано, что языка высокого уровня всего с двумя конструкциями IF и WHILE достаточно для написания структурного кода. Но раз уж мы начали, то давайте немного расширим репертуар. Эта конструкция даже проще, так как она совсем не имеет проверки условия... это бесконечный цикл. Имеет ли смысл такой цикл? Немного сам по себе, но позднее мы собираемся добавить команду BREAK, которая даст нам способ выхода из цикла. Она делает язык значительно более богатым, чем Паскаль, который не имеет команды выхода из цикла и также позволяет избежать забавных конструкций типа WHILE(1) или WHILE TRUE в C и Паскале. Синтаксис прост: LOOP lt;blockgt; ENDLOOP Синтаксически управляемый перевод: LOOP { L = NewLabel; PostLabel(L) } lt;blockgt; ENDLOOP { Emit(BRA L } Соответствующий код показан ниже. Так как мы уже использовали "l" для ELSE на этот раз я использовал последнюю букву "p" как «ключевое слово». {–} { Parse and Translate a LOOP Statement } procedure DoLoop; var L: string; begin Match('p'); L := NewLabel; PostLabel(L); Block; Match('e'); EmitLn('BRA ' + L); end; {–} После того, как вы вставите эту подпрограмму, не забудьте добавить строчку в Block для ее вызова. REPEAT-UNTIL Имеется одна конструкция, которую я взял напрямую из Паскаля. Синтаксис: REPEAT lt;blockgt; UNTIL lt;conditiongt; и синтаксически-управляемый перевод: REPEAT { L = NewLabel; PostLabel(L) } lt;blockgt; UNTIL lt;conditiongt; { Emit(BEQ L) } Как обычно, код вытекает отсюда довольно легко: {–} { Parse and Translate a REPEAT Statement } procedure DoRepeat; var L: string; begin Match('r'); L := NewLabel; PostLabel(L); Block; Match('u'); Condition; EmitLn('BEQ ' + L); end; {–} Как и прежде, мы должны добавить вызов DoRepeat в Block. Хотя на этот раз есть различия. Я решил использовать "r" вместо REPEAT (естественно), но я также решил использовать "u" вместо UNTIL. Это означает, что "u" должен быть добавлен к множеству символов в условии while. Это символы, которые сигнализируют о выходе из текущего блока... символы «follow», на жаргоне разработчиков компиляторов. {–} { Recognize and Translate a Statement Block } procedure Block; begin while not(Look in ['e', 'l', 'u']) do begin case Look of 'i': DoIf; 'w': DoWhile; 'p': DoLoop; 'r': DoRepeat; else Other; end; end; end; {–} |
|
|