HOP :: Lexer с перекрывающимися токенами - PullRequest
1 голос
/ 11 декабря 2011

Я использую HOP :: Lexer для сканирования BlitzMax исходного кода модуля для извлечения некоторых данных из него. Одна конкретная часть данных, в которой я сейчас заинтересован - это описание модуля.

В настоящее время я ищу описание в формате ModuleInfo "Description: foobar" или ModuleInfo "Desc: foobar". Это отлично работает. Но, к сожалению, большинство модулей, которые я сканирую, имеют свое описание, определенное в другом месте, внутри блока комментариев. Что на самом деле является обычным способом сделать это в BlitzMax, как этого ожидает генератор документации.

Вот как описание всех модулей определяется в основном исходном файле.

Rem
    bbdoc: my module description
End Rem
Module namespace.modulename

Это тоже не проблема. Но строка после End Rem также содержит данные, которые я хочу (имя модуля). Это проблема, поскольку теперь 2 определения токенов перекрывают друг друга, и после того, как первый обнаружен, он будет продолжаться с того места, где остановился (позиция сканируемого содержимого). Это означает, что токен для имени модуля ничего не обнаружит.

Да, я убедился, что мой порядок токенов правильный. Просто кажется невозможным (несколько понятным) переместить курсор назад на строку.

Небольшой фрагмент кода для извлечения описания из блока Rem-End Rem, который находится над определением модуля (не разработан, но работает для текущего тестового примера):

        [   'MODULEDESCRIPTION',
            qr/[ \t]*\bRem\n(?:\n|.)*?\s*\bEnd[ \t]*Rem\nModule[\s\t]+/i,
            sub {
                my ($label, $value) = @_;
                $value =~ /bbdoc: (.+)/;
                [$label, $1];
              }
        ],

Итак, в моем тестовом примере я сначала сканирую один комментарий, затем блок выше (MODULEDESCRIPTION), затем комментарий блока (Rem-End Rem), имя модуля и т. Д.

В настоящее время единственное решение, которое я могу придумать, это установить второй лексер только для описания модуля, хотя я бы не предпочел это. То, что я хочу, вообще возможно с HOP :: Lexer?

Источник моего Лексера можно найти на https://github.com/maximos/maximus-web/blob/develop/lib/Maximus/Class/Lexer.pm

1 Ответ

1 голос
/ 12 декабря 2011

Я решил это, добавив (слегка измененную версию) MODULEDESCRIPTION.Внутри подпрограммы я просто отфильтровываю имя модуля и возвращаю arrayref с 4-мя элементами, который позже перебираю для создания удобного в использовании массива с токенами и их значениями.

Решение снова на https://github.com/maximos/maximus-web/blob/develop/lib/Maximus/Class/Lexer.pm

Редактировать: Или позвольте мне вставить сюда фрагмент кода

        [   'MODULEDESCRIPTION',

            qr/[ \t]*\bRem\R(?:\R|.)*?\bEnd[ \t]*Rem\R\bModule[\s\t]\w+\.\w+/i,
            sub {
                my ($label, $value) = @_;
                my ($desc) = ($value =~ /\bbbdoc: (.+)/i);
                my ($name) = ($value =~ /\bModule (\w+\.\w+)/i);
                [$label, $desc, 'MODULENAME', $name];
              }
        ],
...