2009-12-03 15 views
8

¿Cuál es la mejor manera de crear un analizador en C++ a partir de un archivo con gramática?C++ create an parser

+5

¿Qué formato tiene el 'archivo con gramática'? –

+1

http://stackoverflow.com/questions/1669/learning-to-write-a-compiler es la pregunta canónica sobre cómo en compiladores e intérpretes por aquí. Muchos buenos enlaces allí. Para un enfoque recursivo decente construido a mano, mira el tutorial de Crenshaw. – dmckee

Respuesta

17

También puede ser que desee echar un vistazo a estos enlaces:

+0

Yo en segundo lugar. La documentación de Boost es realmente útil. – anno

+1

Sugeriría no utilizar 'boost :: spirit' si planea un compilador de cualquier tamaño decente: los tiempos de compilación para los analizadores construidos con' boost :: spirit' tienden a ser muy grandes, lo que hace que incluso los cambios muy pequeños sean un PITA (porque todo se hace con plantillas) –

8

Hay flex y bison. Lex & primos Yacc que tienen en cuenta la existencia de C++.

3

¿Has mirado en Lex and Yacc? Para citar de la sección 5 del documento vinculado:

Mi forma preferida para hacer un analizador de C++ es tener Lex generar un archivo de C plano , y dejar que YACC generar código C++ . Cuando luego vincula su aplicación , puede encontrarse con algunos problemas porque el código C++ por predeterminado no podrá encontrar las funciones C , a menos que le haya dicho que esas funciones son externas "C".

+0

Lex y Yacc han sido superados por Flex y Bison. –

2

La mejor manera de crear un analizador es usar lex y yacc.

+3

Nadie puede responder la pregunta sobre * mejor *, pero se acercó mucho: los primos lex y yacc flex y bison tienen en cuenta C++. –

+0

Estaba asumiendo que la pregunta era sobre cómo escribir un analizador a mano en C++. – Dima

2

He usado bison, encontraron los ejemplos justo para mi nivel. Pudo crear una calculadora simple con ella, por supuesto que puede hacer mucho más.

La calculadora tomó 1 + 2 * 3, por ejemplo, y construyeron un árbol sintáctico. La documentación no describía cómo construir el árbol, sin embargo, y eso me llevó un poco de tiempo para entrenar.

Si fuera otra vez me vería en 'antlr', ya que se veía bien y bien apoyada.

Martin.

9

Depende mucho de la gramática. Tiendo a me gusta los analizadores de descenso recursivos, que normalmente se escriben a mano (aunque es posible generar uno a partir de una descripción de la gramática).

Si va a utilizar un generador de análisis, en realidad hay dos buenas opciones: byacc y Antlr. Si quieres algo que sea (razonablemente) compatible con yacc, Byacc es (de lejos) tu mejor opción. Si estás empezando desde el principio, sin código ni experiencia que favorezcan el uso de algo compatible con yacc, entonces Antlr es casi seguro tu mejor opción.

Como se ha mencionado, también voy a hablar un poco acerca de bisonte. Evitaría a Bison como la plaga que es. El consejo de Brooks de "planear tirar uno" se aplica aquí. Robert Corbett (el autor de Byacc) escribió Bison como su primer intento en un generador de analizadores sintácticos. Desafortunadamente, se lo dio a GNU en lugar de tirarlo. En un caso clásico de mercadotecnia que supera la excelencia técnica, Bison es ampliamente utilizado (e incluso recomendado, por aquellos que no conocen mejor) mientras que Byacc permanece relativamente oscuro.

Editar: Odio hacerlo, pero como también se ha mencionado, también comentaré sobre Boost.spirit. Si bien este puede ser el mejor ejemplo de programación de metadatos de plantillas, tiene un par de problemas que me llevan a recomendar que no intente ponerlo en serio.

  1. Los tiempos de compilación pueden ser insoportables: 10 minutos es común, y una gramática más grande/más compleja puede llevar incluso más tiempo (suponiendo que no interrumpa el compilador).
  2. Si comete un error, puede y con frecuencia producirá mensajes de error terriblemente largos que son prácticamente imposibles de descifrar. Los mensajes de error del código de plantilla son notoriamente malos de todos modos, y Spirit enfatiza el sistema más que cualquier otra cosa.

Créame: el hecho de que pueda escribir algo así como Spirit está justo en el límite entre impresionante y sorprendente, pero igual solo lo usaría si estuviera seguro de que la gramática con la que estaba tratando era (y siempre permanecería) bastante pequeño y simple.