Давайте создадим компилятор! :: Креншоу Джек
Страница: 139 из 139 | |||
| ||||||||||||||
| ||||||||||||||
КАТЕГОРИИ КНИГПОСЛЕДНИЕ ОТЗЫВЫ О КНИГАХМихаил (19.04.2017 - 06:11:11) Антихрист666 (18.04.2017 - 21:05:58) Ладно, теперь поспешили вы... (18.04.2017 - 20:50:34) Роман (18.04.2017 - 18:12:26) АНДРЕЙ (18.04.2017 - 16:42:55) СЛУЧАЙНОЕ ПРОИЗВЕДЕНИЕПроснись, твоя Фея стоит у ворот 30.06.10 - 08:03 Хотите чтобы ваше произведение или ваш любимый стишок появились здесь? добавьте его! |
Короче говоря, кажущаяся близость между унарным «not» и унарным минусом разваливается при более близком исследованиии. «not» изменяет показатель а не терм и он не имеет отношения ни к унарному минусу, ни исключающему или. Следовательно, он заслуживает своего собственного символа для вызова. Какой символ лучше, чем очевидный, также используемый в Си символ "!"? Используя правила того как мы думаем должен вести себя «not», мы должны быть способны закодировать исключающее или (предполагая что это нам когда-нибудь понадобится) в очень естественной форме: a & !b | !a & b Обратите внимание, что никаких круглых скобок не требуется – выбранные нам уровни приоритета автоматически заботятся обо всем. Если вы продолжаете учитывать уровни приоритета, это определение помещает '!' на вершину кучи. Уровни становятся: ! – (унарный) *, /, & +, -, |, ~ Рассматривая этот список, конечно не трудно увидеть, почему мы имели проблему при использовании '~' как символа «not»! Так, как мы механизируем эти правила? Таким же самым способом, как мы сделали с SignedTerm, но на уровне показателя. Мы определим процедуру NotFactor: {–} { Parse and Translate a Factor with Optional «Not» } procedure NotFactor; begin if Look ='!' then begin Match('!'); Factor; Notit; end else Factor; end; {–} и вызовем ее из всех мест, где мы прежде вызывали Factor, т.е. из Term, Multiply, Divide и _And. Обратите внимание на новую процедуру генерации кода: {–} { Bitwise Not Primary } procedure NotIt; begin EmitLn('EOR #-1,D0'); end; {–} Испытайте ее сейчас с несколькими простыми случаями. Фактически, попробуйте пример с исключающим или: a&!b|!a&b Вы должны получить код (без комментариев, конечно): MOVE A(PC),DO ; load a MOVE D0,-(SP) ; push it MOVE B(PC),DO ; load b EOR #-1,D0 ; not it AND (SP)+,D0 ; and with a MOVE D0,-(SP) ; push result MOVE A(PC),DO ; load a EOR #-1,D0 ; not it MOVE D0,-(SP) ; push it MOVE B(PC),DO ; load b AND (SP)+,D0 ; and with !a OR (SP)+,D0 ; or with first term Это точно то, что мы хотели получить. Так что, по крайней мере, и для арифметических и для логических операторов наш новый приоритет и новый, более тонкий синтаксис, поддерживают друг друга. Даже специфическое, но допустимое выражение с ведущим addop: ~x имеет смысл. SignedTerm игнорирует ведущий '~' как и должно быть, так как выражение эквивалентно: 0~x, что эквивалентно x. Когда мы взглянем на созданные нами БНФ, мы обнаружим, что наша булева алгебра добавляет теперь только одну дополнительную строку: Это большое улучшение предыдущих достижений. Будет ли сохраняться наша удача когда мы примемся за операторы отношений? Мы выясним это скоро, но мы должы будем дождаться следующей главы. У нас выдалась подходящая пауза и я хочу выдать эту главу в ваши руки. Уже прошел год с выпуска Главы 15. Я боюсь признаться, что вся эта текущая глава была готова уже давно, за исключением операторов отношений. Но эта информация совсем не дает вам ничего хорошего, сидя на моем жестком диске, и удерживая ее пока пока операторы отношений не будут сделаны, я не давал ее в ваши руки все это время. Пришло время выдать ее чтобы вы смогли получить из нее что-нибудь ценное. Кроме того, имеется большое количество серъезных философских вопросов, связанных с операторами отношений, и я предпочел бы сохранить их для отдельной главы, где я смог бы сделать это корректно. Развлекайтесь с новой более тонкой арифметикой и логическим анализом, а я скоро увижу вас с отношениями. |
ИНТЕРЕСНОЕ О ЛИТЕРАТУРЕ
ТОП 20 КНИГ
ТОП 20 АВТОРОВ
| ||||||||||||
|