Π Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΈΠΏΠ° Π»Π΅ΠΊΡΠ΅ΠΌ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΠ΅Π»ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ Π½ΠΈΠΌΠΈ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΠΈΠ»ΠΈ Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΌΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΈ "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);