Pregunta

Tengo una estructura de datos que representa el código C # como este:

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;

... que estoy construyendo usando una combinación simple lexer / parser. Necesito atravesar el árbol y aplicar un gran conjunto de reglas (más de 3000). Las reglas se ejecutan cuando se encuentran patrones diferentes (y bastante complejos) en el árbol. Por ejemplo, hay una regla que se ejecuta cuando una clase solo implementa interfaces en el mismo ensamblaje.

Mi implementación original de na & # 239; ite itera sobre cada regla y luego cada regla atraviesa el árbol buscando su patrón específico. Por supuesto, esto lleva bastante tiempo, incluso con una pequeña cantidad de código fuente.

Supongo que esto podría compararse con el funcionamiento del software antivirus, reconociendo patrones complejos en un gran cuerpo de código binario.

¿Cómo sugeriría que se implemente este tipo de software?

EDT: solo me gusta agregar: No, no volveré a implementar FxCop.

Gracias

¿Fue útil?

Solución

Podría intentar agregar sus 3000 reglas. Supongo que algunos de los 3000 suponen otro miembro del 3000. Digamos que la regla 12 verifica "una clase implementa una interfaz". La regla 85 podría ser 'una clase solo implementa interfaces en el mismo ensamblado'. Si la regla 12 falla, no es necesario ejecutar la regla 85 en absoluto.

Este enfoque (poda alfa-beta) necesitaría reestructurar su algoritmo para buscar en el árbol de clases, buscando todos los patrones de reglas al mismo tiempo. O para guardar un registro de que un pase de regla anterior ha identificado que el pase de regla actual es irrelevante.

COMENTARIO: Tengo una cuenta de nivel de nube, así que no puedo comentar directamente. ¿Puedes dar un ejemplo de quizás 2 reglas más? Actualmente estoy pensando que su algoritmo es 0 (n * n) (siguiente copiado de una gran publicación de notación 0)

O (n * log (n)): un algoritmo que hace algún tipo de estrategia de dividir y conquistar. Duele para grandes n. Ejemplo típico: ordenar por fusión

O (n * n): un bucle anidado de algún tipo. Duele incluso con pequeños n. Común con cálculos ingenuos de matriz. Desea evitar este tipo de algoritmo si puede.

Otros consejos

Consideraría crear algún tipo de representación para patrón / contexto, luego crear un mapa hash de patrón a conjunto de acciones. Sin conocer más de sus requisitos, es difícil ser más específico, pero como ejemplo, la cadena " Namespace / Class " podría ser una clave para un conjunto de acciones que dependen de conocer el espacio de nombres y una sola clase que contiene, " Class / Interface " podría ser una clave para el conjunto de acciones que se ocupan de una sola clase y una única interfaz que implementa, etc.

El algoritmo de recorrido del árbol podría realizar un seguimiento de su propio contexto (nodo principal, nodo actual, etc.), formar una clave en función de dónde se encuentra en el árbol, recuperar el conjunto de acciones para esa clave y luego disparar todo esas acciones, dando a cada uno una estructura de argumento que proporcionó los nodos reales correspondientes al patrón clave.

Esto equivale a crear un motor de reglas de propósito especial que se ocupa de las reglas de la forma " Si tengo una clase C , e implementa una interfaz I , luego haga ... con C y I " ;.

@Jimmy McNulty

Ese es un gran enfoque. Poda alfa-beta que dices que se llama? Se reorganizan las reglas para que, si una falla, excluya a otras. Estoy en lo cierto? Voy a investigar eso.

Estos son algunos ejemplos de otras reglas:

  • La clase es final y no implementa / extiende una clase fuera del ensamblaje.
  • El método es virtual pero la clase es privada o interna.
  • La clase o método tiene un atributo específico.
  • El parámetro
  • Método se conoce en tiempo de compilación.

Me encantaría saber sobre cualquier otra técnica que me permita ejecutar este tipo de lógica más rápido / más inteligente.

Gracias

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top