59
6. Булевы выражения
ВВЕДЕНИЕ
В пятой части этой серии мы рассмотрели управляющие конструкции и разработали
подпрограммы синтаксического анализа для трансляции их в объектный код. Мы
закончили с хорошим, относительно богатым набором конструкций.
Однако, когда мы оставили синтаксический анализатор, в наших возможностях
существовал один большой пробел: мы не обращались к вопросу условия ветвления.
Чтобы заполнить пустоту, я представил вам фиктивную подпрограмму анализа Сondition,
которая служила только как заменитель настоящей.
Одним из дел, которыми мы займемся на этом уроке, будет заполнение этого пробела
посредством расширения Condition до настоящего анализатора/транслятора.
ПЛАН
Мы собираемся подойти к этой главе немного по-другому, чем к любой другой. В
других главах мы начинали немедленно с экспериментов, используя компилятор Pascal,
выстраивая синтаксические анализаторы от самых элементарных начал до их конечных
форм, не тратя слишком много времени на предварительное планирование. Это
называется кодированием без спецификации и обычно к нему относятся неодобрительно.
Раньше мы могли избегать планирования, потому что правила арифметики довольно
хорошо установлены... мы знаем, что означает знак "+" без необходимости подробно это
обсуждать. То же самое относится к ветвлениям и циклам. Но способы, которыми языки
программирования реализуют логику, немного отличаются от языка к языку. Поэтому
прежде, чем мы начнем серьезное кодирование, лучше мы сперва примем решение что
же мы хотим. И способ сделать это находится на уровне синтаксических правил БНФ
(грамматики).
ГРАММАТИКА
Некоторое время назад мы реализовали синтаксические уравнения БНФ для
арифметических выражений фактически даже не записав их все в одном месте. Пришло
время сделать это. Вот они:
<expression> ::= <unary op> <term> [<addop> <term>]*
<term> ::= <factor> [<mulop> factor]*
<factor> ::= <integer> | <variable> | ( <expression> )
(Запомните, преимущества этой грамматики в том, что она осуществляет такую иерархию
приоритетов операторов, которую мы обычно ожидаем для алгебры.)
На самом деле, пока мы говорим об этом, я хотел бы прямо сейчас немного исправить
эту грамматику. Способ, которым мы обрабатываем унарный минус, немного неудобный.
Я нашел, что лучше записать грамматику таким образом:
<expression> ::= <term> [<addop> <term>]*
<term> ::= <signed factor> [<mulop> factor]*
<signed factor> ::= [<addop>] <factor>
<factor> ::= <integer> | <variable> | (<expression>)
Это возлагает обработку унарного минуса на Factor, которому он в действительности и
принадлежит.
Это не означает, что вы должны возвратиться назад и переписать программы, которые
вы уже написали, хотя вы свободны сделать так, если хотите. Но с этого момента я буду
использовать новый синтаксис.