2011-02-20 12 views
38

Soy nuevo en Haskell y Parsec. Después de leer Chapter 16 Using Parsec of Real World Haskell, una pregunta apareció en mi mente: ¿Por qué y cuándo Parsec es mejor que otros generadores de analizadores como Yacc/Bison/Antlr?Parsec contra Yacc/Bison/Antlr: ¿Por qué y cuándo usar Parsec?

Mi comprensión es que Parsec crea una buena DSL de analizadores de escritura y Haskell lo hace muy fácil y expresivo. Pero el análisis sintáctico es una tecnología estándar/popular que merece su propio lenguaje, que genera múltiples idiomas de destino. Entonces, ¿cuándo usaremos Parsec en lugar de, digamos, generar código Haskell de Bison/Antlr?

Esta pregunta puede ir un poco más allá de la tecnología, y en el ámbito de la práctica de la industria. Al escribir un analizador sintáctico desde cero, ¿cuál es el beneficio de elegir Haskell/Parsec en comparación con Bison/Antlr o algo similar?

Por cierto: mi pregunta es bastante similar a this one pero no fue respondida satisfactoriamente allí.

+8

"Pero el análisis sintáctico es una tecnología estándar/popular que merece su propio lenguaje, que genera múltiples idiomas de destino". Me gustaría saber por qué, no sé lo suficiente sobre el tema para estar realmente de acuerdo o en desacuerdo, pero ciertamente no me parece una afirmación evidente. –

Respuesta

9

Es posible que desee ver esta pregunta, así como la vinculada en su pregunta.

Which Haskell parsing technology is most pleasant to use, and why?

En Haskell la competencia es entre Parsec (y otros combinadores de analizadores sintácticos) y el generador de análisis feliz. Elegiría Happy si ya tenía una gramática LR para trabajar: los combinadores de analizadores toman gramáticas en forma LL y la traducción de LR a LL requiere un poco de esfuerzo y un analizador combinador generalmente será significativamente más lento. Si no tengo una gramática, usaré Parsec, es más flexible (poderosa) que Happy y es más divertido trabajar "en Haskell" que generar código con Happy y Alex. Si usa Happy para analizar, casi siempre necesitará usar Alex para leer.

Para la práctica de la industria, sería extraño decidir usar Haskell solo para obtener Parsec. Para el análisis sintáctico, la mayor parte de la cosecha actual de idiomas tendrá al menos un generador de analizador sintáctico y probablemente algo más flexible como un puerto de Parsec o un sistema PEG.

respuesta de Ira Baxter a la cuestión vinculada estaba en el lugar alrededor de un analizador de conseguir que meramente al pie del Himalaya para escribir un Traductor, pero al ser parte de un traductor es sólo uno de los usos de los analizadores, entonces todavía hay muchos dominios donde los sistemas bastante minimalistas como ANTLR, Happy y Parsec son satisfactorios.

6

Siguiendo con la respuesta de stephen, creo que una de las alternativas más comunes a Parsec, si quieres seguir con los combinadores de analizadores, es attoparsec. La principal diferencia es que attoparsec fue escrito con un sesgo más rápido hacia la velocidad, y hace concesiones en consecuencia. Por ejemplo, Parsec hace cierta contabilidad para tratar de devolver mensajes de error útiles si falla un análisis sintáctico, que attoparsec no hace en la misma medida. Además, creo que attoparsec está especializado en una fuente de entrada/tipo de token, mientras que Parsec abstrae del tipo de entrada para que pueda analizar las secuencias de tipo String, ByteString, Text, etc. sin problemas.

+1

El analizador de attoparsec es también un funtor aplicativo, pero no es una mónada. esto significa usar el conjunto de combinadores aplicativos (<*><|><$>) en lugar de la notación do o las funciones de mónada. –

+5

@ John F. Miller No estoy seguro de si hubo alguna vez en la que el analizador de Attoparsec no fuera una mónada, pero ciertamente no es el caso ahora, y dudo mucho que haya sido el caso. Sin embargo, tanto Parsec como Attoparsec recomiendan utilizar las mónadas de Applicative cuando sea posible ... De hecho, acabo de verificar y la versión más antigua de Hackage, de 2008, 5 años antes de su publicación, la tenía como una Mónada. Entonces esa es simplemente información incorrecta. – alternative

53

Una de las principales diferencias entre las herramientas que enumeró, es que antlr, bisonte y sus amigos están analizador generadores, mientras que Parsec es un analizador biblioteca combinador.

Un generador de analizador lee en una descripción de una gramática y escupe un analizador. En general, no es posible combinar las gramáticas existentes en una nueva gramática, y ciertamente no es posible combinar dos analizadores generados existentes en un nuevo analizador.

Un analizador de analizadores OTOH no hace nada pero combina los analizadores existentes en nuevos analizadores. Por lo general, una biblioteca de combinador de analizador se envía con un par de analizadores integrados triviales que pueden analizar la cadena vacía o un solo carácter, y se envía con un conjunto de combinadores que toman 1 o más analizadores y devuelven uno nuevo que, por ejemplo , analiza la secuencia de los analizadores originales (por ejemplo, se puede combinar un analizador d y un analizador o para formar un analizador do), la alternancia de los analizadores originales (por ejemplo, un analizador 0 y un analizador 1 a un analizador 0|1) o analiza el análisis original varias veces (repetición).

Lo que esto significa es que podría, por ejemplo, tomar un analizador existente para Java y un analizador existente para HTML y combinarlos en un analizador para JSP.

La mayoría de los generadores de analizadores no son compatibles con esto, o solo lo admiten de forma limitada. Parser combinadores OTOH solo admiten esto y nada más.

+2

s/combinator/combinator library. Un combinador es, clásicamente hablando, una función que toma funciones y devuelve funciones. Una biblioteca combinadora es una biblioteca construida a partir, en su mayor parte, de funciones combinatorias. – sclv

+3

@sclv: Gracias. Creo que arreglé todas las instancias en las que realmente estaba hablando sobre la biblioteca como un todo y dejé aquellos casos en los que realmente estaba hablando de combinators individuales. Realmente aprecio su comentario, ya que generalmente soy un riguroso con la terminología correcta. Curiosamente, la mayoría de los puertos Ruby y Smalltalk de Parsec combinan objetos analizadores, no funciones de analizador sintáctico, aunque por supuesto una función es solo un objeto con un solo método y un objeto es simplemente una (función) función (es) parcialmente aplicada a 'esto' :-) –

Cuestiones relacionadas