Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 [ 45 ] 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

{ Set D0 If Compare was != } procedure SetNEqual; begin

EmitLnCSNE D0);

EmitLnCEXT D0); end;

{ Set D0 If Compare was > } procedure SetGreater; begin

EmitLnCSLT D0);

EmitLnCEXT D0); end;

{ Set D0 If Compare was < }

procedure SetLess;

begin

EmitLnCSGT D0);

EmitLnCEXT D0); end;

Все это дает нам необходимые инструменты. БНФ для булевых выражений такая:

<bool-expr> ::= <bool-term> ( <orop> <bool-term> )* <bool-term> ::= <not-factor> ( <andop> <not-factor> )* <not-factor> ::= [ ! ] <relation>

<relation> ::= <expression> [ <relop> <expression> ] Зоркие читатели могли бы заметить, что этот синтаксис не включает нетерминал "bool-factor" используемый в ранних версиях. Тогда он был необходим потому, что я также разрешал булевы константы TRUE и FALSE. Но не забудьте, что в TINY нет никакого различия между булевыми и арифметическими типами... они могут свободно смешиваться. Так что нет нужды в этих предопределенных значениях... мы можем просто использовать -1 и 0 соответственно.

В терминологии C мы могли бы всегда использовать определения:

#define TRUE -1

#define FALSE 0

(Так было бы, если бы TINY имел препроцессор.) Позднее, когда мы разрешим объявление констант, эти два значения будут предопределены языком.

Причина того, что я заостряю на этом ваше внимание, в том что я пытался использовать альтернативный путь, который заключался в использовании TRUE и FALSE как ключевых слов. Проблема с этим подходом в том, что он требует лексического анализа каждого имени переменной в каждом выражении. Как вы помните, я указал в главе 7, что это значительно замедляет компилятор. Пока ключевые слова не могут быть в выражениях нам нужно выполнять сканирование только в начале каждого нового оператора... значительное улучшение. Так что использование вышеуказанного синтаксиса не только упрощает синтаксический анализ, но также ускоряет сканирование.

Итак, если мы удовлетворены синтаксисом, представленным выше, то соответствующий код показан ниже:



procedure Equals; begin

Match(=);

Expression;

PopCompare;

SetEqual; end;

{ Recognize and Translate a Relational "Not Equals" }

procedure NotEquals;

begin

Match(#);

Expression;

PopCompare;

SetNEqual; end;

{ Recognize and Translate a Relational "Less Than" }

procedure Less;

begin

Match(<);

Expression;

PopCompare;

SetLess; end;

{ Recognize and Translate a Relational "Greater Than" }

procedure Greater;

begin

Match(>);

Expression;

PopCompare;

SetGreater; end;

{ Parse and Translate a Relation }

procedure Relation;

begin

Expression;

if IsRelop(Look) then begin Push;

case Look of =: Equals; #: NotEquals; <: Less; >: Greater; end; end; end;

{ Parse and Translate a Boolean Factor with Leading NOT }

procedure NotFactor;

begin



if Look = ! then begin

MatchC!);

Relation;

NotIt;

end else

Relation;

end;

{ Parse and Translate a Boolean Term }

procedure BoolTerm;

begin

NotFactor;

while Look = & do begin Push;

Matches); NotFactor; PopAnd; end; end;

{ Recognize and Translate a Boolean OR }

procedure BoolOr;

begin

Match(l);

BoolTerm;

PopOr; end;

{ Recognize and Translate an Exclusive Or }

procedure BoolXor;

begin

Match(~);

BoolTerm;

PopXor; end;

{ Parse and Translate a Boolean Expression }

procedure BoolExpression;

begin

BoolTerm;

while IsOrOp(Look) do begin Push;

case Look of

l: BoolOr; -: BoolXor;

end; end; end;

Чтобы связать все это вместе не забудьте изменить обращение к Expression в процедурах Factor и Assignment на вызов BoolExpression.

Хорошо, если вы набрали все это, откомпилируйте и погоняйте эту версию. Сначала



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 [ 45 ] 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97