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

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

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

Π’ΠΎΠ³Π΄Π° ΠΌΡ‹ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅ΠΌ всС Π΅Ρ‰Π΅ Π½ΡƒΠΆΠ΄Π°ΡΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² GetName ΠΈ GetNum, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΌΡ‹ использовали ΠΈΡ… Π² Ρ€Π°Π½Π½ΠΈΡ… Π³Π»Π°Π²Π°Ρ….

Π‘Π½Π°Ρ‡Π°Π»Π° Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ это шаг Π½Π°Π·Π°Π΄ ΠΈ довольно ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹ΠΉ способ. ЀактичСски ΠΆΠ΅, это ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½ΠΈΠ΅ классичСского сканСра, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ сканирования Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π°ΠΌ, Π³Π΄Π΅ ΠΎΠ½ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΡƒΠΆΠ½Ρ‹. Π’ Ρ‚Π΅Ρ… мСстах, Π³Π΄Π΅ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова Π½Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Ρ‹, ΠΌΡ‹ Π½Π΅ замСдляСм ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡŽ, ΠΈΡ‰Π° ΠΈΡ….

ОбъСдинСниС сканСра ΠΈ парсСра

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

ВсС элСмСнты ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ для синтаксичСского Π°Π½Π°Π»ΠΈΠ·Π° этого подмноТСства с использованиСм ΠΎΠ΄Π½ΠΎΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π² Π½Π°ΡˆΠΈΡ… ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…. Π― построил Π΅Π΅ остороТно скопировав эти Ρ„Π°ΠΉΠ»Ρ‹, Π½ΠΎ я Π½Π΅ посмСю ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ провСсти вас Ρ‡Π΅Ρ€Π΅Π· этот процСсс. ВмСсто этого, Π²ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΠ΅ бСспорядка, вся ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π½ΠΈΠΆΠ΅:

{–}

program KISS;

{–}

{ Constant Declarations }

const TAB = ^I;

CR = ^M;

LF = ^J;

{–}

{ Type Declarations }

type Symbol = string[8];

SymTab = array[1..1000] of Symbol;

TabPtr = ^SymTab;

{–}

{ Variable Declarations }

var Look : char; { Lookahead Character }

Lcount: integer; { Label Counter }

{–}

{ Read New Character From Input Stream }

procedure GetChar;

begin

Read(Look);

end;

{–}

{ Report an Error }

procedure Error(s: string);

begin

WriteLn;

WriteLn(^G, 'Error: ', s, '.');

end;

{–}

{ Report Error and Halt }

procedure Abort(s: string);

begin

Error(s);

Halt;

end;

{–}

{ Report What Was Expected }

procedure Expected(s: string);

begin

Abort(s + ' Expected');

end;

{–}

{ Recognize an Alpha Character }

function IsAlpha(c: char): boolean;

begin

IsAlpha := UpCase(c) in ['A'..'Z'];

end;

{–}

{ Recognize a Decimal Digit }

function IsDigit(c: char): boolean;

begin

IsDigit := c in ['0'..'9'];

end;

{–}

{ Recognize an AlphaNumeric Character }

function IsAlNum(c: char): boolean;

begin

IsAlNum := IsAlpha(c) or IsDigit(c);

end;

{–}

{ Recognize an Addop }

function IsAddop(c: char): boolean;

begin

IsAddop := c in ['+', '-'];

end;

{–}

{ Recognize a Mulop }

function IsMulop(c: char): boolean;

begin

IsMulop := c in ['*', '/'];

end;

{–}

{ Recognize White Space }

function IsWhite(c: char): boolean;

begin

IsWhite := c in [' ', TAB];

end;

{–}

{ Skip Over Leading White Space }

procedure SkipWhite;

begin

while IsWhite(Look) do

GetChar;

end;

{–}

{ Match a Specific Input Character }

procedure Match(x: char);

begin

