2009-05-17 16 views
6

¿Hay equivalentes de expresiones regulares para buscar y modificar estructuras de árbol? Los mini-idiomas concisos (como perl regex) son lo que estoy buscando.Regex para estructuras de árboles?

Aquí hay un ejemplo que podría aclarar lo que estoy buscando.

<root> 
    <node name="1"> 
    subtrees .... 
    </node> 
    <node name="2"> 
    <node name="2.1"> 
    data 
    </node> 
    other subtrees... 
    </node> 
</root> 

Una operación que sería posible en el árbol de arriba es "mover subárbol en el nodo 2.1 en el subárbol en el nodo 1." El resultado de la operación podría ser algo como ..

<root> 
    <node name="1"> 
    subtrees .... 
    <node name="2.1"> 
    data 
    </node> 
    </node> 
    <node name="2"> 
    other subtrees... 
    </node> 
</root> 

Buscar y reemplazar operaciones como encontrar todos los nodos con al menos 2 hijos, encontrar todos los nodos cuyos datos comienza con "a" y sustituirla por "b" si el los subárboles tienen al menos 2 otros hermanos, etc. deben ser compatibles.

Para las cadenas, donde la única dimensión se encuentra a lo largo de la cadena, podemos hacer muchas de las operaciones anteriores (o sus equivalentes 1D) usando expresiones regulares. Me pregunto si hay equivalentes para los árboles. (En lugar de una sola expresión regular, es posible que deba escribir un conjunto de reglas de transformación, pero eso está bien).

Me gustaría saber si hay algún mini lenguaje simple (no regex per.se, pero algo que es tan accesible como regex a través de bibliotecas, etc.). para realizar estas operaciones? Preferiblemente, como una biblioteca de Python.

+0

Pensando en cómo podría ser la sintaxis de esa cosa ... :) –

+0

Mmh, ¿puede ser más explícito sobre lo que tiene y qué debe hacer la expresión regular? – akappa

+0

Esto tiene que ser más específico: ¿está analizando XML o qué? –

Respuesta

1

Navegar a través de un árbol de búsqueda binario requiere estado (¿en qué nodo estoy?) Y comparaciones (¿ese valor es menor o mayor que eso?), Cosas que un autómata de estado finito no puede hacer.

Claro, puede buscar el nodo con un valor dado, pero ¿cómo podría, por ejemplo, eliminar un nodo que no sea una hoja si no conoce su elemento primario?

E incluso si conoce al padre a través de la información proporcionada por el nodo, ¿cómo determina el mínimo del subárbol izquierdo, lo elimina y lo coloca en el nodo?

Creo que le está pidiendo demasiado a la FSA.

+0

El autómata podría funcionar si cada nodo contiene los datos relevantes (y los estados relacionados con eso) para todos los datos que pueden coincidir, como ancestry y parent-state? –

+0

- continuación - Entonces las subexpresiones relacionadas con otros nodos pueden invocar un motor secundario para devolver un estado o un booleano asignados a una transición. –

+0

Pero, al eliminarlo, debe "actualizar" los datos relevantes para cada nodo ... – akappa

5

No conozco una languga de uso general que pueda hacer eso, pero me parece que usted está buscando algo como XPath.

+0

He consultado XPath. Parece prometedor, pero no parece manejar expresiones sobre conjuntos de nodos (por ejemplo, encontrar todos los nodos que tienen al menos 2 hermanos). Tiene una funcionalidad limitada. – JSN

4

Hay TXL para la reescritura de árboles basada en patrones.

árbol de reescritura con los patrones también se realiza con kits de herramientas del analizador como ANTLR

La generación de código de abajo hacia arriba con la reescritura de árbol, Google fresas o BURG.

+0

TXL parece muy prometedor, sin embargo, tanto ANTLR como TXL suponen una gramática libre de contexto, que es importante cuando también necesita realizar un análisis sintáctico. Sin embargo, a los efectos de la transformación y el comportamiento de tipo regex en los árboles, debe ser explícitamente dependiente del contexto. Vea mi aclaración de la pregunta anterior para algunos casos de uso que me gustaría (p. Ej .: búsqueda con condiciones sobre hermanos). – JSN

1

This artículo da algunos consejos sabrosos sobre las expresiones regulares recursivas de Perl, pero sinceramente es raro ver una estructura de árbol abordada de esta manera.

Más típicamente, uno escribiría un analizador de estilo de máquina de estado, que podría usar expresiones regulares para analizar cada nodo en particular en el árbol.

Expat es probablemente un buen ejemplo a tener en cuenta.

1

Coincidencia de patrones, proporcionada por idiomas como Scala, F #, Erlang y Haskell (estoy seguro de que hay más) está diseñada para manipular estructuras de datos de forma sucinta, especialmente cuando se usa con recursividad.

here es una vista de muy alto nivel de lo que Pattren Match puede hacer en Scala. Los ejemplos mostrados realmente no hacen justicia de coincidencia de patrones.

Wikipedia tiene un par de referencias a la coincidencia de patrones, también. Here y here.

1

Estoy algo sorprendido de que XSLT no haya surgido como una respuesta. Por supuesto, no creo que sea un lenguaje particularmente elegante, y la mayoría de las soluciones existentes tienden a favorecer los enfoques de procedimiento en lugar de la coincidencia de patrones, y se ha logrado una mala reputación por ser aplicado ciegamente solo porque XML se aplica a XML, pero se ajusta a la ley. Lástima que su representación canónica es tan detallada, aunque ...

+0

En este momento, XSLT parece ser lo más cercano a lo que quiero, pero escribir consultas sensibles al contexto parece intrincado, mi pregunta era encontrar algo mejor que xslt. – JSN

Cuestiones relacionadas