Tengo un corpus de documentos basados en token-index que ofrece un método de consulta. El usuario ingresa manualmente (!) Una cadena de consulta que necesita ser analizada y evaluada. El corpus debería devolver una lista de todos los documentos que coincidan con la cadena de consulta dada. El lenguaje de consulta presenta los operadores booleanos simples AND, NOT y OR que también se pueden priorizar por paréntesis. Después de algunas investigaciones, ya utilicé ANTLR para analizar una cadena de consulta dada en un árbol de sintaxis.¿Cómo evaluar y procesar un árbol de sintaxis de cadena simple en C#?
Por ejemplo: La consulta
"Bill OR (John AND Jim) OR (NOT Simon AND Mike)"
se traduce en el siguiente árbol de sintaxis:
EDIT: Por favor, véase el gráfico correcto en Bart Kiers post (copiado aquí):
Todos los nodos en el árbol son cadenas simples y cada nodo conoce su padre y niños pero no sus hermanos. Como puede ver, la gramática ANTLR ya dictaba el orden en el que las operaciones deben ejecutarse: las que están en la parte inferior del árbol son lo primero.
Entonces, lo que probablemente deba hacer es recusivamente (?) Evaluar todos los operandos en el árbol. En general, puedo hacer una búsqueda simple en mi corpus utilizando un método Get (término de cadena) para cada hoja en el árbol (como "Bill" o "John"). Get() devuelve una lista de documentos que contienen el término en la hoja. También puedo evaluar el padre de cada hoja para reconocer un posible operador NOT que luego llevaría a una lista de resultados de documentos que NO contienen el término en la hoja (usando el método Not() en lugar de Get()).
El AND y OR operador debería transformarse en llamadas a métodos que requieren dos parámetros:
- y debe llamar a un método Intersect (lista1, lista2) que devuelve una lista de documentos que se encuentran en Lista1 y en lista2 .
- O debe llamar a un método Union (list1, list2) que devuelve una lista de documentos que están en list1 O en list2.
Los parámetros list1 y list2 contienen los documentos que recibí antes de usar Get() o Not().
Mi pregunta es: ¿cómo puedo, semánticamente y sintácticamente en C#, evaluar todos los términos de búsqueda necesarios y usarlos para llamar a los métodos correctos del operador en el orden correcto? Intuitivamente suena como recursividad, pero de alguna manera no puedo imaginarlo, especialmente porque no todos los métodos que necesitan ser llamados tienen la misma cantidad de parámetros. ¿O hay otras maneras completamente diferentes de lograr esto?
Completamente fuera de tema, pero ¿qué herramienta usaste para hacer ese gráfico? – Cameron
¿Debería "NO Simon" devolver un conjunto de todos menos Simon, o una expresión que evalúe falso para Simon, o qué ...? –
@Cameron: Microsoft PowerPoint 2010 con formato rápido integrado :) – Shackles