if Look <> x then Expected('''' + x + '''');

GetChar;

SkipWhite;

end;

{–}

{ Skip a CRLF }

procedure Fin;

begin

if Look = CR then GetChar;

if Look = LF then GetChar;

SkipWhite;

end;

{–}

{ Get an Identifier }

function GetName: char;

begin

while Look = CR do

Fin;

if not IsAlpha(Look) then Expected('Name');

Getname := UpCase(Look);

GetChar;

SkipWhite;

end;

{–}

{ Get a Number }

function GetNum: char;

begin

if not IsDigit(Look) then Expected('Integer');

GetNum := Look;

GetChar;

SkipWhite;

end;

{–}

{ Generate a Unique Label }

function NewLabel: string;

var S: string;

begin

Str(LCount, S);

NewLabel := 'L' + S;

Inc(LCount);

end;

{–}

{ Post a Label To Output }

procedure PostLabel(L: string);

begin

WriteLn(L, ':');

end;

{–}

{ Output a String with Tab }

procedure Emit(s: string);

begin

Write(TAB, s);

end;

{–}

{ Output a String with Tab and CRLF }

procedure EmitLn(s: string);

begin

Emit(s);

WriteLn;

end;

{–}

{ Parse and Translate an Identifier }

procedure Ident;

var Name: char;

begin

Name := GetName;

if Look = '(' then begin

Match('(');

Match(')');

EmitLn('BSR ' + Name);

end

else

EmitLn('MOVE ' + Name + '(PC),D0');

end;

{–}

{ Parse and Translate a Math Factor }

procedure Expression; Forward;

procedure Factor;

begin

if Look = '(' then begin

Match('(');

Expression;

Match(')');

end

else if IsAlpha(Look) then

Ident

else

EmitLn('MOVE #' + GetNum + ',D0');

end;

{–}

{ Parse and Translate the First Math Factor }

procedure SignedFactor;

var s: boolean;

begin

s := Look = '-';

if IsAddop(Look) then begin

GetChar;

SkipWhite;

end;

Factor;

if s then

EmitLn('NEG D0');

end;

{–}

{ Recognize and Translate a Multiply }

procedure Multiply;

begin

Match('*');

Factor;

EmitLn('MULS (SP)+,D0');

end;

{–}

{ Recognize and Translate a Divide }

procedure Divide;

begin

Match('/');

Factor;

EmitLn('MOVE (SP)+,D1');

EmitLn('EXS.L D0');

EmitLn('DIVS D1,D0');

end;

{–}

{ Completion of Term Processing (called by Term and FirstTerm }

procedure Term1;

begin

while IsMulop(Look) do begin

EmitLn('MOVE D0,-(SP)');

case Look of

'*': Multiply;

'/': Divide;

end;

end;

end;

{–}

{ Parse and Translate a Math Term }

procedure Term;

begin

Factor;

Term1;

end;

{–}

{ Parse and Translate a Math Term with Possible Leading Sign }

procedure FirstTerm;

begin

SignedFactor;

Term1;

end;

{–}

{ Recognize and Translate an Add }

procedure Add;

begin

Match('+');

Term;

EmitLn('ADD (SP)+,D0');

end;

{–}

{ Recognize and Translate a Subtract }

procedure Subtract;

begin

Match('-');

Term;

EmitLn('SUB (SP)+,D0');

EmitLn('NEG D0');

end;

{–}

{ Parse and Translate an Expression }

procedure Expression;

begin

FirstTerm;

while IsAddop(Look) do begin

EmitLn('MOVE D0,-(SP)');

case Look of

'+': Add;

'-': Subtract;

end;

end;

end;

{–}

{ Parse and Translate a Boolean Condition }

{ This version is a dummy }

Procedure Condition;

begin

EmitLn('Condition');

end;

{–}

{ Recognize and Translate an IF Construct }

procedure Block;

Forward;

procedure DoIf;

var L1, L2: string;

begin

Match('i');

Condition;

L1 := NewLabel;

L2 := L1;

EmitLn('BEQ ' + L1);

Block;

if Look = 'l' then begin

Match('l');

L2 := NewLabel;

EmitLn('BRA ' + L2);

PostLabel(L1);

Block;

end;

PostLabel(L2);

Match('e');

end;

{–}

{ Parse and Translate an Assignment Statement }

procedure Assignment;

var Name: char;

begin

Name := GetName;

Match('=');

Expression;

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

EmitLn('MOVE D0,(A0)');

end;

{–}

{ Recognize and Translate a Statement Block }

procedure Block;

begin

while not(Look in ['e', 'l']) do begin

case Look of

'i': DoIf;

CR: while Look = CR do

Fin;

else Assignment;

end;

end;

end;

{–}

{ Parse and Translate a Program }

procedure DoProgram;

begin

Block;

if Look <> 'e' then Expected('END');

EmitLn('END')

end;

{–}

{ Initialize }

procedure Init;

begin

LCount := 0;

GetChar;

end;

{–}

{ Main Program }

begin

Init;

DoProgram;

end.

{–}

ΠŸΠ°Ρ€Π° ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π²:

Π€ΠΎΡ€ΠΌΠ° синтаксичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅Π³ΠΎ FirstTerm ΠΈ Ρ‚.ΠΏ., Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ отличаСтся ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ Ρ€Π°Π½Π΅Π΅. Π­Ρ‚ΠΎ Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° вариация Π½Π° Ρ‚Ρƒ ΠΆΠ΅ ΡΠ°ΠΌΡƒΡŽ Ρ‚Π΅ΠΌΡƒ. НС позволяйтС ΠΈΠΌ Π²Π΅Ρ€Ρ‚Π΅Ρ‚ΡŒ Π²Π°ΠΌΠΈ... измСнСния Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ дальшС.

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ я Π΄ΠΎΠ±Π°Π²ΠΈΠ» Π²Ρ‹Π·ΠΎΠ²Ρ‹ Fin Π² стратСгичСских мСстах для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ мноТСствСнных строк.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΠΊ добавлСнию сканСра, сначала скопируйтС этот Ρ„Π°ΠΉΠ» ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ выполняСт Π°Π½Π°Π»ΠΈΠ·. НС Π·Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ Β«ΠΊΠΎΠ΄Π°Β»: "i" для IF, "l" для ELSE ΠΈ "e" для ELSE ΠΈΠ»ΠΈ ENDIF.

Если ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Ρ‚ΠΎΠ³Π΄Π° Π΄Π°Π²Π°ΠΉΡ‚Π΅ поспСшим. ΠŸΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ сканСра Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ систСматичСский ΠΏΠ»Π°Π½. Π’ΠΎ всСх синтаксичСских Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ написали Π΄ΠΎ этого Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΌΡ‹ ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π»ΠΈΡΡŒ соглашСния, Ρ‡Ρ‚ΠΎ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ символ Π΄ΠΎΠ»ΠΆΠ΅Π½ всСгда Π±Ρ‹Ρ‚ΡŒ нСпустым символом. ΠœΡ‹ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π»ΠΈ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ символ Π² Init ΠΈ послС этого оставляли Β«ΠΏΠΎΠΌΠΏΡƒ Π·Π°ΠΏΡƒΡ‰Π΅Π½Π½ΠΎΠΉΒ». Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ с Π½ΠΎΠ²Ρ‹ΠΌΠΈ строками ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΅Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ символ Π½ΠΎΠ²ΠΎΠΉ строки ΠΊΠ°ΠΊ допустимый Ρ‚ΠΎΠΊΠ΅Π½.

Π’ многосимвольной вСрсии ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ: Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ прСдсказыващий символ Π΄ΠΎΠ»ΠΆΠ΅Π½ всСгда ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ Π½Π° Π½Π°Ρ‡Π°Π»Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ лСксСмы ΠΈΠ»ΠΈ Π½Π° Π½ΠΎΠ²ΠΎΠΉ строкС.

Многосимвольная вСрсия ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π½ΠΈΠΆΠ΅. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π΅Π΅ я сдСлал ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ измСнСния:

β€’ Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Token ΠΈ Value ΠΈ опрСдСлСния Ρ‚ΠΈΠΏΠΎΠ², Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для Lookup.

β€’ Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ KWList ΠΈ KWcode.

β€’ Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Lookup.

β€’ GetName ΠΈ GetNum Π·Π°ΠΌΠ΅Π½Π΅Π½Ρ‹ ΠΈΡ… ΠΌΠ½ΠΎΠ³ΠΎΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌΠΈ вСрсиями. (ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² Lookup Π±Ρ‹Π» ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ ΠΈΠ· GetName, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ).

β€’ Π‘ΠΎΠ·Π΄Π°Π½Π° новая, рудимСнтарная Scan, которая Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ GetName Π·Π°Ρ‚Π΅ΠΌ сканируСт ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова.

β€’ Π‘ΠΎΠ·Π΄Π°Π½Π° новая ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° MatchString, которая ΠΈΡ‰Π΅Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ΅ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово. Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Match, MatchString Π½Π΅ считываСт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово.

β€’ ИзмСнСн Block для Π²Ρ‹Π·ΠΎΠ²Π° Scan.

β€’ НСмного ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ‹ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Fin. Fin Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ вызываСтся ΠΈΠ· GetName.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ:

{–}

program KISS;

{–}

{ Constant Declarations }

const TAB = ^I;

CR = ^M;

LF = ^J;

{–}

{ Type Declarations }

type Symbol = string[8];

SymTab = array[1..1000] of Symbol;

TabPtr = ^SymTab;

{–}

{ Variable Declarations }

var Look : char; { Lookahead Character }

Token : char; { Encoded Token }

Value : string[16]; { Unencoded Token }

Lcount: integer; { Label Counter }

{–}

{ Definition of Keywords and Token Types }

const KWlist: array [1..4] of Symbol =

('IF', 'ELSE', 'ENDIF', 'END');

const KWcode: string[5] = 'xilee';

{–}

{ Read New Character From Input Stream }

procedure GetChar;

begin

Read(Look);

end;

{–}

{ Report an Error }

procedure Error(s: string);

begin

WriteLn;

WriteLn(^G, 'Error: ', s, '.');

end;

{–}

{ Report Error and Halt }

procedure Abort(s: string);

begin

Error(s);

Halt;

end;

{–}

{ Report What Was Expected }

procedure Expected(s: string);

begin

Abort(s + ' Expected');

end;

{–}

{ Recognize an Alpha Character }

function IsAlpha(c: char): boolean;

begin

IsAlpha := UpCase(c) in ['A'..'Z'];

end;

{–}