2009-11-12 14 views
13

de Google "Go" dice on its website:¿No hay tabla de símbolos en Go? nuevo lenguaje

el idioma ha sido diseñado para ser fácil de analizar y puede ser analizado sin una tabla de símbolos

Ciertamente no soy experto en estos temas , pero pensé que una tabla de símbolos era una construcción básica común a todos los compiladores para idiomas que usan variables, y Go usa claramente variables. ¿Qué no estoy entendiendo?

Respuesta

20

Analizar significa simplemente descifrar la estructura del programa: separar el módulo en declaraciones/declaraciones, dividir expresiones en sub-expresiones, etc. Usted termina con una estructura de árbol, conocida como "árbol de análisis sintáctico", o "resumen" árbol de sintaxis "(AST).

Al parecer, C++ requiere una tabla de símbolos que hacer el análisis sintáctico.

está página explica algunas de las razones why C++ requires a symbol table for parsing.

Por supuesto, el análisis sintáctico es sólo una parte de la compilación, y se necesita una tabla de símbolos que hacer una compilación completa.

Sin embargo, el análisis en sí mismo puede ser útil en la escritura herramientas de análisis (por ejemplo, que las importaciones que módulos de módulo). Por lo tanto, simplificar el proceso de análisis significa que es más fácil escribir herramientas de análisis de código.

+1

Esa es una excelente referencia. –

+0

Honestamente, fue solo el primer (o segundo) resultado de Google – hasen

+1

Tenga en cuenta también las respuestas a esa publicación; también contienen muy buenas razones por las que es imposible. – MSalters

10

interpretación y compilación absolutamente requieren tablas de símbolos o similares. Esto es cierto para casi todos los idiomas.

En C y C++, incluso analizando el lenguaje requiere una tabla de símbolos.

+0

Eso es lo que pensé. Entonces, ¿cómo puede su reclamo ser cierto? Supongo que debe ser, pero no entiendo cómo. – Dinah

+2

@Dinah: lea la declaración de nuevo lentamente, luego lea esta respuesta nuevamente. No son contradictorios. –

+1

@Dinah: hay más en la compilación que en el análisis. El análisis construye una representación en árbol de la estructura del programa.El análisis semántico y la generación de código operan en ese árbol para producir el resultado compilado. – quark

8

@Justice es correcto. Para ampliar un poco eso, en C, la única parte realmente difícil es distinguir los tipos de las variables. Específicamente cuando vea esto:

T t; 

lo que necesita saber que T es un tipo para que para ser un análisis sintáctico legal. Eso es algo que tienes que buscar en una tabla de símbolos. Esto es relativamente simple de entender siempre y cuando los tipos se agreguen a la tabla de símbolos a medida que continúa el análisis. No necesita hacer mucho trabajo adicional en el compilador: T está presente en la tabla o no lo está.

En C++ las cosas son mucho, mucho más complicado. Hay un enorme número de constructos ambiguos o potencialmente ambiguos. La más obvia es ésta:

B::C (c); 

Aparte del hecho de que no está claro si B es una class, un typedef, o una namespace, tampoco es claro si C es un tipo y c un objeto de esa tipo, o si C es una función (o constructor) que toma c como argumento (o incluso si C es un objeto con operator() sobrecargado). Necesita la tabla de símbolos para continuar con el análisis sintáctico, aunque aún es posible continuar lo suficientemente rápido, ya que el tipo del símbolo se encuentra en la tabla de símbolos.

Las cosas se ponen mucho, mucho, mucho peor que cuando las plantillas entran en la mezcla. Si C (c) está en una plantilla, es posible que no conozca la definición real de la plantilla, si C es un tipo o una función/objeto.Esto se debe a que la plantilla puede declarar C como ya sea un tipo o una variable. Lo que esto significa es que necesita la tabla de símbolos, pero usted no tiene tiene uno - y usted no puede tener uno hasta que la plantilla se declare realmente. Peor aún, no es necesariamente suficiente tener solo el tipo del símbolo: puede encontrar situaciones que requieren la información completa del tipo que representa el símbolo, incluido el tamaño, la alineación y otra información específica de la máquina.

Todo esto tiene varios efectos prácticos. Los dos más significativos que diría son:

  • La compilación es mucho más rápida. Supongo que Go es más rápido de compilar que C, y C++ tiene tiempos de recopilación famosos lentos para situaciones que involucran muchas plantillas.
  • Puede escribir analizadores que no dependen de tener un compilador completo. Esto es muy útil para hacer análisis de código y refactorizar.
2

Para analizar la mayoría de los idiomas que necesita saber cuando los nombres son variables, tipos o funciones para desambiguar ciertas construcciones. Go no tiene tales constructos ambiguos.

Por ejemplo:

int x = Foo (bar);

Foo podría ser un tipo o una función y están representados por diferentes tipos de AST. Básicamente, el analizador nunca tiene que hacer búsquedas en símbolos para saber cómo construir el AST. La gramática y AST son simplemente más simples que la mayoría de los lenguajes. Muy bueno realmente.

0

Las tablas de símbolos son lentas y generalmente no son necesarias. Así que ve y elige irse con eso. Otros lenguajes funcionales tampoco necesitan ninguno. La búsqueda rápida requiere un algoritmo hash, pero para admitir ámbitos anidados, debe insertar/mostrar nombres en una pila. Simple symtabs se implementan como la pila de búsqueda lineal, mejores symtabs como hash con una pila por símbolo. Pero aún así, la búsqueda debe hacerse en tiempo de ejecución.

La interpretación y compilación para lenguajes de ámbito léxico no requieren absolutamente ninguna tabla de símbolos o similar. Solo los símbolos de ámbito dinámico necesitan tablas de símbolos, y algunos compiladores con lenguajes estrictamente tipados necesitan algún tipo de tabla de símbolos interna para contener las anotaciones de tipo.

En C y C++, incluso el análisis del lenguaje requiere una tabla de símbolos, ya que necesita almacenar los tipos y declaraciones de funciones globales y.

Los símbolos de ámbito léxico no se almacenan en symtab, sino como una lista indizada de nombres en marcos de bloque, como en los lenguajes funcionales. Esos índices se calculan en tiempo de compilación. Por lo tanto, el acceso en tiempo de ejecución es inmediato. Salir del alcance hace que esos archivos sean inaccesibles de forma automática, por lo que no es necesario que pulse/muestre los nombres de los espacios de nombres/symtabs.

Los idiomas no tan funcionales sin funciones de primera clase a menudo necesitan almacenar sus nombres de funciones en tablas de símbolos. Como diseñador de idiomas, intenta vincular funciones a léxicos en su lugar, para poder deshacerse de la búsqueda dinámica de nombres en symtabs.

Cuestiones relacionadas