Давайте создадим компилятор! :: Креншоу Джек
Страница:
374 из 382
Это легко сделать; во первых, измените функцию IsAddop в модуле Scanner чтобы включить два дополнительных оператора: '|' для «или» и "~" для «исключающее или»:
{–}
function IsAddop(c: char): boolean;
begin
IsAddop := c in ['+','-', '|', '~'];
end;
{–}
Затем, мы должны включить анализ операторов в процедуру Expression:
{–}
procedure Expression;
begin
SignedTerm;
while IsAddop(Look) do
case Look of
'+': Add;
'-': Subtract;
'|': _Or;
'~': _Xor;
end;
end;
{–}
(Символы подчеркивания необходимы, конечно, потому что «or» and «xor» являются зарезервированными словами Turbo Pascal).
Затем процедуры _Or and _Xor:
{–}
{ Parse and Translate a Subtraction Operation }
procedure _Or;
begin
Match('|');
Push;
Term;
PopOr;
end;
{–}
{ Parse and Translate a Subtraction Operation }
procedure _Xor;
begin
Match('~');
Push;
Term;
PopXor;
end;
{–}
И, наконец, новые процедуры генерации кода:
{–}
{ Or TOS with Primary }
procedure PopOr;
begin
EmitLn('OR (SP)+,D0');
end;
{–}
{ Exclusive-Or TOS with Primary }
procedure PopXor;
begin
EmitLn('EOR (SP)+,D0');
end;
{–}
Теперь давайте протестируем транслятор (вы возможно захотите изменить вызов в Main обратно на вызов Expression просто чтобы избежать необходимости набирать каждый раз «x=» для присваивания).
Пока все хорошо. Синтаксический анализатор четко обрабатывает выражения вида:
x|y~z
К сожалению, он также не делает ничего для того, чтобы защитить нас от смешивания булевой и арифметической алгебры. Он радостно сгенерирует код для:
(a+b)*(c~d)
Мы говорили об этом немного в прошлом. Вообще, правила какие операции допустимы а какие нет не могут быть применены самим синтаксическим анализатором, потому что они не являются частью синтаксиса языка, а скорее его семантики.
|< Пред. 372 373 374 375 376 След. >|