parsing haskell parser-generator parsec happy

parsing - ¿Cuál es la ventaja de utilizar un generador de analizador como "feliz" en lugar de usar "combinadores de analizador"?



haskell parser-generator (5)

En mi opinión, Parsec oculta la mayoría de los desagradables detalles gramaticales y te permite escribir tus analizadores de forma más intuitiva. Si quieres aprender estas cosas en primer lugar ve con algún generador de analizadores como Happy (o incluso intenta implementar uno tú mismo).

Para aprender a escribir y analizar una gramática libre de contexto, quiero elegir una herramienta. Para Haskell, hay dos grandes opciones: Happy, que genera un analizador a partir de una descripción gramatical y * Parsec, que le permite codificar directamente un analizador en Haskell.

¿Cuáles son las (des) ventajas de cualquiera de los enfoques?


Esta es la decisión tradicional: ¿uso lex / yacc (feliz) o escribo mi propio analizador (en su mayoría de descendencia recursiva), solo que la biblioteca parsec es como una DSL para hacerlo bien?

Si uno tiene experiencia con el enfoque yacc / lex, usar happy será una curva de aprendizaje más pequeña.


Estoy acostumbrado a la biblioteca del combinador analizador uu-parsinglib de la universidad de utrecht. Uno puede tener correcciones de errores y permutaciones gratis, y también las cosas que tiene parsec. También me gusta porque mi gramática implementada parece una gramática EBNF, sin mucho material monádico, y es fácil de leer.


Los combinadores de analizadores ingenuos no permiten la recursión a la izquierda en las reglas gramaticales y no he encontrado una biblioteca que sí lo haga.

Happy permite un BNF completo en la especificación del idioma, y ​​algunos empleados útiles como las reglas de prioridad. Entonces, para casos complicados, los generadores Happy y Parser en general son mucho mejores. Sin embargo, en el caso de lenguajes simples y estúpidos con gramáticas analizables LL (k), usaría una biblioteca de combinador de analizadores como más amigable para el desarrollador.


DSL externo vs interno

El formato de especificación del analizador para Happy es un DSL externo, mientras que con Parsec tienes todo el poder de Haskell disponible cuando defines tus analizadores. Esto significa que puede, por ejemplo, escribir funciones para generar analizadores sintácticos, usar Template Haskell, etc.

Reglas de precedencia

Con Happy, puede usar precedences para simplificar su gramática, mientras que con Parsec tiene que anidar las reglas de gramática correctamente. Por lo tanto, cambiar la precedencia de un operador es mucho más tedioso en Parsec.

Comprobación estática

Happy te advertirá sobre las ambigüedades en tu gramática en el momento de la compilación. (Aunque no es muy bueno para decirte dónde están.) Con Parsec, no obtienes ninguna advertencia hasta que tu analizador falla en tiempo de ejecución.