解析VB6语法

时间:2011-11-30 00:24:35

标签: parsing vb6

我需要在现有的VB6应用程序中注入一些代码。

我想要做的是在几百个vb6文件的每个方法的顶部添加日志记录代码,使用值记录方法名称和参数。

编写代码很简单,但我在苦苦挣扎的是VB6语法中的方法或属性标题的匹配,因为似乎有大量的变体和可选的关键字。

有没有人对如何实现这一点有任何建议? 我已经尝试过使用RegEx并且失败了,并且已经使用代码化代码并寻找令牌模式。

3 个答案:

答案 0 :(得分:17)

将其编写为VB6插件可能更容易,它允许您枚举所有模块/过程并插入适合的代码。
或者,使用免费的MZTools,可以自动为各个过程或新过程添加标题。

答案 1 :(得分:1)

对于像这样的项目,您可能想要比正则表达式更强大的东西。我不知道任何OSS VB6解析器实现,但我建议使用适当的工具。如果要概括在编译时注入代码的方法,此活动有时称为Aspect Oriented Programming或Mixins。

我将花点时间插入我自己的工具meta#,它允许您为这些类型的场景构建匹配语法的模式,但您也可以使用其中许多其他工具,如Lexx / Yacc,Flexx /野牛或ANTLR。

但即使你没有特别使用我的,这也是我将采取的解决问题的一般策略:

  1. 创建代码转换(预编译)构建步骤
  2. 将文件解析为对象模型
  3. 将新对象插入此模型中,表示日志记录调用
  4. 基于该对象模型生成新的代码文件
  5. 仅编译生成的代码。
  6. 生成的代码是构建工件,永远不会编辑或添加到源代码控制中。
  7. 每次构建时都运行此转换步骤。

答案 2 :(得分:1)

我们的DMS Software Reengineering Toolkit及其Visual Basic front end可用于执行此操作。

DMS使用前端解析源文本以抽象语法树,然后将任意分析/转换应用于这些树。可以使用source-to-source program transformation完成许多转换更改,其中使用“如果您看到语法,使用语法替换 语法”来重写代码作为定义抽象占位符的一种方式。这使得使用熟悉的语法在代码上编写转换相对容易。这概括了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匹配的参数 header as ... n:N .... tostring是一个自定义元函数(用meta parens()调用) 将树节点参数转换为文本字符串的树节点。

OP可能需要比处理其他案件更多的规则;也许他想要伐木 GOSUB调用,和/或在日志调用中捕获函数参数。

其他答案建议获取解析器生成器,以及定义VB6以启用解析。重要的是要理解正确地使用VB6语法非常困难;语言记录很少,并且有关于空格,行内语句和跨行边界语句的一些非常奇怪的规则。如果你没有做到这一点,你根本无法解析数百个文件。我们必须定义自己的语法(正如我们为DMS所做的那样) many other languages)。

您可以使用程序转换了解有关代码检测/日志记录的更多信息 here