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

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

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

var i: integer;

found: boolean;

begin

found := false;

i := n;

while (i > 0) and not found do

if s = T^[i] then

found := true

else

dec(i);

Lookup := i;

end;

{–}

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

{–}

{ Main Program }

begin

ReadLn(Token);

WriteLn(Lookup(Addr(KWList), Token, 4));

end.

{–}

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΊΠ°ΠΊ вызываСтся Lookup: функция Addr устанавливаСт ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° KWList, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ пСрСдаСтся Π² Lookup.

ОК, испытайтС Π΅Π΅. Π’Π°ΠΊ ΠΊΠ°ΠΊ здСсь ΠΌΡ‹ пропускаСм Scan, для получСния соотвСтствия Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π½Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова Π² Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ рСгистрС.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ€Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова, Π΄Π°Π»Π΅Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒΡΡ ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Ρ… для Π½ΠΈΡ… ΠΊΠΎΠ΄Π°Ρ….

Π˜Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΊΠΎΠ΄Π° ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ? Π’ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π²Π° ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΡ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°. Π­Ρ‚ΠΎ ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° идСальноС примСнСния пСрСчислимого Ρ‚ΠΈΠΏΠ° Паскаля. К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Ρ‚ΠΈΠΏΠ°

SymType = (IfSym, ElseSym, EndifSym, EndSym, Ident, Number, Operator);

ΠΈ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒΡΡ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ этого Ρ‚ΠΈΠΏΠ°. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ это. Π’ΡΡ‚Π°Π²ΡŒΡ‚Π΅ строку Π²Ρ‹ΡˆΠ΅ Π² описаниС Ρ‚ΠΈΠΏΠΎΠ².

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π΄Π²Π° описания ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…:

Token: Symtype; { Current Token }

Value: String[16]; { String Token of Look }

Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚Π΅ сканСр Ρ‚Π°ΠΊ:

{–}

{ Lexical Scanner }

procedure Scan;

var k: integer;

begin

while Look = CR do

Fin;

if IsAlpha(Look) then begin

Value := GetName;

k := Lookup(Addr(KWlist), Value, 4);

if k = 0 then

Token := Ident

else

Token := SymType(k – 1);

end

else if IsDigit(Look) then begin

Value := GetNum;

Token := Number;

end

else if IsOp(Look) then begin

Value := GetOp;

Token := Operator;

end

else begin

Value := Look;

Token := Operator;

GetChar;

end;

SkipWhite;

end;

{–}

(Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Scan сСйчас стала ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ΠΎΠΉ Π° Π½Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ).

НаконСц, ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ:

{–}

{ Main Program }

begin

Init;

repeat

Scan;

case Token of

Ident: write('Ident ');

Number: Write('Number ');

Operator: Write('Operator ');

IfSym, ElseSym, EndifSym, EndSym: Write('Keyword ');

end;

Writeln(Value);

until Token = EndSym;

end.

{–}

ΠœΡ‹ Π·Π°ΠΌΠ΅Π½ΠΈΠ»ΠΈ строку Token, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ Ρ€Π°Π½ΡŒΡˆΠ΅, Π½Π° пСрСчислимый Ρ‚ΠΈΠΏ. Scan Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΈΠΏ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Token ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ саму строку Π² Π½ΠΎΠ²ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Value.

ОК, ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ погоняйтС Π΅Π΅. Если всС Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ распознаСм ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас всС Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ, ΠΈ Π±Ρ‹Π»ΠΎ Π»Π΅Π³ΠΊΠΎ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ это ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΠΌΠ΅Π»ΠΈ Ρ€Π°Π½ΡŒΡˆΠ΅. Однако, ΠΎΠ½Π° всС Ρ€Π°Π²Π½ΠΎ каТСтся ΠΌΠ½Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Β«ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠΉΒ». ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π΅Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ, ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠ² GetName, GetNum, GetOp ΠΈ Scan Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Token ΠΈ Value, вслСдствиС этого удаляя ΠΈΡ… Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΏΠΈΠΈ. ΠšΠ°ΠΆΠ΅Ρ‚ΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠΌΠ½Π΅ΠΉ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ просмотр Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π² GetName. Π’ΠΎΠ³Π΄Π° новая Ρ„ΠΎΡ€ΠΌΠ° для этих Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ:

{–}

{ Get an Identifier }

procedure GetName;

var k: integer;

begin

Value := '';

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

while IsAlNum(Look) do begin

Value := Value + UpCase(Look);

GetChar;

end;

k := Lookup(Addr(KWlist), Value, 4);

if k = 0 then

Token := Ident

else

Token := SymType(k-1);

end;

{–}

{ Get a Number }

procedure GetNum;

begin

Value := '';

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

while IsDigit(Look) do begin

Value := Value + Look;

GetChar;

end;

Token := Number;

end;

{–}

{ Get an Operator }

procedure GetOp;

begin

Value := '';

