О чём не пишут в книгах по 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
Поделиться:
Популярные книги
Зубных дел мастер
1. Зубных дел мастер
Фантастика:
научная фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Бывшие. Война в академии магии
2. Измены
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Идеальный мир для Лекаря 7
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 3
3. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга X
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Хозяин Теней
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Опасная любовь командора
1. Проклятые луной
Фантастика:
фэнтези
5.00
рейтинг книги
Друд, или Человек в черном
Фантастика:
социально-философская фантастика
6.80
рейтинг книги
Волхв
3. Волшебник
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Мастер Разума VII
7. Мастер Разума
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен
Документальная литература:
публицистика
5.40
рейтинг книги
Сумеречный Стрелок 5
5. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Морской волк. 1-я Трилогия
1. Морской волк
Фантастика:
альтернативная история
8.71
рейтинг книги
Прогрессор поневоле
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00