Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π”Π°Π²Π°ΠΉΡ‚Π΅ создадим компилятор!Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 49

Автор Π”ΠΆΠ΅ΠΊ ΠšΡ€Π΅Π½ΡˆΠΎΡƒ

ОбъявлСниС Ρ‚ΠΈΠΏΠΎΠ²

РаспрСдСлСниС памяти Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² Π½Π΅ слоТнСС Ρ‡Π΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ TopDecl для распознавания Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова. Π—Π΄Π΅ΡΡŒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ ряд Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ, с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊΠΎΠ² Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ синтаксис ΠΈ Ρ‚.ΠΏ., Π½ΠΎ сСйчас я ΡΠΎΠ±ΠΈΡ€Π°ΡŽΡΡŒ ΠΎΡ‚Π»ΠΎΠΆΠΈΡ‚ΡŒ Π²ΡΠ΅ эти вопросы ΠΈ просто ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Π½Π΅ ΠΏΠΎΠ΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠΉ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΡŽ ΡƒΠΊΠ°Π· Ρ‡Ρ‚ΠΎ наш синтаксис Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Π°ΠΊΠΈΠΌ:

<data decl> ::= <typename> <identifier>

Π³Π΄Π΅:

<typename> ::= BYTE | WORD | LONG

(По ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ совпадСнию, ΠΏΠ΅Ρ€Π²Ρ‹Π΅ Π±ΡƒΠΊΠ²Ρ‹ этих Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠΉ оказались Ρ‚Π΅ ΠΆΠ΅ самыми Ρ‡Ρ‚ΠΎ ΠΈ спСцификации Π΄Π»ΠΈΠ½Ρ‹ ассСмблСрного ΠΊΠΎΠ΄Π° 68000, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ Π²Ρ‹Π±ΠΎΡ€ ΡΡŠΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ Π½Π°ΠΌ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π±ΠΎΡ‚Ρ‹.)

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позаботится ΠΎΠ± этих ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½ΠΈΡΡ…, внСся всСго лишь нСбольшС измСнСния. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π½ΠΈΠΆΠ΅, я ΠΎΡ‚Π΄Π΅Π»ΠΈΠ» Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΊΠΎΠ΄ Π² Alloc ΠΎΡ‚ логичСской части. Π­Ρ‚ΠΎ соотвСтствуСт Π½Π°ΡˆΠ΅ΠΌΡƒ ТСланию ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ машино-Π·Π°Π²ΠΈΡΠΈΠΌΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ компилятора.

{–}

{ Generate Code for Allocation of a Variable }

procedure AllocVar(N, T: char);

begin

WriteLn(N, ':', TAB, 'DC.', T, ' 0');

end;

{–}

{ Allocate Storage for a Variable }

procedure Alloc(N, T: char);

begin

AddEntry(N, T);

AllocVar(N, T);

end;

{–}

{ Parse and Translate a Data Declaration }

procedure Decl;

var Typ: char;

begin

Typ := GetName;

Alloc(GetName, Typ);

end;

{–}

{ Parse and Translate Global Declarations }

procedure TopDecls;

begin

while Look <> '.' do begin

case Look of

'b', 'w', 'l': Decl;

else Abort('Unrecognized Keyword ' + Look);

end;

Fin;

end;

end;

{–}

ВнСситС ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹Π΅ измСнСния Π² эти ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ ΠΈ испытайтС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Π΅ символы "b", "w" ΠΈ "l" ΠΊΠ°ΠΊ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова (сСйчас ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π² Π½ΠΈΠΆΠ½Π΅ΠΌ рСгистрС). Π’Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ случаС ΠΌΡ‹ выдСляСм ΠΏΠ°ΠΌΡΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ объСма. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, глядя Π½Π° Π΄Π°ΠΌΠΏ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ², Ρ‡Ρ‚ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ сохранСны для использования ΠΏΠΎΠ·ΠΆΠ΅. Какого использования? Π₯ΠΎΡ€ΠΎΡˆΠΎ, это Ρ‚Π΅ΠΌΠ° ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ части этой Π³Π»Π°Π²Ρ‹.

ΠŸΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΡ

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ², ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ с Π½ΠΈΠΌΠΈ Π΄Π΅Π»Π°Ρ‚ΡŒ. На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π°Π·, Π΄Π°Π²Π°ΠΉΡ‚Π΅ просто ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈΡ… Π² наш Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ рСгистр D0. Π˜ΠΌΠ΅Π΅Ρ‚ смысл ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Ρƒ ΠΆΠ΅ ΡΠ°ΠΌΡƒΡŽ идСю, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ использовали для Alloc, Ρ‚.Π΅. сдСлаСм ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, которая ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ². Нам Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ машино-зависимоС содСрТимоС. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ выглядит Ρ‚Π°ΠΊ:

{–}

{ Load a Variable to Primary Register }

procedure LoadVar(Name, Typ: char);

begin

Move(Typ, Name + '(PC)', 'D0');

end;

{–}

По ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ для 68000, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ MOVE. Π‘Ρ‹Π»ΠΎ Π±Ρ‹ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΊΠΎΠ΄Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для этих инструкций ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ:

{–}

{ Generate a Move Instruction }

procedure Move(Size: char; Source, Dest: String);

begin

EmitLn('MOVE.' + Size + ' ' + Source + ',' + Dest);

end;

{–} 

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ эти Π΄Π²Π΅ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ – строго Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΊΠΎΠ΄Π°; ΠΎΠ½ΠΈ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ошибок ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ прСдоставляСт эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏΡ‹, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΌΡ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ – Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π­Ρ‚ΠΎ Π·Π²ΡƒΡ‡ΠΈΡ‚ ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π° для Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ распознаватСля:

{–}

{ Recognize a Legal Variable Type }

function IsVarType(c: char): boolean;

begin

IsVarType := c in ['B', 'W', 'L'];

end;

{–}

Π—Π°Ρ‚Π΅ΠΌ, Π±Ρ‹Π»ΠΎ Π±Ρ‹ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, которая ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Ρ‚ Ρ‚ΠΈΠΏ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈΠ· Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² Π² Ρ‚ΠΎ ΠΆΠ΅ врСмя провСряя Π΅Π³ΠΎ Π½Π° Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ:

{–}

{ Get a Variable Type from the Symbol Table }

function VarType(Name: char): char;

var Typ: char;

begin

Typ := TypeOf(Name);

if not IsVarType(Typ) then Abort('Identifier ' + Name +

' is not a variable');

VarType := Typ;

end;

{–}

ВооруТСнная этими инструмСнтами, ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰Π°Ρ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, становится Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ:

{–}

{ Load a Variable to the Primary Register }

procedure Load(Name: char);

begin

LoadVar(Name, VarType(Name));

end;

{–}

(ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅ для ΠΎΠ±Π΅ΡΠΏΠΎΠΊΠΎΠΈΠ²ΡˆΠΈΡ…ΡΡ: я знаю, знаю, всС это ΠΎΡ‡Π΅Π½ΡŒ нСэффСктивно. Π’ ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΌΡ‹, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, прСдприняли Π±Ρ‹ шаги Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ³ΠΎ Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ влоТСния Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€. НС Π²ΠΎΠ»Π½ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΎΠ± этом. Π­Ρ‚ΠΎ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅, ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅? Π‘ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈ ΠΏΠΎΠ½ΡΡ‚ΡŒ Π΅Π³ΠΎ, Ρ‡Π΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚ Π½ΠΎ быстро. Если Π²Ρ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΡ‚Π΅ свой компилятор ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ нСсчастны ΠΎΡ‚ Π΅Π³ΠΎ быстродСйствия, Π²Ρ‹ Π²ΠΎΠ»ΡŒΠ½Ρ‹ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΈ Π΄ΠΎΡ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ для Π±ΠΎΠ»Π΅Π΅ быстрой Ρ€Π°Π±ΠΎΡ‚Ρ‹).

