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

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

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

// Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈΠ· строки подстроки, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ

// ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΡŽ <Number>, ΠΈ вычислСниС этого числа

// S β€” строка, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ выдСляСтся подстрока

// Π  β€” Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² строкС, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π΄ΠΎΠ»ΠΆΠ½ΠΎ

// Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ число. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

// этот ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ содСрТит Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ послС числа

function Number(const S: string; var P: Integer): Extended;

var

 InitPos: Integer;

begin

 // InitPos Π½Π°ΠΌ понадобится для выдСлСния подстроки,

 // которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° Π² StrToFloat

 InitPos := Π ;

 if (Π  <= Length(S)) and IsSign(S[P]) then Inc(P);

 if (P > Length(S)) or not IsDigit(S[P]) then

  raise ESyntaxError.Create(

   'ΠžΠΆΠΈΠ΄Π°Π΅Ρ‚ΡΡ Ρ†ΠΈΡ„Ρ€Π° Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ' + IntToStr(Π ));

 repeat

  Inc(P);

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

 if (P <= Length(S)) and IsSeparator(S[P]) then begin

  Inc(P);

  if (P > Length(S)) or not IsDigit(S[P]) then

   raise ESyntaxError.Create(

    'ΠžΠΆΠΈΠ΄Π°Π΅Ρ‚ΡΡ Ρ†ΠΈΡ„Ρ€Π° Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ' + IntToStr(Π ));

  repeat

   Inc(P);

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

 end;

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

 begin

  Inc(P);

  if Π  > Length(S) then

   raise ESyntaxError.Create('НСоТиданный ΠΊΠΎΠ½Π΅Ρ† строки');

  if IsSign(S[P]) then Inc(P);

  if (P > Length(S)) or not IsDigit(S[P]) then

   raise ESyntaxError.Create(

    'ΠžΠΆΠΈΠ΄Π°Π΅Ρ‚ΡΡ Ρ†ΠΈΡ„Ρ€Π° Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ' + IntToStr(Π ));

  repeat

   Inc(P);

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

 end;

 Result := StrToFloat(Copy(S, InitPos, P - InitPos));

end;


// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° символа Π½Π° соотвСтствиС <Operator>

function IsOperator(Ch: Char): Boolean;

begin

 Result := Ch in ['+', '-', '*', '/'];

end;


// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° строки Π½Π° соотвСтствиС <Expr>

// ΠΈ вычислСниС выраТСния

function Expr(const S: string): Extended;

var

 P: Integer;

 OpSymb: Char;

begin

 P := 1;

 Result := Number(S, P);

 while (P <= Length(S)) and IsOperator(S[P]) do

 begin

  OpSymb := S[P];

  Inc(P);

  case OpSymb of

  '+': Result := Result + Number(S, P);

  '-': Result := Result - Number(S, P);

  '*': Result := Result * Number(S, P);

  '/': Result := Result / Number(S, P);

  end;

 end;

 if P <= Length(S) then

  raise ESyntaxError.Create(

   'HeΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ символ Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ' + IntToStr(Π ));

end;

Код ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ практичСски Π±Π΅Π· ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π², Ρ‚.ΠΊ. ΠΎΠ½ ΠΎΡ‡Π΅Π½ΡŒ простой, ΠΈ всС ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹, Π·Π°ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠ΅ упоминания, ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈ Π² тСкстС. На ΠΏΡ€ΠΈΠ»Π°Π³Π°Π΅ΠΌΠΎΠΌ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС находится ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° SimpleCalcSample, которая дСмонстрируСт Ρ€Π°Π±ΠΎΡ‚Ρƒ нашСго ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€Π°. ΠšΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€ выполняСт дСйствия Π½Π°Π΄ числами слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ, Π±Π΅Π· ΡƒΡ‡Π΅Ρ‚Π° ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Ρ‚.Π΅. вычислСниС выраТСния "2+2*2" даст 8.

Π“Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° выраТСния являСтся простой для Ρ€Π°Π·Π±ΠΎΡ€Π°, Ρ‚.ΠΊ. Ρ€Π°Π·Π±ΠΎΡ€ выраТСния ΠΈΠ΄Π΅Ρ‚ слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ, ΠΈ для соотнСсСния ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ части строки с Ρ‚Π΅ΠΌ ΠΈΠ»ΠΈ ΠΈΠ½Ρ‹ΠΌ Π½Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ символом Π½Π° любом этапС Π°Π½Π°Π»ΠΈΠ·Π° достаточно Π·Π½Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ. Π’Π°ΠΊΠΈΠ΅ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠΈ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ LR(1)-Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ°ΠΌΠΈ (Π² Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±Ρ‰Π΅ΠΌ случаС трСбуСтся Π½Π΅ ΠΎΠ΄ΠΈΠ½ символ, Π° ΠΎΠ΄Π½Π° лСксСма). Класс этих Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊ Π±Ρ‹Π» исслСдован ΠšΠ½ΡƒΡ‚ΠΎΠΌ.

