Для тех, кто является экспертом по лексированию и анализу... Я пытаюсь написать серию программ в perl, которые будут анализировать мейнфрейм IBM z/OS JCL для самых разных целей, но я нахожусь в качестве препятствия в методологии. Я в основном придерживаюсь идеологии лексинга/синтаксического анализа, выдвинутой Марком Джейсоном Доминисом в "Perl верхнего порядка", но есть некоторые вещи, которые я не могу понять, как это сделать.
JCL имеет то, что называется встроенными данными, что очень похоже на документы "здесь". Я не совсем уверен, как лексиковать их в токены.
Макет для встроенных данных выглядит следующим образом:
//DDNAME DD *
this is the inline data
this is some more inline data
/*
...
Обычно "*" после "DD" означает, что следующие строки являются встроенными данными, которые заканчиваются либо "/*", либо следующей допустимой записью JCL (начиная с "//" в первых двух столбцах).
Более продвинутые, встроенные данные могут отображаться как таковые:
//DDNAME DD *,DLM=ZZ
//THIS LOOKS LIKE JCL BUT IT ACTUALLY DATA
//MORE DATA MASQUERADING AS JCL
ZZ
...
Иногда встроенные данные сами по себе являются JCL (возможно, для перекачки в программу или для внутреннего считывателя).
Но вот руб. В JCL записи составляют 80 байт, фиксированных по длине. Все прошлое столбец 72 (cols 73-80) является "комментарием". Кроме того, все, что следует за пробелом, которое следует за действительным JCL, также является комментарием. Поскольку я пытаюсь манипулировать JCL в своих программах и выплевывать его обратно, я бы хотел записать комментарии, чтобы сохранить их.
Итак, вот пример встроенных комментариев в случае встроенных данных:
//DDNAME DD *,DLM=ZZ THIS IS A COMMENT COL73DAT
data
...
ZZ
...more JCL
Первоначально предполагалось, что я мог бы извлечь самый лексер в строку JCL и сразу же создать не-токен для cols 1-72, а затем токен ([COL73COMMENT ', $1]) для столбца 73 комментарий, если таковой имеется. Затем он передал бы следующему итератору/токенизатору строку из текста cols 1-72, за которой следует токен col73.
Но как бы я, вниз по течению, захватить встроенные данные? Я изначально полагал, что самый верхний токенизатор может искать "DD\* (, DLM = (\ S *))" (или тому подобное), а затем просто продолжать извлекать записи из подающего итератора, пока не попадет в разделитель или действительный стартер JCL ( "//" ).
Но вы можете увидеть эту проблему здесь... У меня не может быть двух верхних токенизаторов... либо токенизатор, который ищет комментарии COL73, должен быть вершиной, либо токенизатор, который получает встроенные данные, должен быть наверху.
Я полагаю, что perl-парсеры имеют одинаковую задачу, поскольку видя
<<DELIM
не обязательно является концом строки, за которой следуют данные документа. В конце концов, вы можете увидеть perl like:
my $this=$obj->ingest(<<DELIM)->reformat();
inline here document data
more data
DELIM
Как бы токенизатор/парсер знал, чтобы токенизировать ") → reformat();" а затем все еще захватывать следующие записи как есть? В случае встроенных данных JCL эти строки передаются как есть, cols 73-80 НЕ являются комментариями в этом случае...
Итак, все берут на себя это? Я знаю, что будет много вопросов, разъясняющих мои потребности, и я рад прояснить столько, сколько необходимо.
Заранее благодарим за помощь...