Π‘Ρ‹Π»ΠΎ Π±Ρ‹ Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΉ ΠΈΠ΄Π΅Π΅ΠΉ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ сСйчас. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΏΠΎΠΊΠ° Π½Π΅ ΠΈΠΌΠ΅Π΅ΠΌ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с опСрациями присваивания, я просто Π΄ΠΎΠ±Π°Π²ΠΈΠ» строки:

Load('A');

Load('B');

Load('C');

Load('X');

Π² ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Ρ€Π°Π·Π΄Π΅Π» объявлСния Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ комбинациями объявлСний Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ошибки.

Π― ΡƒΠ²Π΅Ρ€Π΅Π½, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΡƒΠ΄ΠΈΠ²Π»Π΅Π½Ρ‹, ΡƒΠ·Π½Π°Π², Ρ‡Ρ‚ΠΎ сохранСниС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ ΠΈΡ… Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅. НСобходимыС ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ дальшС:

{–}

{ Store Primary to Variable }

procedure StoreVar(Name, Typ: char);

begin

EmitLn('LEA ' + Name + '(PC),A0');

Move(Typ, 'D0', '(A0)');

end;

{–}

{ Store a Variable from the Primary Register }

procedure Store(Name: char);

begin

StoreVar(Name, VarType(Name));

end;

{–}

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΈΡ… Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, достаточно Π»Π΅Π³ΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ присваивания. Π§Ρ‚ΠΎ ΠΌΡ‹ сдСлаСм – создадим ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Block, которая ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ приваивания, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Expression, которая ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π² качСствС допустимых Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅. Π’ΠΎΡ‚ ΠΎΠ½ΠΈ:

{–}

{ Parse and Translate an Expression }

procedure Expression;

var Name: char;

begin

Load(GetName);

end;

{–}

{ Parse and Translate an Assignment Statement }

procedure Assignment;

var Name: char;

begin

Name := GetName;

Match('=');

Expression;

Store(Name);

end;

{–}

{ Parse and Translate a Block of Statements }

procedure Block;

begin

while Look <> '.' do begin

Assignment;

Fin;

end;

end;

{–}

(Π‘Ρ‚ΠΎΠΈΡ‚ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π½ΠΎΠ²Ρ‹Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ, Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΎΡ‰Π΅ ΠΈ яснСС Ρ‡Π΅ΠΌ Ρ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ Ρ€Π°Π½Π΅Π΅. Π­Ρ‚ΠΎ Π² основном блягодаря нашим усилиям ΠΏΠΎ изоляции ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π°.)

Π•ΡΡ‚ΡŒ ΠΎΠ΄Π½Π° нСбольшая назойливая ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°. ΠŸΡ€Π΅ΠΆΠ΄Π΅ ΠΌΡ‹ использовали Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΡƒΡŽ Ρ‚ΠΎΡ‡ΠΊΡƒ Паскаля Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒΡΡ ΠΈΠ· ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ TopDecl. Π’Π΅ΠΏΠ΅Ρ€ΡŒ это Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ символ... ΠΎΠ½ использован для Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Block. Π’ ΠΏΡ€Π΅Π΄ΡƒΠ΄ΡƒΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… ΠΌΡ‹ использовали для Π²Ρ‹Ρ…ΠΎΠ΄Π° символ BEGIN (сокращСнно "b"). Но ΠΎΠ½ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ°ΠΊ символ Ρ‚ΠΈΠΏΠ°.

РСшСниС, хотя ΠΈ являСтся отчасти ΠΊΠ»ΡƒΠ΄ΠΆΠ΅ΠΌ, достаточно простоС. Для обозначСния BEGIN ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ 'B' Π² Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ рСгистрС. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚Π΅ символ Π² Ρ†ΠΈΠΊΠ»Π΅ WHILE Π²Π½ΡƒΡ‚Ρ€ΠΈ TopDecl с "." Π½Π° "B" ΠΈ всС Π±ΡƒΠ΄Π΅Ρ‚ прСкрасно.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Π·Π°Π΄Π°Ρ‡Ρƒ, ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ² ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

{–}

{ Main Program }

begin

Init;

TopDecls;

Match('B');

Fin;

Block;

DumpTable;

end.

{–}

(ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ я Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Π» Ρ€Π°ΡΡΡ‚Π°Π²ΠΈΡ‚ΡŒ нСсколько ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΉ ΠΊ Fin Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ пСрСносов строк.)

ОК, запуститС эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ввСсти:

ba { byte a } *** НЕ ΠΠΠ‘Π˜Π ΠΠ™Π’Π• ΠšΠžΠœΠœΠ•ΠΠ’ΠΠ Π˜Π˜!!! ***

wb { word b }

lc { long c }

B { begin }

a=a

a=b

a=c

b=a

b=b

b=c

c=a

c=b

c=c

.

Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ объявлСния Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ сгСнСрированный ΠΊΠΎΠ΄, Ρ€Π°ΡΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ ΠΏΠ°ΠΌΡΡ‚ΡŒ. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ присваивания Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΈ сохраняСт Π΅Π΅, Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°.

Π•ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° нСбольшая ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: сгСнСрированный ΠΊΠΎΠ΄ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ!

ВзглянитС Π½Π° ΠΊΠΎΠ΄ для a=c:

MOVE.L C(PC),D0

LEA A(PC),A0

MOVE.B D0,(A0)

Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ. Он ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΡΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΡŽ ΠΌΠ»Π°Π΄ΡˆΠΈΡ… восьми Π±ΠΈΡ‚ C Π² A, Ρ‡Ρ‚ΠΎ являСтся ΠΏΡ€ΠΈΠΌΠ»Π΅ΠΌΡ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ. Π­Ρ‚ΠΎ ΠΏΠΎΡ‡Ρ‚ΠΈ всС, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ.

Но Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ, взглянитС Π½Π° ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½Ρ‹ΠΉ случай. Для c=a гСнСрируСтся Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠ΄:

MOVE.B A(PC),D0

LEA C(PC),A0

MOVE.L D0,(A0)

Π­Ρ‚ΠΎ Π½Π΅ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ. Он ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΡΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΡŽ Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ A Π² ΠΌΠ»Π°Π΄ΡˆΠΈΡ… восьми Π±ΠΈΡ‚Π°Ρ… D0. Богласно ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ для процСссора 68000 ΡΡ‚Π°Ρ€ΡˆΠΈΠ΅ 24 Π±ΠΈΡ‚Π° останутся Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ сохраняСм всС 32 Π±ΠΈΡ‚Π° Π² C, любой мусор, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» Π² этих ΡΡ‚Π°Ρ€ΡˆΠΈΡ… разрядах, Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ сохранСн. ΠΠ΅Ρ…ΠΎΡ€ΠΎΡˆΠΎ.

Π’ΠΎ, с Ρ‡Π΅ΠΌ ΠΌΡ‹ сСйчас ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ назваСтся ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ прСобразования Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ»ΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅, Ρ‡Π΅ΠΌ ΠΌΡ‹ сдСлаСм Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ², Π΄Π°ΠΆΠ΅ Ссли это просто ΠΈΡ… ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Π²ΡΡ‚Ρ€Π΅Ρ‚ΠΈΡ‚ΡŒΡΡ с этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ. Π­Ρ‚ΠΎ Π½Π΅ самая простая Ρ‡Π°ΡΡ‚ΡŒ компилятора. Π‘ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ошибок, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ я Π²ΠΈΠ΄Π΅Π» Π² ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½Ρ‹Ρ… компиляторах, ΠΈΠΌΠ΅Π»ΠΈ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ ΠΊ ошибкам прСобразования Ρ‚ΠΈΠΏΠΎΠ² для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ нСизвСстной ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Как ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, сущСствуСт компромисс ΠΌΠ΅ΠΆΠ΄Ρƒ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ компилятора ΠΈ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌ качСством сгСнСрированного ΠΊΠΎΠ΄Π°, ΠΈ, ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, ΠΌΡ‹ Π²Ρ‹Π±Π΅Ρ€Π΅ΠΌ ΠΏΡƒΡ‚ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сохранит компилятор простым. Π― Π΄ΡƒΠΌΠ°ΡŽ Π²Ρ‹ Π½Π°Π΄Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ с Ρ‚Π°ΠΊΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ΄ достаточным ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅ΠΌ.