2010-08-29 14 views
8

Estoy trabajando en un nuevo lenguaje de programación, pero siempre me ha extrañado el hecho de que todos estén usando yaxx/lex para analizar el código, pero yo no.yacc/lex o codificación manual?

Mi compilador (que ya está funcionando) está codificado a mano en C++/STL, y no puedo decir que sea complejo o requirió demasiado tiempo. Tiene algún tipo de lexer y analizador, pero no se autogeneran.

Anteriormente, escribí un compilador C (no completo) de la misma manera - fue capaz de compilar el programa en 1 pasada, con todas estas referencias que resuelven el preprocesamiento & - esto es definitivamente imposible con yacc/lex.

No puedo convencerme de desechar todo esto, y comenzar a bucear en yaxx/lex, lo que podría requerir un gran esfuerzo de implementación y posiblemente podría introducir algunas limitaciones gramaticales.

¿Hay algo que echo de menos cuando no uso yacc/lex? ¿Hago algo malo?

Respuesta

3

Yacc es inflexible en algunos aspectos:

  • buena gestión de errores es duro (básicamente, su algoritmo sólo se define para analizar una cadena correcta correctamente, de lo contrario, todas las apuestas están apagadas, lo que es una de las razones que GCC se trasladó a un analizador escrito a mano)
  • dependencia del contexto es difícil de expresar, mientras que con un analizador descendente recursivo escrito a mano que simplemente puede añadir un parámetro a las funciones

Además, he notado ese código de objeto lex/yacc es a menudo es más grande que un analizador de descenso recursivo escrito a mano (el código fuente tiende a ser al revés).

No he usado ANTLR, así que no puedo decir si eso es mejor en estos puntos.

1

Tal vez se está perdiendo ANTLR, lo cual es bueno para los idiomas que se pueden definir con una estrategia de análisis recursivo-descendente.

Existen algunas ventajas con el uso de Yacc/Lex, pero no es obligatorio usarlas. Hay algunas desventajas de usar Yacc/Lex también, pero las ventajas generalmente superan las desventajas. En particular, a menudo es más fácil mantener una gramática guiada por Yacc que una codificada a mano, y se beneficia de la automatización que proporciona Yacc.

Sin embargo, escribir su propio analizador desde cero no es una mala cosa que hacer. Puede hacer que sea más difícil de mantener en el futuro, pero también puede hacerlo más fácil.

6

Las principales ventajas de utilizar cualquier tipo de generador de lexer/analizador es que le ofrece mucha más flexibilidad si su lenguaje evoluciona. En un lexer/analizador codificado a mano (¡especialmente si ha mezclado mucha funcionalidad en una sola pasada!), Los cambios en el lenguaje se vuelven desagradables con bastante rapidez, mientras que con un generador de analizadores realiza el cambio, vuelva a ejecutar el generador, y seguir con tu vida. Ciertamente, no hay limitaciones técnicas inherentes a escribir todo a mano siempre, pero creo que la capacidad de evolución y mantenimiento de la automatización de las partes aburridas lo vale!

+2

El diseño bueno y modular (por ejemplo, el tokenizador y el analizador léxico deben estar completamente separados) puede hacer que esto no suponga un problema. Aún importante. – delnan

3

La otra gran ventaja del uso de generadores es que están garantizados para procesar exactamente y solo el idioma especificado en la gramática. No se puede decir eso de ningún código escrito a mano. También se garantiza que las variantes LR/LALR serán O (N), lo que tampoco se puede afirmar con ninguna codificación manual, al menos no sin mucho esfuerzo al construir la prueba.

He escrito ambos y viví con ambos y nunca volvería a codificar manualmente. Solo lo hice porque no tenía yacc en la plataforma en ese momento.

+0

Bueno, no necesito una prueba matemática para saber que mi código es rápido; por lo general, es obvio que está en algún lugar en O (N) u O (N * LogN). – BarsMonster

+2

No dije nada sobre 'rápido'. Estoy hablando de complejidad algorítmica y necesitas una prueba para eso. – EJP

+0

Bueno, cuando escribo código, siempre sé que es complejo. Si la herramienta es escribir código para mí, entonces definitivamente necesitaría una prueba. – BarsMonster

0

Sin duda, depende de la complejidad de su gramática de idioma. Una gramática fácil significa que hay una implementación fácil y puede hacerlo usted mismo.

Eche un vistazo quizás al peor ejemplo posible: C++ :) (¿Alguien sabe otro idioma, además de los lenguajes naturales, que son más difíciles de analizar correctamente?) Incluso con herramientas como Antlr, es bastante difícil hazlo bien, aunque es manejable. Por el cual, por otro lado, aunque sea mucho más difícil, parece que algunos de los mejores analizadores de C++, p. GCC y LLVM, también son en su mayoría manuscritos.

Si no necesita demasiada flexibilidad y su lenguaje no es demasiado trivial, seguramente ahorrará algo de trabajo/tiempo al usar Antlr.

+0

La complejidad de mi lenguaje es solo un poco menor que C++. – BarsMonster

+1

Classic Fortran es bastante difícil de analizar: la asignación "' DO10I = 12.43' "y el bucle DO" 'DO10I = 12,43'" no se pueden dividir en palabras con precisión hasta llegar a la coma frente al punto. (El primero implica una variable de coma flotante 'DO10I', el segundo implica una variable entera' I' y una etiqueta '10':' DO 10 I = 12, 43'.) ¡Esto tiende a hacerlo bastante difícil! –