我有一个代表C#代码的数据结构:
class Namespace:
string Name;
List<Class> Classes;
class Class:
string Name;
List<Property> Properties;
List<Method> Methods;
List<Method> Constructors;
List<Field> Fields;
List<Class> InnerClasses;
Class Parent;
List<Interface> Implements;
...我正在使用简单的词法分析器/解析器组合构建。我需要遍历树并应用大量规则(超过3000)。当遇到树中不同(且非常复杂)的模式时,规则会运行。例如,有一个规则在类只在同一个程序集中实现接口时运行。
我原始的天真实现迭代每个规则,然后每个规则遍历树寻找其特定模式。当然,这需要相当多的时间,即使只有少量的源代码。
我认为这可以比作防病毒软件的工作方式,识别大量二进制代码上的复杂模式。
您如何建议实施此类软件?
美国东部时间:刚补充说:不,我没有重新实施FxCop。
由于
答案 0 :(得分:1)
您可以尝试汇总3000条规则。一些3000,我猜想假设3000的另一个成员。说规则12检查'一个类实现一个接口'。规则85可能是 '一个类只在同一个程序集中实现接口'。如果规则12失败,则根本不需要运行规则85.
这种方法(alpha-beta修剪)要么需要重构算法以搜索类树,同时查找所有规则模式。或者存储以前规则传递已识别出当前规则传递无关的记录。
评论:我有一个nub级帐户,所以我无法直接评论。你能举一个可能还有2个规则的例子吗?我目前认为你的算法是0(n * n)(从大0表示后复制)
O(n * log(n)):一种执行某种分而治之策略的算法。伤害大n。典型示例:合并排序
O(n * n):某种嵌套循环。即使是小n也会受伤。与天真矩阵计算相同。如果可以的话,你想避免使用这种算法。
答案 1 :(得分:0)
我会考虑为模式/上下文创建某种表示,然后创建从模式到操作集的哈希映射。在不了解更多需求的情况下,很难更具体,但作为示例,字符串"Namespace/Class"
可能是依赖于知道命名空间及其包含的单个类的一组操作的关键,{ {1}}可以是处理单个类及其实现的单个接口的操作集的关键字等。
树遍历算法可以跟踪它自己的上下文(父节点,当前节点等),根据它在树中的位置形成一个键,检索该键的动作集,然后触发所有这些动作,给每个参数结构提供了与键模式相对应的实际节点。
这等于创建一个特殊用途的规则引擎,它处理“如果我有一个类"Class/Interface"
”的形式规则,它实现了一个接口C
,然后执行... { {1}}和I
“。
答案 2 :(得分:0)
@Jimmy McNulty
这是一个很好的方法。 Alpha-beta修剪你说它被称为?它正在重新安排规则,以便如果一个失败则排除其他规则。我对吗?我要调查一下。
以下是其他规则的一些示例:
我很想知道任何其他技术可以让我更快/更聪明地执行这种逻辑。
由于