Delphi - сбориник статей


Решение


Проанализировав все имеющиеся реализованные автором анализаторы, были сделаны следующие наблюдения:

  • модуль (unit) создается всегда;
  • включаемые файлы не используются;
  • для каждого анализатора создается класс-обертка или вызывающий метод класса;
  • некоторые анализаторы используют консоль для ввода символов, некоторые - потоки, некоторые файлы типа Text;
  • разные анализаторы используют один и тот же разделяемый код из библиотек LexLib и YaccLib.

Обобщение наблюдений привело к тому, что было решено произвести переделку генераторов таким образом, чтобы они генерировали модули, содержащий классы, соответствующие лексическому и синтаксическому анализаторам.

Реализация задачи потребовала довольно значительных изменений в исходных кодах пакета.

Встраивание в механизм работы генераторов автору показалось весьма сложным, поэтому было принято решение вносить изменения, опираясь на существующий механизм работы.

Были произведены следующие изменения.

Для того, чтобы отличать оригинальные библиотеки от измененных, имена файлов были изменены:

БылоСтало
LexLib.pas  OLexLib.pas
 YaccLib.pas  OYaccLib.pas
 yylex.cod  yyolex.cod
 yyparse.cod  yyoparse.cod

В библиотеках OLexLib и OYaccLib были определены классы для сканера (TBaseScanner) и парсера (TBaseParser). Во вновь созданные классы были инкапсулированы все процедуры/функции и переменные соответствующих библиотек. Это дало возможность построить шаблоны так, что генераторы будут создавать анализаторы, являющиеся наследниками указанных классов. Инкапсуляция переменных и методов, используемых при разборе, внутри класса позволяет запускать несколько анализаторов одновременно.

Работа с генерируемым файлом была поделена на два этапа. Первый - это "честная" работа Lex (Yacc) по созданию генератора. Учитывая структуру шаблона, генераторы создают метод класса, yylex или yyparse, в зависимости от анализатора. Второй этап - это работа непосредственно с созданным файлом по его доводке. В шаблон встроены некоторые подстановочные символы, которые заменяются названием модуля, класса и т.д. (полный перечень приведен ниже). Для поддержки второго этапа были введены соответствующие изменения в генераторы.

Выбор источника символов был ограничен консолью и входящим потоком. Сделано это было из соображений практичности - работу с текстовыми файлами удобно проводить и с помощью потоков, а консоль иногда все-таки нужна для коротких фильтров. Собственно выбор осуществляется при помощи параметра _useconsole конструктора класса TBaseScanner.




Начало  Назад  Вперед