Π“Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° Паскаля Π½Π΅ относится ΠΊ классу LR(1)-Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊ ΠΈΠ·-Π·Π° ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π²ΡˆΠ΅ΠΉΡΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ отнСсСния else ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΌΡƒ if. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, приходится Π²Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π΄Π²Π° Π½Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… символа β€” Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΡ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° if (с else) ΠΈ Π½Π΅Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎΠΉ (Π±Π΅Π· else). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, встрСтив Π² тСкстС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ лСксСму if, синтаксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ сразу отнСсти Π΅Π΅ ΠΊ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ· этих символов, ΠΏΠΎΠΊΠ° Π½Π΅ продвинСтся Π²ΠΏΠ΅Ρ€Π΅Π΄ ΠΈ Π½Π΅ натолкнСтся Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΈΠ»ΠΈ отсутствиС else. А ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ if ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ Π² Ρ†ΠΈΠΊΠ»Π°Ρ… for, while ΠΈΠ»ΠΈ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ with, для Π½ΠΈΡ… Ρ‚Π°ΠΊΠΆΠ΅ приходится Π²Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΡƒΡŽ ΠΈ Π½Π΅Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ. ИмСнно ΠΈΠ·-Π·Π° этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π’ΠΈΡ€Ρ‚ (Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Паскаля) отказался ΠΎΡ‚ ΠΈΠ΄Π΅ΠΈ составного ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΠΈ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π» синтаксис Π² своСм Π½ΠΎΠ²ΠΎΠΌ языкС ΠžΠ±Π΅Ρ€ΠΎΠ½ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° else Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»Π°.

Π”Ρ€ΡƒΠ³ΠΎΠ΅ достоинство нашСй простой Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠΈ β€” Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ. Π›ΡŽΠ±Π°Ρ синтаксичСски вСрная строка Π½Π΅ допускаСт Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΠΉ Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²ΠΊΠΈ. ΠΠ΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ ΠΌΠΎΠ³Π»Π° Π±Ρ‹ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€), Ссли Π±Ρ‹ какая-Ρ‚ΠΎ опСрация ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π»Π°ΡΡŒ символом "." (Ρ‚ΠΎΡ‡ΠΊΠ°). Π’ΠΎΠ³Π΄Π° Π±Ρ‹Π»ΠΎ Π±Ρ‹ нСпонятно, Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π»ΠΈ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ "1.5" Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ число "ΠΎΠ΄Π½Π° цСлая ΠΏΡΡ‚ΡŒ дСсятых" ΠΈΠ»ΠΈ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ числами 1 ΠΈ 5. Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ выглядит нСсколько Π½Π°Π΄ΡƒΠΌΠ°Π½Π½Ρ‹ΠΌ, Π½ΠΎ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½Ρ‹Π΅ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠΈ, Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΈΠ½ΠΎΠ³Π΄Π° Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‚ΡΡ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅. НапримСр, Ссли запятая слуТит для отдСлСния Π΄Ρ€ΠΎΠ±Π½ΠΎΠΉ части числа ΠΎΡ‚ Ρ†Π΅Π»ΠΎΠΉ ΠΈ для раздСлСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² спискС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ f(1,5) ΠΌΠΎΠΆΠ΅Ρ‚, с ΠΎΠ΄Π½ΠΎΠΉ стороны, Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ f с ΠΎΠ΄Π½ΠΈΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ 1.5, Π° с Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” ΠΊΠ°ΠΊ Π²Ρ‹Π·ΠΎΠ² Π΅Π΅ с двумя Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ 1 ΠΈ 5. ΠŸΡ€Π°Π²ΠΈΠ»Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½Ρ‹Ρ… ситуаций Π½Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅ БНЀ, ΠΈΡ… приходится ΠΎΠ±ΡŠΡΡΠ½ΡΡ‚ΡŒ "Π½Π° словах", Ρ‡Ρ‚ΠΎ затрудняСт Ρ€Π°Π·Π±ΠΎΡ€ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ. Π”Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΠΉ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠΈ β€” Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° языков C/C++. Π’ Π½ΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π°, Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉΡΡ ΠΊΠ°ΠΊ "++", ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π΅ Ρ„ΠΎΡ€ΠΌΡ‹ записи β€” ΠΏΡ€Π΅Ρ„ΠΈΠΊΡΠ½ΡƒΡŽ (ΠΏΠ΅Ρ€Π΅Π΄ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ) ΠΈ ΠΏΠΎΡΡ‚Ρ„ΠΈΠΊΡΠ½ΡƒΡŽ (послС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ). ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, этот ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, поэтому Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² выраТСниях. БинтаксичСски допустимо, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π°+++b, Π½ΠΎ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° Π½Π΅ Π΄Π°Π΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚Π°, слСдуСт Π»ΠΈ это Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ (Π°++)+b ΠΈΠ»ΠΈ ΠΊΠ°ΠΊ Π°+(++b). ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ‚.ΠΊ. сущСствуСт опСрация "ΡƒΠ½Π°Ρ€Π½Ρ‹ΠΉ плюс", Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π°Π½ΠΈΠ΅ β€” Π°+(+(+b)).

