Синтаксический анализ VB6 - PullRequest
4 голосов
/ 30 ноября 2011

Мне нужно внедрить некоторый код в существующее приложение VB6.

Что я хотел бы сделать, это добавить код регистрации в начало каждого метода через несколько сотен файлов vb6, регистрируя имя метода и параметрысо значениями.

Написание кода легко, но я немного бьюсь над соответствием заголовка метода или свойства в синтаксисе VB6, так как существует множество вариантов и необязательных ключевых слов..

Кто-нибудь получил какие-либо предложения о том, как этого добиться?Я попытался и потерпел неудачу с RegEx и прибегнул к токенизации кода и поиску шаблонов токенов.

Ответы [ 3 ]

17 голосов
/ 30 ноября 2011

Может быть проще написать его как надстройку VB6, которая позволяет перечислять все модули / процедуры и вставлять подходящий код.
Также можно использовать MZTools , который является бесплатным и может автоматически добавлять заголовки к отдельным процедурам или новым.

1 голос
/ 30 ноября 2011

Для этого можно использовать наш инструментарий реинжиниринга программного обеспечения DMS с интерфейсом Visual Basic .

DMS анализирует исходный текст с использованием внешнего интерфейса для абстрактного синтаксического дерева, а затем позволяет применять произвольный анализ / преобразование к этим деревьям.Многие изменения преобразования могут быть выполнены с использованием преобразования программы «источник-источник» , в котором код переписывается с использованием «если вы видите этот синтаксис, замените его на , что синтаксис ", используя грамматику как способ определения абстрактных заполнителей.Это позволяет относительно легко писать преобразования в коде, используя знакомый синтаксис.Это обобщает метод OP, который пытается сопоставить последовательности токенов.

Проблема OP может быть представлена ​​как аспект, похожий на переписывание формы:

 default domain VisualBasic~VB6;

 rule function_insert_log_call(a: attributes, t: type,
                               i: IDENTIFIER, p: parameters, s:statements) 
    = function -> function
 = " \a FUNCTION \i ( \p ) AS \t
        \s
     END FUNCTION"
 -> "\a FUNCTION \i ( \p ) AS \t
        my_log(\tostring\(\i\))
        \s
     END FUNCTION";

 rule subroutine_insert_log_call(a: attributes,  
                                 i: IDENTIFIER, p: parameters, s:statements)
    = subroutine -> subroutine
 = " \a SUB \i ( \p )
        \s
     END SUB"
 -> " \a SUB \i ( \p )
        my_log(\tostring\(\i\))
        \s
     END SUB";

Эти переписывания имеют форму

 rule *rulename* ( *patternvars* ) *nonterminal* -> *nonterminal*
 = " *syntaxpattern* " 
 -> " *syntaxpattern* ";

Конкретные предоставленные правила будут распознавать заголовки и тела функций независимо от содержимого / пробелов / комментариев, поскольку они фактически совпадают с AST.«...» являются мета-кавычками, а снаружи находится синтаксис правила DMS, а внутри - синтаксис VB6.\ N внутри "..." представляет параметр (AST), который должен соответствовать нетерминальной грамматике N, объявленной в заголовке правила как ... n: N .... tostring - это пользовательская мета-функция (вызывается с помощью metaparens ()), который преобразует аргумент узла дерева в узел дерева для литеральной строки.

OP может потребоваться больше правил, чем для обработки других случаев;возможно, он хочет регистрировать вызовы GOSUB и / или записывать параметры функции в вызове log .

Другой ответ предлагает получить генератор синтаксического анализатора и, ну, в общем, определить VB6 для включения синтаксического анализа.Важно понимать, что правильно понять синтаксис VB6 очень сложно;язык плохо документирован и имеет некоторые действительно странные правила, касающиеся пробелов, операторов в строках и операторов через границы строк.Если вы не понимаете это правильно, вы просто не сможете разобрать сотни файлов.Мы должны были определить нашу собственную грамматику (как для DMS для для многих других языков ).

Подробнее об инструментарии / журналировании кода вы можете узнать, используя преобразования программы здесь

1 голос
/ 30 ноября 2011

Возможно, вы хотите что-то более надежное, чем регулярные выражения для такого проекта. Я не знаю каких-либо реализаций парсера OSS VB6, но я бы порекомендовал использовать для этого подходящий инструмент. Это действие иногда называется Аспектно-ориентированным программированием или Mixins, если вы хотите обобщить подход внедрения кода во время компиляции.

Я воспользуюсь моментом, чтобы подключить свой собственный инструмент meta # , который позволяет вам строить грамматику сопоставления с образцом именно для этих типов сценариев, но вы также можете использовать один из многих других, например Lexx / Yacc , Flexx / Bison или ANTLR.

Но даже если вы не используете мой специально, вот общая стратегия, которую я бы использовал для решения проблемы:

  1. Создание шага сборки с преобразованием кода (прекомпиляция)
  2. Разбор файлов в объектную модель
  3. Вставка новых объектов в эту модель, представляющих журнал вызовов
  4. Создание новых файлов кода на основе этой объектной модели
  5. Компилировать только сгенерированный код.
  6. Сгенерированный код является артефактом сборки и никогда не редактируется и не добавляется в систему контроля версий.

Запускайте этот шаг трансформации всякий раз, когда вы строите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...