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

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

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

ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π΅ΠΉ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π² этом случаС просто Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² ΠΈ поиска ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов. ВСрсия Scan, показанная Π½ΠΈΠΆΠ΅, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ провСряСт ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° ΠΎΠΏΠ΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠΌ ΠΈ Π½Π΅ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ³Π°Π΅Ρ‚ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ.

{–}

{ Scan the Current Identifier for Keywords }

procedure Scan;

begin

if Token = 'x' then

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

end;

{–}

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

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ вСрсия MatchString Π·Π°ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ символьно-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Match. Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΈ Match ΠΎΠ½Π° Π½Π΅ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ³Π°Π΅Ρ‚ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ.

{–}

{ Match a Specific Input String }

procedure MatchString(x: string);

begin

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

Next;

end;

{–}

Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ компилятора

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

ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Block Π½Π΅ измСняСтся, Π½ΠΎ мСняСтся Π΅Π΅ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅:

{–}

{ Parse and Translate a Block of Statements }

procedure Block;

begin

Scan;

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

case Token of

'i': DoIf;

'w': DoWhile;

'R': DoRead;

'W': DoWrite;

else Assignment;

end;

Scan;

end;

end;

{–}

НС Π·Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ новая вСрсия Scan Π½Π΅ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ³Π°Π΅Ρ‚ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΎΠ½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сканируСт ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова. Π’Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ΠΎΠΉ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Block.

Π’ ΠΎΠ±Ρ‰ΠΈΡ… Ρ‡Π΅Ρ€Ρ‚Π°Ρ…, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Look Π½Π° Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Token. НапримСр:

{–}

{ Parse and Translate a Boolean Expression }

procedure BoolExpression;

begin

BoolTerm;

while IsOrOp(Token) do begin

Push;

case Token of

'|': BoolOr;

'~': BoolXor;

end;

end;

end;

{–}

Π’ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°Ρ… Ρ‚ΠΈΠΏΠ° Add ΠΌΡ‹ большС Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Match. Нам Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Next для продвиТСния Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°:

{–}

{ Recognize and Translate an Add }

procedure Add;

begin

Next;

Term;

PopAdd;

end;

{–}

Π£ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ структуры фактичСски Π±ΠΎΠ»Π΅Π΅ простыС. ΠœΡ‹ просто Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Next для продвиТСния Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… конструкций:

{–}

{ Recognize and Translate an IF Construct }

procedure Block; Forward;

procedure DoIf;

var L1, L2: string;

begin

Next;

BoolExpression;

L1 := NewLabel;

L2 := L1;

BranchFalse(L1);

Block;

if Token = 'l' then begin

Next;

L2 := NewLabel;

Branch(L2);

PostLabel(L1);

Block;

end;

PostLabel(L2);

MatchString('ENDIF');

end;

{–}

Π­Ρ‚ΠΎ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ измСнСния. Π’ листингС Tiny Version 1.1, Π΄Π°Π½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅, я Ρ‚Π°ΠΊΠΆΠ΅ сдСлал ряд Π΄Ρ€ΡƒΠ³ΠΈΡ… Β«ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½ΠΈΠΉΒ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹. ΠŸΠΎΠ·Π²ΠΎΠ»ΡŒΡ‚Π΅ ΠΌΠ½Π΅ ΠΊΡ€Π°Ρ‚ΠΊΠΎ Ρ€Π°Π·ΡŠΡΡΠ½ΠΈΡ‚ΡŒ ΠΈΡ…:

1. Π― ΡƒΠ΄Π°Π»ΠΈΠ» Π΄Π²Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Prog ΠΈ Main ΠΈ объСдинил ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅. Они каТСтся Π½Π΅ добавляли ясности... фактичСски ΠΎΠ½ΠΈ просто Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ загрязняли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ.

2. Π― ΡƒΠ΄Π°Π»ΠΈΠ» ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова PROGRAM ΠΈ BEGIN ΠΈΠ· списка ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов. КаТдоС ΠΈΠ· Π½ΠΈΡ… появляСтся Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π½Π΅Ρ‚ нСобходимости ΠΈΡΠΊΠ°Ρ‚ΡŒ Π΅Π³ΠΎ.

3. ОбТСгшись ΠΎΠ΄Π½Π°ΠΆΠ΄Ρ‹ Π½Π° Ρ‡Ρ€Π΅Π·ΠΌΠ΅Ρ€Π½ΠΎΠΉ Π΄ΠΎΠ·Π΅ ΡΠΎΠΎΠ±Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, я Π½Π°ΠΏΠΎΠΌΠ½ΠΈΠ» сСбС, Ρ‡Ρ‚ΠΎ TINY ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ Π±Ρ‹Ρ‚ΡŒ минималистским языком. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я Π·Π°ΠΌΠ΅Π½ΠΈΠ» ΠΏΡ€ΠΈΡ‡ΡƒΠ΄Π»ΠΈΠ²ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΡƒΠ½Π°Ρ€Π½ΠΎΠ³ΠΎ минуса Π½Π° ΡΠ°ΠΌΡƒΡŽ ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ ΠΊΠ°ΠΊΡƒΡŽ ΠΌΠΎΠ³ ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ. Гигантский шаг Π½Π°Π·Π°Π΄ Π² качСствС ΠΊΠΎΠ΄Π°, Π½ΠΎ ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠ΅ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΠ΅ компилятора. Для использования Π΄Ρ€ΡƒΠ³ΠΎΠΉ вСрсии ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌ мСстом Π±Ρ‹Π» Π±Ρ‹ KISS.

4. Π― Π΄ΠΎΠ±Π°Π²ΠΈΠ» нСсколько ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ ошибок Ρ‚ΠΈΠΏΠ° CheckTable ΠΈ CheckDup ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΠ» встроСнный ΠΊΠΎΠ΄ Π½Π° ΠΈΡ… Π²Ρ‹Π·ΠΎΠ²Ρ‹. Π­Ρ‚ΠΎ Π½Π°Π²Π΅Π»ΠΎ порядок Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ….

5. Π― ΡƒΠ±Ρ€Π°Π» ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ ошибок ΠΈΠ· ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π° Ρ‚ΠΈΠΏΠ° Store ΠΈ помСстил ΠΈΡ… Π² ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π°Π½Π°Π»ΠΈΠ·Π°, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΎΠ½ΠΈ относятся. Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Assignment.

6. БущСствовала ошибка Π² InTable ΠΈ Locate которая заставляла ΠΈΡ… ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ всС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ вмСсто ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с достовСрными Π΄Π°Π½Π½Ρ‹ΠΌΠΈ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΠ½ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ допустимыС ячСйки. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ ΡƒΡΡ‚Ρ€Π°Π½ΠΈΡ‚ΡŒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ², которая Π±Ρ‹Π»Π° Π² Init.

7. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° AddEntry Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠΉ.

8. Π― подчистил ΠΊΠΎΠ΄ для ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΉ Π΄ΠΎΠ±Π°Π²ΠΈΠ² Π½ΠΎΠ²Ρ‹Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ CompareExpression ΠΈ NextExpression.

9. Π― устранил ΠΎΡˆΠΈΠ±ΠΊΡƒ Π² ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Read... старая вСрсия Π½Π΅ выполняла ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ компилятор Tiny ΠΏΠΎΠΊΠ°Π·Π°Π½ Π½ΠΈΠΆΠ΅. НС считая ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова PROGRAM ΠΎΠ½ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ самый язык Ρ‡Ρ‚ΠΎ ΠΈ Ρ€Π°Π½ΡŒΡˆΠ΅. Он просто Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Ρ‡ΠΈΡ‰Π΅ ΠΈ, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ, Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΉ. Он ΠΌΠ½Π΅ нравится.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Π³Π»Π°Π²Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅: спСрва обсуТдСниС Ρ‚ΠΎΡ‡Π΅ΠΊ с запятой ΠΈ всС, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π»ΠΎ мСня Ρ‚Π°ΠΊΠΎΠΌΡƒ бСспорядку. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ займСмся ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ ΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ. Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ этих возмоТностСй Π΄Π°Π»Π΅ΠΊΠΎ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½Π΅Ρ‚ нас Π½Π° ΠΏΡƒΡ‚ΠΈ ΠΊ Π²Ρ‹Π²Π΅Π΄Π΅Π½ΠΈΡŽ KISS ΠΈΠ· ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Β«ΠΈΠ³Ρ€ΡƒΡˆΠ΅Ρ‡Π½Ρ‹Ρ… языков». ΠœΡ‹ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ ΠΎΡ‡Π΅Π½ΡŒ Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ возмоТности Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ΅Ρ€ΡŠΠ΅Π·Π½Ρ‹ΠΉ компилятор.

TINY VERSION 1.1

{–}

program Tiny11;

{–}

{ Constant Declarations }

const TAB = ^I;

CR = ^M;

LF = ^J;

LCount: integer = 0;

NEntry: integer = 0;

{–}

{ 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 }

const MaxEntry = 100;

var ST : array[1..MaxEntry] of Symbol;

SType: array[1..MaxEntry] of char;

{–}

{ Definition of Keywords and Token Types }

const NKW = 9;

NKW1 = 10;

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

('IF', 'ELSE', 'ENDIF', 'WHILE', 'ENDWHILE',

'READ', 'WRITE', 'VAR', 'END');

const KWcode: string[NKW1] = 'xileweRWve';

{–}

{ 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;

{–}

{ Report an Undefined Identifier }

procedure Undefined(n: string);

begin

Abort('Undefined Identifier ' + n);

end;

{–}

{ Report a Duplicate Identifier }

procedure Duplicate(n: string);

begin

Abort('Duplicate Identifier ' + n);

end;

{–}

{ Check to Make Sure the Current Token is an Identifier }

procedure CheckIdent;

begin

if Token <> 'x' then Expected('Identifier');

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 a Boolean Orop }

function IsOrop(c: char): boolean;

begin

IsOrop := c in ['|', '~'];

end;

{–}

{ Recognize a Relop }

function IsRelop(c: char): boolean;

begin

IsRelop := c in ['=', '#', '<', '>'];

end;

{–}

{ Recognize White Space }

function IsWhite(c: char): boolean;

begin

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

end;

{–}

{ Skip Over Leading White Space }

procedure SkipWhite;

begin

while IsWhite(Look) do

GetChar;

end;

{–}

{ Table Lookup }

function Lookup(T: TabPtr; s: string; n: integer): integer;

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;

{–}

{ Locate a Symbol in Table }

{ Returns the index of the entry. Zero if not present. }

function Locate(N: Symbol): integer;

begin

Locate := Lookup(@ST, n, NEntry);

end;

{–}

{ Look for Symbol in Table }

function InTable(n: Symbol): Boolean;

begin

InTable := Lookup(@ST, n, NEntry) <> 0;

end;

{–}

{ Check to See if an Identifier is in the Symbol Table }

{ Report an error if it's not. }

procedure CheckTable(N: Symbol);

begin

if not InTable(N) then Undefined(N);

end;

{–}

{ Check the Symbol Table for a Duplicate Identifier }

{ Report an error if identifier is already in table. }

procedure CheckDup(N: Symbol);

begin

if InTable(N) then Duplicate(N);

end;

{–}

{ Add a New Entry to Symbol Table }

procedure AddEntry(N: Symbol; T: char);

begin

CheckDup(N);

if NEntry = MaxEntry then Abort('Symbol Table Full');

Inc(NEntry);

ST[NEntry] := N;

SType[NEntry] := T;

end;

{–}

{ Get an Identifier }

procedure GetName;

begin

SkipWhite;

if Not IsAlpha(Look) then Expected('Identifier');

Token := 'x';

Value := '';

repeat

Value := Value + UpCase(Look);

GetChar;

until not IsAlNum(Look);

end;

{–}

{ Get a Number }

procedure GetNum;

begin

SkipWhite;

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

Token := '#';

Value := '';

repeat

Value := Value + Look;

GetChar;

until not IsDigit(Look);

end;

{–}

{ Get an Operator }

procedure GetOp;

begin

SkipWhite;

Token := Look;

Value := Look;

GetChar;

end;

{–}

{ Get the Next Input Token }

procedure Next;

begin

SkipWhite;

if IsAlpha(Look) then GetName

else if IsDigit(Look) then GetNum

else GetOp;

end;

{–}

{ Scan the Current Identifier for Keywords }

procedure Scan;

begin

if Token = 'x' then

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

end;

{–}

{ Match a Specific Input String }

procedure MatchString(x: string);

begin

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

Next;

end;

{–}

{ Output a String with Tab }

procedure Emit(s: string);