haskell parsec

haskell - Parsec contra Yacc/Bison/Antlr: ¿Por qué y cuándo usar Parsec?



(3)

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

¿Qué tecnología de análisis Haskell es más agradable de usar y por qué?

En Haskell, la competencia es entre Parsec (y otros combinadores de analizadores) y el generador de analizadores Happy. 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.

La respuesta de Ira Baxter a la pregunta vinculada fue acertada sobre un analizador sintáctico que lo lleva simplemente al punto de apoyo de los Himalayas para escribir un traductor , pero ser parte de un traductor es solo uno de los usos de un analizador sintáctico, por lo que todavía hay muchos dominios donde sistemas bastante minimalistas como ANTLR, Happy y Parsec son satisfactorios.

Soy nuevo en Haskell y Parsec. Después de leer el Capítulo 16 Usando Parsec de Real World Haskell , una pregunta apareció en mi mente: ¿Por qué y cuándo Parsec es mejor que otros generadores de analizadores sintácticos como Yacc / Bison / Antlr?

Tengo entendido 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 podría ir un poco más allá de la tecnología, y entrar 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 esta, pero no fue respondida satisfactoriamente allí.


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.


Una de las principales diferencias entre las herramientas que enumeró, es que ANTLR, Bison y sus amigos son generadores de analizadores, mientras que Parsec es una biblioteca de combinación de analizadores.

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 combinador de analizadores OTOH no hace más que combinar 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, puede combinar un analizador d y un analizador sintáctico 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. Los combinadores de analizadores OTOH solo admiten esto y nada más.