if not IsOp(Look) then Expected('Operator');

while IsOp(Look) do begin

Value := Value + Look;

GetChar;

end;

Token := Operator;

end;

{–}

{ Lexical Scanner }

procedure Scan;

var k: integer;

begin

while Look = CR do

Fin;

if IsAlpha(Look) then

GetName

else if IsDigit(Look) then

GetNum

else if IsOp(Look) then

GetOp

else begin

Value := Look;

Token := Operator;

GetChar;

end;

SkipWhite;

end;

{–}

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ символа

По сущСству, всС сканСры, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ я ΠΊΠΎΠ³Π΄Π°-Π»ΠΈΠ±ΠΎ Π²ΠΈΠ΄Π΅Π» ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ написаны Π½Π° ПаскалС, использовали ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ пСрСчислимых Ρ‚ΠΈΠΏΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ я Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ описал. Π­Ρ‚ΠΎ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, Π½ΠΎ ΠΎΠ½ Π½Π΅ каТСтся ΠΌΠ½Π΅ самым простым ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, список Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² символов ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ довольно Π΄Π»ΠΈΠ½Π½Ρ‹ΠΌ. Π—Π΄Π΅ΡΡŒ я использовал Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ символ Β«OperatorΒ» для обозначСния всСх ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ², Π½ΠΎ я Π²ΠΈΠ΄Π΅Π» Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… фактичСски Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΊΠΎΠ΄Π° для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ.

БущСствуСт, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π΄Ρ€ΡƒΠ³ΠΎΠΉ простой Ρ‚ΠΈΠΏ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ ΠΊΠ°ΠΊ ΠΊΠΎΠ΄: символ. ВмСсто возвращСния значСния Β«OperatorΒ» для Π·Π½Π°ΠΊΠ° "+", Ρ‡Ρ‚ΠΎ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ сам символ? Π‘ΠΈΠΌΠ²ΠΎΠ» – такая ΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠ°Ρ пСрСмСнная для кодирования Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² лСксСм, ΠΎΠ½Π° Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°Ρ… Case, ΠΈ это Π³ΠΎΡ€Π°Π·Π΄ΠΎ ΠΏΡ€ΠΎΡ‰Π΅ Π½Π°Π±Ρ€Π°Ρ‚ΡŒ. Π§Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‰Π΅?

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΈΠΌΠ΅Π»ΠΈ ΠΎΠΏΡ‹Ρ‚ с ΠΈΠ΄Π΅Π΅ΠΉ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова ΠΊΠ°ΠΊ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Π΅ символы. Наши ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΡƒΠΆΠ΅ написаны Ρ‚Π°ΠΊΠΈΠΌ способом, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ использованиС этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ измСнСния Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ сдСлали.

НСкоторыС ΠΈΠ· вас ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡ‡ΡƒΠ²ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ идСя с Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠ΄ΠΎΠ² слишком дСтская. Π― Π΄ΠΎΠ»ΠΆΠ΅Π½ Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° становится Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π½Π΅ΡƒΠΊΠ»ΡŽΠΆΠ΅ΠΉ для ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Ρ‚ΠΈΠΏΠ° Β«<=Β». Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΎΡΡ‚Π°Ρ‚ΡŒΡΡ с пСрСчислимыми Ρ‚ΠΈΠΏΠ°ΠΌΠΈ, Ρ…ΠΎΡ€ΠΎΡˆΠΎ. Для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… я Ρ…ΠΎΡ‚Π΅Π» Π±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ сдСлали Π²Ρ‹ΡˆΠ΅, для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°.

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, сСйчас Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ объявлСниС Ρ‚ΠΈΠΏΠ° SymType... ΠΎΠ½ Π½Π°ΠΌ большС Π½Π΅ понадобится. И Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏ Token Π² char.

Π—Π°Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ SymType, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ константу:

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

(Π― Π±ΡƒΠ΄Ρƒ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΌ символом 'x').

НаконСц ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚Π΅ Scan ΠΈ Π΅Π³ΠΎ родствСнников ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

{–}

{ Get an Identifier }

procedure GetName;

begin

Value := '';

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

while IsAlNum(Look) do begin

Value := Value + UpCase(Look);

GetChar;

end;

Token := KWcode[Lookup(Addr(KWlist), Value, 4) + 1];

end;

{–}

{ Get a Number }

procedure GetNum;

begin

Value := '';

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

while IsDigit(Look) do begin

Value := Value + Look;

GetChar;

end;

Token := '#';

end;

{–}

{ Get an Operator }

procedure GetOp;

begin

Value := '';

if not IsOp(Look) then Expected('Operator');

while IsOp(Look) do begin

Value := Value + Look;

GetChar;

end;

if Length(Value) = 1 then

Token := Value[1]

else

Token := '?';

end;

{–}

{ Lexical Scanner }

procedure Scan;

var k: integer;

begin

while Look = CR do

Fin;

