Лекции по построению компилятора на Pascal
## end;
end;
{--------------------------------------------------------------}
Чтобы связать все это вместе не забудьте изменить обращение к Expression в процедурах
Factor и Assignment на вызов BoolExpression.
Хорошо, если вы набрали все это, откомпилируйте и погоняйте эту версию. Сначала
удостоверьтесь, что вы все еще можете анализировать обычные арифметические выражения.
Затем попробуйте булевские. Наконец удостоверьтесь, что вы можете присваивать результат
сравнения. Попробуйте к примеру:
#### pvx,y,zbx=z>ye.
что означает
#### PROGRAM
#### VAR X,Y,Z
#### BEGIN
#### X = Z > Y
#### END.
Видите как происходит присваивание булевского значения X?
УПРАВЛЯЮЩИЕ СТРУКТУРЫ
Мы почти дома. Имея булевы выражения легко добавить управляющие структуры. Для TINY
мы разрешим только две из них, IF и WHILE:
#### <if> ::= IF <bool-expression> <block> [ ELSE <block>] ENDIF
#### <while> ::= WHILE <bool-expression> <block> ENDWHILE
Еще раз позвольте мне разъяснить решения, подразумевающиеся в этом синтаксисе,]
который сильно отличается от синтаксиса C или Pascal. В обоих этих языках "тело" IF или
WHILE расценивается как одиночный оператор. Если вы предполагаете использовать блок
из более чем одного оператора вы должны создать составной утверждение использую
BEGIN-END (в Pascal) или '{}' (в C). В TINY (и KISS) нет таких вещей как составное
утверждение... одиночное или множественное, они являются в этом языке просто блоками.
В KISS все управляющие структуры имеют явные и уникальные ключевые слова,
выделяющие операторный блок поэтому не может быть никакой путаницы где он начинается
и заканчивается. Это современный подход, используемый в таких уважаемых языках, как
Ada и Modula-2 и он полностью устраняет проблему "висячих else".
Обратите внимание, что я мог бы использовать то же самое ключевое слово END для
завершения всех конструкций, как это сделано в Pascal. (Закрывающая '}'] в C служит той же
самой цели.) Но это всегда вело к неразберихе, вот почему программисты на Pascal
предпочитают писать так:
#### end { loop }
#### или## end { if }
Как я объяснил в пятой части, использование уникальных терминальных ключевых слов
увеличивает размер списка ключевых слов и, следовательно, замедляет лексический анализ,
но в данном случае это кажется небольшой ценой за дополнительную подстраховку. Лучше
обнаруживать ошибки во время компиляции, чем во время выполнения.
Одна последняя мысль: каждая из двух конструкций выше имеют нетерминалы
#### <bool-expression> и <block>,
расположенные рядом без разделяющих ключевых слов. В Паскале мы ожидали бы в этом
месте ключевые слова THEN и DO.
Я не вижу проблем в том, чтобы опустить эти ключевые слова, и синтаксический анализатор
также не будет иметь проблем, при условии, что мы не сделаем ошибок в bool-expression. С
другой стороны, если мы включим эти дополнительные ключевые слова мы получили бы