2009-04-29 11 views
6

Me he estado preguntando durante mucho tiempo por qué no parece haber ningún analizador para, por ejemplo, BNF, que se comporte como expresiones regulares en varias bibliotecas.¿Por qué los analizadores en línea parecen detenerse en las expresiones regulares?

Claro, hay cosas como ANTLR, Yacc y muchos otros que generar código el cual, a su vez, puede analizar una CFG, pero no parece ser una biblioteca que puede hacerlo sin el paso intermedio.

Estoy interesado en escribir un Packrat parser, para arrancar todos los paréntesis anidados-caprichos asociados con expresiones regulares (y, tal vez más aún, por el deporte de hacerlo), pero de alguna manera tengo la sensación de que soy simplemente caminando hacia otro problema de detención, como una clase de pantanos.

¿Existe una limitación técnica/teórica para estos analizadores, o simplemente me falta algo?

Respuesta

4

Creo que es algo más cultural. El uso de gramáticas libres de contexto se limita principalmente a los compiladores, que generalmente tienen un código asociado con cada regla de producción. En algunos idiomas, es más fácil generar código que simular devoluciones de llamada. En otros, verá bibliotecas de analizadores: combinadores de analizadores en Haskell, por ejemplo. Por otro lado, las expresiones regulares tienen un amplio uso en herramientas como grep, donde no es conveniente ejecutar el compilador de C cada vez que el usuario da una nueva expresión regular.

0

Porque las gramáticas completas sin contexto son lo suficientemente confusas como lo son, sin alguna sintaxis crípticamente densa e incomprensible para hacerlas aún más confusas.

Es difícil saber lo que está preguntando. ¿Estás tratando de crear algo así como una expresión regular, pero para gramáticas libres de contexto? Me gusta, usando $var =~ /expr = expr + expr/ (en Perl) y teniendo esa coincidencia "1 + 1" o "1 + 1 + 1" o "1 + 1 + 1 + 1 + 1 + ..."? Creo que una de las limitaciones de esto será la sintaxis: tener más de tres reglas hará que tu "expresión gramatical" sea aún más ilegible que cualquier expresión regular de hoy en día.

+0

Parece que está discutiendo la implementación (aunque no especificada), que la capacidad de analizar un CFG en sí mismo. Claro, las expresiones regulares son crípticas para el ojo inexperto. Tal vez, un lenguaje libre de contexto podría ser aún más críptico. Pero ese no era el punto. El punto era, ¿por qué hay solo generadores de código, y no cosas que puedo poner en una función/objeto y obtener bloques de texto combinados, como hago con las expresiones regulares de hoy? –

+0

Normalmente, cuando las personas usan un analizador, buscan hacer mucho más que mirar un texto y ver si coincide con su gramática o no. No es que haya nada de malo en eso, pero la mayoría de los analizadores hacen bastante más. –

+0

Además, la implementación es una limitación técnica con la que tendrá que lidiar en algún momento, y usted preguntó acerca de las limitaciones técnicas/teóricas. –

0

El efecto secundario es lo único que veo que te atrapará. La mayoría de los generadores de analizadores incluyen código incrustado para el procesamiento y necesitaría una evaluación para que funcione.

Una forma de evitarlo sería nombrar acciones y luego realizar una función de "acción" que tome el nombre de la acción a hacer y los argumentos para hacerlo.

0

En teoría, puede hacerlo con Boost Spirit en C++, pero está hecho principalmente para gramáticas estáticas. Creo que la razón por la que esto no es común es porque los CFG no son tan comúnmente utilizados como los regex. Nunca tuve que usar una gramática, excepto para la construcción de compiladores, pero he usado expresiones regulares muchas veces. Los CFG son generalmente mucho más complejos que los regex, por lo que tiene sentido generar código estáticamente con una herramienta como YACC o ANTLR.

+0

Estoy de acuerdo en que el uso de expresiones regulares es más común de lo que parece ser la demanda actual de CFG: s. Pero, dado que he encontrado una gran cantidad de preguntas sobre cómo obtener un conjunto anidado de paréntesis en Stack Overflow solo, estoy seguro de que hay algún uso de CFG: s. Tal vez no se les pide, porque la gente sabe solamente de expresiones regulares? –

+0

IIRC Boost :: Spirit es una implementación pura en tiempo de compilación. No veo ninguna razón para permitir la definición de gramáticas en tiempo de ejecución. – BCS

+0

Boost Spirit se puede usar en tiempo de ejecución: simplemente cambie los tokens al final de la gramática: grammar = gramática >> ch_p ('a'); – Zifre

2

Boost.Spirit parece lo que está buscando.

Si está buscando hacer uno propio, he usado BNFC para mi último proyecto de compilación y proporciona the grammar used in its own implementation. Este podría ser un buen punto de partida ...

+0

Como dije en mi respuesta, Boost.Spirit funciona, pero está destinado principalmente a gramáticas estáticas. Sin embargo, gracias por mencionar BNFC, podría usar eso para mi compilador ahora. ¡Se ve realmente genial! – Zifre

2

No hay una limitación técnica/teórica al acecho en las sombras. No puedo decir por qué no son más populares, pero sé de al menos una biblioteca que proporciona este tipo de análisis "en línea" que usted busca.

SimpleParse es una biblioteca de Python que le permite simplemente pegar su peluda gramática EBNF en su programa y usarla para analizar las cosas de inmediato, no en pasos inmediatos. Lo he usado para varios proyectos en los que quería un lenguaje de entrada personalizado, pero realmente no quería comprometerme con ningún proceso formal de compilación.

Aquí hay un pequeño ejemplo de la parte superior de mi cabeza:

bibliotecas combinator
decl = r""" 
    root := expr 
    expr := term, ("|", term)* 
    term := factor+ 
    factor := ("(" expr ")")/[a-z] 
""" 
parser = Parser(decl) 
success, trees, next = parser.parse("(a(b|def)|c)def") 

el analizador para Haskell y Scala también permiten su expresar su la gramática para su analizador en el mismo trozo de código que lo utiliza. Sin embargo, no se puede, por ejemplo, dejar que el usuario escriba una gramática en tiempo de ejecución (lo que solo podría interesar a las personas que crean software para ayudar a las personas a comprender las gramáticas de todos modos).

+0

¡Gracias por su respuesta informativa! –

Cuestiones relacionadas