if IsAlpha(Look) then

GetName

else if IsDigit(Look) then

GetNum

else if IsOp(Look) then begin

GetOp

else begin

Value := Look;

Token := '?';

GetChar;

end;

SkipWhite;

end;

{–}

{ Main Program }

begin

Init;

repeat

Scan;

case Token of

'x': write('Ident ');

'#': Write('Number ');

'i', 'l', 'e': Write('Keyword ');

else Write('Operator ');

end;

Writeln(Value);

until Value = 'END';

end.

{–}

Π­Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ прСдыдущая вСрсия. НСбольшоС Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ Π² структурС, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Π½ΠΎ ΠΎΠ½Π° каТСтся ΠΌΠ½Π΅ Π±ΠΎΠ»Π΅Π΅ простой.

РаспрСдСлСнныС сканСры ΠΏΡ€ΠΎΡ‚ΠΈΠ² Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ…

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° лСксичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ я Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ ΠΏΠΎΠΊΠ°Π·Π°Π», вСсьма стандартна ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ 99% всСх компиляторов ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π±Π»ΠΈΠ·ΠΊΠΎΠ΅ ΠΊ Π½Π΅ΠΉ. Π­Ρ‚ΠΎ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π½Π΅ СдинствСнно возмоТная структура, ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ Π½Π΅ всСгда самая Π»ΡƒΡ‡ΡˆΠ°Ρ.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° со стандартным ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ сканСр Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… свСдСний ΠΎ контСкстС. НапримСр, ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания "=" ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ "=" (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ поэтому ΠΈ C ΠΈ Паскаль ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ для Π½ΠΈΡ… Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ строки). ВсС, Ρ‡Ρ‚ΠΎ сканСр ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, это ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ синтаксичСскому Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚ΠΎΡ‡Π½ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ исходя ΠΈΠ· контСкста, ΠΊΠ°ΠΊΠΎΠΉ это ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€. Π’ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово Β«IFΒ» Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ посрСдинС арифмСтичСского выраТСния, Π½ΠΎ Ссли Π΅ΠΌΡƒ случится ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Ρ‚Π°ΠΌ, сканСр Π½Π΅ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚ Π² этом Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ Π΅Π³ΠΎ синтаксичСскому Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ, ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π² ΠΊΠ°ΠΊ Β«IFΒ».

Π‘ Ρ‚Π°ΠΊΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ, ΠΌΡ‹ Π² Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ всю ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, ΠΈΠΌΠ΅ΡŽΡ‰ΡƒΡŽΡΡ Π² нашСм распоряТСнии. Π’ сСрСдинС выраТСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, синтаксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Β«Π·Π½Π°Π΅Ρ‚Β», Ρ‡Ρ‚ΠΎ Π½Π΅Ρ‚ Π½ΡƒΠΆΠ΄Ρ‹ ΠΈΡΠΊΠ°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово, Π½ΠΎ ΠΎΠ½ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ возмоТности ΡΠΊΠ°Π·Π°Ρ‚ΡŒ это сканСру. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ сканСр ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ это. Π­Ρ‚ΠΎ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, замСдляСт ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡŽ.

Π’ настоящих компиляторах ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠΈ часто ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΌΠ΅Ρ€Ρ‹ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ сканСром ΠΈ парсСром, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ. Но это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ΡƒΠΊΠ»ΡŽΠΆΠ΅ ΠΈ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠΈΡ‚ Ρ‡Π°ΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π² структурС компилятора.

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²ΠΎΠΉ являСтся поиск ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ способа для использования контСкстной ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, которая исходит ΠΈΠ· знания Ρ‚ΠΎΠ³ΠΎ, Π³Π΄Π΅ ΠΌΡ‹ находимся Π² синтаксичСском Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π΅. Π­Ρ‚ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ нас ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΊ ΠΏΠΎΠ½ΡΡ‚ΠΈΡŽ распрСдСлСнного сканСра, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ части сканСра Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² зависимости ΠΎΡ‚ контСкста.

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

Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ, оказываСтся, Π΄Π°ΠΆΠ΅ с ΠΌΠ½ΠΎΠ³ΠΎΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌΠΈ ΠΌΡ‹ всС Π΅Ρ‰Π΅ ΠΌΠΎΠΆΠ΅ΠΌ всСгда Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π²ΠΈΠ΄ лСксСмы исходя ΠΈΠ· Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ символа, ΠΈΡΠΊΠ»ΡŽΡ‡Π°Ρ самоС Π½Π°Ρ‡Π°Π»ΠΎ утвСрТдСния.

Π”Π°ΠΆΠ΅ Π² этой Ρ‚ΠΎΡ‡ΠΊΠ΅, СдинствСнным Π²ΠΈΠ΄ΠΎΠΌ лСксСмы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ, являСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€. Нам Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, являСтся Π»ΠΈ этот ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ словом ΠΈΠ»ΠΈ Π»Π΅Π²ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания.