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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «О Ρ‡Ρ‘ΠΌ Π½Π΅ ΠΏΠΈΡˆΡƒΡ‚ Π² ΠΊΠ½ΠΈΠ³Π°Ρ… ΠΏΠΎ DelphiΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 123

Автор А. Π“Ρ€ΠΈΠ³ΠΎΡ€ΡŒΠ΅Π²

Π’ зависимости ΠΎΡ‚ Ρ‚ΠΈΠΏΠ° лСксСм Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΈΠ»ΠΈ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ. НапримСр, Π² Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ "2+3" Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ лСксСмами "2", "+" ΠΈ "5" Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»Π΅Π½Ρ‹ Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π° ΠΈ Π±Π΅Π· этого. А Π² Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ 6 div 3 Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ "div" ΠΈ "3" Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС эти лСксСмы Π±ΡƒΠ΄ΡƒΡ‚ восприняты ΠΊΠ°ΠΊ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ div3. А Π²ΠΎΡ‚ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ "6" ΠΈ "div" Π½Π΅ обязатСлСн, Ρ‚.ΠΊ. 6div Π½Π΅ являСтся допустимым ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ, ΠΈ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ смоТСт ΠΎΡ‚Π΄Π΅Π»ΠΈΡ‚ΡŒ эти лСксСмы Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π° ΠΈ Π±Π΅Π· раздСлитСля. Π’ΠΎΠΎΠ±Ρ‰Π΅, Ссли подстрока, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰Π°ΡΡΡ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ слияния Π΄Π²ΡƒΡ… лСксСм, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π° ΠΊΠ°ΠΊ какая-Π»ΠΈΠ±ΠΎ другая лСксСма, Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС β€” нСобязатСлСн. Π Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ лСксСмы Π½Π΅ допускаСтся (Ρ‚.Π΅. подстрока "a 1" Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ лСксСм "Π°" ΠΈ "1", Π° Π½Π΅ ΠΊΠ°ΠΊ лСксСма "Π°1").

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ возмоТности лСксичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π². ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ β€” это ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ символов, Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰Π°ΡΡΡ с "{" ΠΈ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°ΡŽΡ‰Π°ΡΡΡ "}", которая ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€ΠΈ сСбя Π»ΡŽΠ±Ρ‹Π΅ символы, ΠΊΡ€ΠΎΠΌΠ΅ "}". ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ считаСтся Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΌ, ΠΎΠ½ допустим Π² любом мСстС, Π³Π΄Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ появлСниС Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΉ, Ρ‚.Π΅. Π² Π½Π°Ρ‡Π°Π»Π΅ ΠΈ Π² ΠΊΠΎΠ½Ρ†Π΅ строки ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ лСксСмами.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€Π° с лСксичСским Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ Ρ‚Π°ΠΊΠΆΠ΅ находится Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС ΠΈ называСтся LexicalSample.

ЛСксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π° Π²Ρ…ΠΎΠ΄Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ строку, Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π΄Π°Ρ‚ΡŒ список структур, каТдая ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… описываСт ΠΎΠ΄Π½Ρƒ лСксСму. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ эти структуры выглядят ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (листинг 4.11).

Листинг 4.11. Π’ΠΈΠΏ TLexeme для хранСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± ΠΎΠ΄Π½ΠΎΠΉ лСксСмС

TLexemeType = (

 ltEqual, ltLess, ltGreater, ltLessOrEqual,

 ltGreaterOrEqual, ltNotEqual, ltPlus, ltMinus,

 ltOr, ltXor, ltAsterisk, ltSlash, ltDiv, ltMod,

 ltAnd, ltNot, ltCap,

ltLeftBracket, ltRightBracket,

 ltSin, ltCos, ltLn,

 ltIdentifier, ltNumber, ltEnd);


TLexeme = record

 LexemeType: TLexemeType;

 Pos: Integer;

 Lexeme: string;

end;

LexemeType β€” ΠΏΠΎΠ»Π΅, содСрТащСС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ это Π·Π° лСксСма. Π’ΠΈΠΏ TLexemeType β€” это ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ пСрСчислимый Ρ‚ΠΈΠΏ, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ· Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ соотвСтствуСт ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² лСксСмы. ПолС Pos Ρ…Ρ€Π°Π½ΠΈΡ‚ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² строкС, начиная с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΈΠ΄Π΅Ρ‚ данная лСксСма. Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅ Π½ΡƒΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ синтаксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ ΠΌΠΎΠ³ Ρ‚ΠΎΡ‡Π½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ мСсто ошибки, Ссли встрСтит Π½Π΅Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΠΌΡƒΡŽ лСксСму.

ПолС Lexeme Ρ…Ρ€Π°Π½ΠΈΡ‚ саму подстроку, Ρ€Π°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡƒΡŽ ΠΊΠ°ΠΊ лСксСма. Оно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли Ρ‚ΠΈΠΏ лСксСмы Ρ€Π°Π²Π΅Π½ ltIdentifier ΠΈΠ»ΠΈ ltNumber. Для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² лСксСм достаточно ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΈΠ· поля LexemeType.

ЛСксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π² Π²ΠΈΠ΄Π΅ класса TLexicalAnalyzer. Π’ конструкторС класса выполняСтся Ρ€Π°Π·Π±ΠΎΡ€ строки ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ списка лСксСм. Π§Π΅Ρ€Π΅Π· этот ΠΆΠ΅ класс синтаксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ лСксСмам: свойство Lexeme Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ лСксСму, ΠΌΠ΅Ρ‚ΠΎΠ΄ Next позволяСт ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ. Π’Π°ΠΊ ΠΊΠ°ΠΊ наша Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° прСдусматриваСт Ρ€Π°Π·Π±ΠΎΡ€ слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ, Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹Ρ… возмоТностСй Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ синтаксичСскому Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ Π²ΠΏΠΎΠ»Π½Π΅ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚. Код Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² листингС 4.12.

Листинг 4.12. Код лСксичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°

type

 TLexicalAnalyzer = class

 private

  FLexemeList: TList;

  // НомСр Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ лСксСмы Π² спискС

  FIndex: Integer;

  function GetLexeme: PLexeme;

  // ΠŸΡ€ΠΎΠΏΡƒΡΠΊ всСго, Ρ‡Ρ‚ΠΎ являСтся Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΌ лСксСм

  procedure SkipWhiteSpace(const S: string; var P: Integer);

  // Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ лСксСмы, Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰Π΅ΠΉΡΡ с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ P

  procedure ExtractLexeme(const S: string; var P: Integer);

  // ΠŸΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ лСксСмы Π² список

  procedure PutLexeme(LexemeType: TLexemeType; Pos: Integer; const Lexeme: string);

  // Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ лСксСмы-числа

  procedure Number(const S: string; var P: Integer);

  // Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ слова ΠΈ отнСсСниС Π΅Π³ΠΎ ΠΊ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌ

  // ΠΈΠ»ΠΈ Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ словам

  procedure Word(const S: string; var P: Integer);

 public

  constructor Create(const Expr: string);

  destructor Destroy; override;

  // ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ лСксСмС

  procedure Next;

  // Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ лСксСму

  property Lexeme: PLexeme read GetLexeme;

 end;


constructor TLexicalAnalyzer.Create(const Expr: string);

var

 P: Integer;

begin

 inherited Create;

 // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ список лСксСм

 FLexemeList := TList.Create;

 // И сразу ΠΆΠ΅ заполняСм Π΅Π³ΠΎ

 Π  := 1;

 while Π  <= Length(Expr) do

 begin

  SkipWhiteSpace(Expr, P);

  ExtractLexeme(Expr, P);

 end;

 // ΠŸΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π² ΠΊΠΎΠ½Π΅Ρ† списка ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ лСксСму

 PutLexeme(ltEnd, Π , '');

 FIndex := 0;

end;


destructor TLexicalAnalyzer.Destroy;

var

 I: Integer;

begin

 for I := 0 to FLexemeList.Count - 1 do

  Dispose(PLexeme(FLexemeList[I]));

 FLexemeList.Free;

 inherited Destroy;

end;


// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ указатСля Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ лСксСму

function TLexicalAnalyzer.GetLexeme: PLexeme;

begin

 Result := FLexemeList[FIndex];

end;


// ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ лСксСмС

procedure TLexicalAnalyzer.Next;

begin

 if FIndex < FLexemeList.Count - 1 then Inc(FIndex);

end;


// ΠŸΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ лСксСмы Π² список. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π·Π°Π΄Π°ΡŽΡ‚

// ΠΎΠ΄Π½ΠΎΠΈΠΌΠ΅Π½Π½Ρ‹Π΅ поля Ρ‚ΠΈΠΏΠ° TLexeme.

procedure TLexicalAnalyzer.PutLexeme(LexemeType: TLexemeType; Pos: Integer; const Lexeme: string);

var

 NewLexeme: PLexeme;

begin

 New(NewLexeme);

 NewLexeme^.LexemeType := LexemeType;

 NewLexeme^.Pos := Pos;

 NewLexeme^.Lexeme := Lexeme;

 FLexemeList.Add(NewLexeme);

end;


// пропускаСт ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹, символы табуляции, ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ строки,

// ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² Π½Π°Ρ‡Π°Π»Π΅ ΠΈ Π² ΠΊΠΎΠ½Ρ†Π΅ строки ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ лСксСмами

procedure TLexicalAnalyzer.SkipWhiteSpace(const S: string; var P: Integer);

begin

 while (P <= Length(S)) and (S[P] in [' ', #9, #13, #10, '{']) do

  if S[P] = '{' then

  begin

   Inc(P);

   while (P <-=Length(S)) and (S[P) <> '}') do Inc(P);

   if P > Length(S) then

    raise ESyntaxError.Create('ΠΠ΅Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ');

   Inc(P);

  end

  else Inc(P);

end;


// Ѐункция выдСляСт ΠΎΠ΄Π½Ρƒ лСксСму ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π΅ Π² список

procedure TLexicalAnalyzer.ExtractLexeme(const S: string; var P: Integer);

begin

 if P > Length(S) then Exit;

 case S[P] of

 '(': begin

  PutLexeme(ltLeftBracket, P, '');

  Inc(P);

 end;

 ')': begin

  PutLexeme(ltRightBracket, P, '');

  Inc(P);

 end;

 '*': begin

  PutLexeme(ltAsterisk, P, '');

  Inc(P);

 end;

 '+': begin

  PutLexeme(ltPlus, P, '');

  Inc(P);

 end;

 '-': begin

  PutLexeme(ltMinus, P, '');

  Inc(P);

 end;

 '/': begin

  PutLexeme(ltSlash, P, '');

  Inc(P);

 end;

 '0'..'9': Number(S, P);

 '<':if (P < Length(S)) and (S[P + 1] = '=') then

 begin

  PutLexeme(ltLessOrEqual, P, '');

  Inc(P, 2);

 end

 else

  if (P < Length(S)) and (S[P + 1] = '>') then

  begin

   PutLexeme(ltNotEqual, P, '');

   Inc(P, 2);

  end

  else

  begin

   PutLexeme(ltLess, P, '');

   Inc(P);

  end;

 '=': begin

  PutLexeme(ltEqual, P, '');

  Inc(P);

 end;

 '>': if (P < Length(S)) and (S[P + 1] = '=') then

 begin

  PutLexeme(ltGreaterOrEqual, P, '');

  Inc(P, 2);

 end

 else

 begin

  PutLexeme(ltGreater, P, '');

  Inc(P);

 end;

 'A'..'Z, 'a'..'z', '_': Word(S, P);

 '^': begin

  PutLexeme(ltCap, P, '');

  Inc(P);

 end;

 else

  raise ESyntaxError.Create('НСкоррСктный символ Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ' +

   IntToStr(Π ));

 end;

end;


// Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ лСксСмы-числа

procedure TLexicalAnalyzer.Number(const S: string; var P: Integer);

var

 InitPos, RollbackPos: Integer;

 function IsDigit(Ch: Char): Boolean;

 begin

  Result := Ch in ['0'..'9'];

 end;

begin

 InitPos := P;

 // ВыдСляСм Ρ†Π΅Π»ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ числа

 repeat

  Inc(P);

 until (P < Length(S)) or not IsDigit(S[P]);

 // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π΄Ρ€ΠΎΠ±Π½ΠΎΠΉ части ΠΈ выдСляСм Π΅Ρ‘

 if (Π  <= Length(S)) and (S[P] = DecimalSeparator) then

 begin

  Inc(P);