Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

 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

Поделиться:
Популярные книги

Мир-о-творец

Ланцов Михаил Алексеевич
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Мир-о-творец

Виконт. Книга 4. Колонист

Юллем Евгений
Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.50
рейтинг книги
Виконт. Книга 4. Колонист

Титан империи

Артемов Александр Александрович
1. Титан Империи
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Титан империи

Запретный Мир

Каменистый Артем
1. Запретный Мир
Фантастика:
фэнтези
героическая фантастика
8.94
рейтинг книги
Запретный Мир

Ты предал нашу семью

Рей Полина
2. Предатели
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты предал нашу семью

Цеховик. Книга 2. Движение к цели

Ромов Дмитрий
2. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Цеховик. Книга 2. Движение к цели

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3

Проданная невеста

Wolf Lita
Любовные романы:
любовно-фантастические романы
5.80
рейтинг книги
Проданная невеста

Волк 7: Лихие 90-е

Киров Никита
7. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк 7: Лихие 90-е

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

Приручитель женщин-монстров. Том 9

Дорничев Дмитрий
9. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 9

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Я – Орк. Том 6

Лисицин Евгений
6. Я — Орк
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 6

Совок-8

Агарев Вадим
8. Совок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совок-8