4.5. Π£Ρ‡Π΅Ρ‚ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ²

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ нашим шагом станСт модификация ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€Π° Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π» ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Ρ‚. Π΅. Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»ΠΈΡΡŒ Ρ€Π°Π½ΡŒΡˆΠ΅ слоТСния ΠΈ умноТСния.

Дня ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° рассмотрим Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ "2*4+3*8/6". Наш синтаксис Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠ°ΠΊ-Ρ‚ΠΎ ΠΎΡ‚Ρ€Π°Π·ΠΈΡ‚ΡŒ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ слоТСния Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π½Π΅ числа 4 ΠΈ 3, Π° "2*4" ΠΈ "3*8/6". Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ β€” это ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… слагаСмых, ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ стоят Π·Π½Π°ΠΊΠΈ "+" ΠΈΠ»ΠΈ "-". А слагаСмыС β€” это, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… чисСл, Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π·Π½Π°ΠΊΠ°ΠΌΠΈ "*" ΠΈ "/". А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ запишСм Ρ‚ΠΎ ΠΆΠ΅ самоС Π½Π° языкС БНЀ (листинг 4.4).

Листинг 4.4. Π“Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° выраТСния с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ

<Expr> ::= <Term> {<Operator1> <Term>}

<Term> ::= <Number> {<Operator2> <Number>}

<Operator1> ::= '+' | '-'

<Operator2> ::= '*' | '/'

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ символа <Operator1> совпадаСт с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Π²Π²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Ρ€Π°Π½Π΅Π΅ символа <Sign>. Но ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ <Sign> Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ <Expr> Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ, Ρ‚.ΠΊ., Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅, Π² Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ (ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ арифмСтичСского ΠΈΠ»ΠΈ ΠΈ арифмСтичСского ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΈΠ»ΠΈ Π² Delphi"), ΠΈ Ρ‚ΠΎΠ³Π΄Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ <Operator1> Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΎ. Но это Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π·Π°Ρ‚Ρ€ΠΎΠ½ΡƒΡ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ символа <Number>, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ <Sign>.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΡΠΏΠΎΡΠΎΠ±ΠΈΡ‚ΡŒ ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€ ΠΊ Π½ΠΎΠ²Ρ‹ΠΌ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ, Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Operator Π½Π° Operator1 ΠΈ Operator2, Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Term (слагаСмоС) ΠΈ внСсти измСнСния Π² Expr. Ѐункция Number остаСтся Π±Π΅Π· измСнСния. ОбновлСнная Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€Π° выглядит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (листинг 4.5).

Листинг 4.5. РСализация ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€Π° с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ

// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° символа Π½Π° соотвСтствиС <Operator1>

function IsOperator1(Ch: Char): Boolean;

begin

 Result := Ch in ['+', '-'];

end;


// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° символа Π½Π° соотвСтствиС <Operator2>

function IsOperator2(Ch: Char): Boolean;

begin

 Result := Ch in ['*', '/'];

end;


// Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ подстроки, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ <Term>,

// ΠΈ Π΅Π΅ вычислСниС

function Term(const S: string; var P: Integer): Extended;

var

 OpSymb: Char;

begin

 Result := Number(S,P);

 while (P <= Length(S)) and IsOperator2(S[P]) do

 begin

  OpSymb := S[P];

  Inc(P);

  case OpSymb of

  '*': Result := Result * Number(S, P);

  '/': Result := Result / Number(S, P);

 end;

end;


// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° строки Π½Π° соотвСтствиС <Expr>

// ΠΈ вычислСниС выраТСния

function Expr(const S: string): Extended;

var

 P: Integer;

 OpSymb: Char;

begin

 P := 1;

 Result := Term(S, P);

 while (P <= Length(S)) and IsOperator1(S[P]) do

 begin

  OpSymb := S[P];

  Inc(P);