Проанализировав все имеющиеся реализованные автором
Проанализировав все имеющиеся реализованные автором анализаторы, были сделаны следующие наблюдения:
- модуль (unit) создается всегда;
- включаемые файлы не используются;
- для каждого анализатора создается класс-обертка или вызывающий метод класса;
- некоторые анализаторы используют консоль для ввода символов, некоторые - потоки, некоторые файлы типа Text;
- разные анализаторы используют один и тот же разделяемый код из библиотек LexLib и YaccLib.
Реализация задачи потребовала довольно значительных изменений в исходных кодах пакета.
Встраивание в механизм работы генераторов автору показалось весьма сложным, поэтому было принято решение вносить изменения, опираясь на существующий механизм работы.
Были произведены следующие изменения.
Для того, чтобы отличать оригинальные библиотеки от измененных, имена файлов были изменены:
LexLib.pas | OLexLib.pas |
YaccLib.pas | OYaccLib.pas |
yylex.cod | yyolex.cod |
yyparse.cod | yyoparse.cod |
Работа с генерируемым файлом была поделена на два этапа. Первый - это "честная" работа Lex (Yacc) по созданию генератора. Учитывая структуру шаблона, генераторы создают метод класса, yylex или yyparse, в зависимости от анализатора. Второй этап - это работа непосредственно с созданным файлом по его доводке. В шаблон встроены некоторые подстановочные символы, которые заменяются названием модуля, класса и т.д. (полный перечень приведен ниже). Для поддержки второго этапа были введены соответствующие изменения в генераторы.
Выбор источника символов был ограничен консолью и входящим потоком. Сделано это было из соображений практичности - работу с текстовыми файлами удобно проводить и с помощью потоков, а консоль иногда все-таки нужна для коротких фильтров. Собственно выбор осуществляется при помощи параметра _useconsole конструктора класса TBaseScanner.