2009-11-12 13 views
13

Google nouvelle langue « Go » dit on its website:Aucune table de symboles dans Go?

la langue a été conçu pour être facile à analyser et peut être analysé sans une table de symboles

Je ne suis certainement pas un expert sur ces questions , mais je pensais qu'une table de symboles était une construction de base commune à tous les compilateurs pour les langages utilisant des variables, et Go utilise clairement des variables. Qu'est-ce que je ne comprends pas?

Répondre

20

L'analyse signifie simplement déterminer la structure du programme: séparer le module en instructions/déclarations, briser les expressions en sous-expressions, etc. Vous vous retrouvez avec une structure arborescente, appelée "arbre d'analyse", ou "résumé". arbre de syntaxe "(AST).

Apparemment, C++ nécessite une table de symboles pour effectuer l'analyse syntaxique.

Cette page explique certaines raisons why C++ requires a symbol table for parsing.

Bien sûr, l'analyse n'est qu'une partie de la compilation, et vous aurez besoin d'une table de symboles pour faire une compilation complète. Toutefois, l'analyse elle-même peut être utile pour écrire des outils d'analyse (par exemple, quel module importe quels modules). Ainsi, en simplifiant le processus d'analyse, il est plus facile d'écrire des outils d'analyse de code.

+1

C'est une excellente référence. –

+0

Honnêtement, c'était juste le premier (ou deuxième) résultat de Google – hasen

+1

Notez également les réponses à ce poste - elles aussi contiennent de très bonnes raisons pour lesquelles c'est impossible. – MSalters

10

L'interprétation et la compilation nécessite absolument des tables de symboles ou similaire. Cela est vrai pour presque toutes les langues.

En C et C++, même l'analyse la langue nécessite une table de symboles.

+0

C'est ce que je pensais. Alors, comment leur affirmation peut-elle être vraie? Je suppose que cela doit être, mais je ne comprends pas comment. – Dinah

+2

@Dinah: Relisez lentement l'instruction, puis relisez cette réponse. Ils ne sont pas contradictoires. –

+1

@Dinah: Il y a plus à compiler qu'à analyser. L'analyse génère une représentation arborescente de la structure du programme.L'analyse sémantique et la génération de code fonctionnent ensuite sur cet arbre pour produire la sortie compilée. – quark

8

@Justice a raison. Pour développer cela un peu, en C la seule partie délicate est de distinguer les types des variables. Plus précisément quand vous voyez ceci:

T t; 

Vous devez savoir que T est un type pour que ce soit une analyse syntaxique juridique. C'est quelque chose que vous devez rechercher dans une table de symboles. Ceci est relativement simple à comprendre tant que les types sont ajoutés à la table de symboles pendant que l'analyse se poursuit. Vous n'avez pas besoin de faire beaucoup de travail supplémentaire dans le compilateur: soit T soit présent dans la table ou ce n'est pas le cas.

En C++ choses sont beaucoup, beaucoup plus compliqué. Il y a énormément de constructions ambiguës ou potentiellement ambiguës. La plus évidente est celle-ci:

B::C (c); 

Mis à part le fait que ce n'est pas clair si B est un class, un typedef ou un namespace, il est également pas clair si C est un type et c un objet de cette type, ou si C est une fonction (ou un constructeur) prenant c en tant qu'argument (ou même si C est un objet avec operator() surchargé). Vous avez besoin de la table de symboles pour continuer l'analyse, bien qu'il soit toujours possible de continuer assez rapidement, car le type du symbole est dans la table des symboles.

Les choses deviennent beaucoup, beaucoup, beaucoup pires que lorsque les gabarits entrent dans le mixage. Si C (c) est dans un modèle, il est possible que vous ne connaissiez pas la définition réelle du modèle, si C est un type ou une fonction/un objet.En effet, le modèle peut déclarer C être soit un type, soit une variable. Cela signifie que vous avez besoin de la table de symboles, mais vous n'avez pas de et vous ne pouvez pas en avoir une jusqu'à ce que le modèle soit déclaré. Pire encore, il n'est pas forcément suffisant d'avoir seulement le type du symbole: vous pouvez trouver des situations qui requièrent l'information complète du type représenté par le symbole, y compris la taille, l'alignement et d'autres informations spécifiques à la machine.

Tout cela a plusieurs effets pratiques. Les deux plus importants que je dirais sont:

  • La compilation est beaucoup plus rapide. Je suppose que Go est plus rapide à compiler que C, et C++ a des temps de compilation très lents pour les situations impliquant beaucoup de modèles.
  • Vous pouvez écrire des analyseurs qui ne dépendent pas d'un compilateur complet. C'est très utile pour faire de l'analyse de code et pour refactoriser.
2

Pour analyser la plupart des langages, vous devez savoir quand les noms sont des variables, des types ou des fonctions pour désambiguïser certaines constructions. Go n'a pas de telles constructions ambiguës.

Par exemple:

int x = Foo (bar);

Foo peut être un type ou une fonction et ils sont représentés par différents types AST. Fondamentalement, l'analyseur n'a jamais à faire des recherches sur les symboles pour savoir comment construire l'AST. La grammaire et l'AST sont simplement plus simples que la plupart des langues. Assez cool vraiment.

0

Les tables de symboles sont lentes et généralement inutiles. Alors, choisis de partir avec. D'autres langages fonctionnels n'en ont pas non plus besoin. La recherche rapide nécessite un hachage, mais pour prendre en charge les étendues imbriquées, vous devez placer les noms sur une pile. Les symtabs simples sont implémentés en pile linéaire recherchée, les meilleurs symtabs en tant que hash avec une pile par symbole. Mais encore, la recherche doit être effectuée au moment de l'exécution.

L'interprétation et la compilation pour les langages à portée lexicale ne nécessitent absolument aucune table de symboles ou similaire. Seuls les symboles de portée dynamique nécessitent des tables de symboles, et certains compilateurs avec des langues strictement typées ont besoin d'une sorte de table de symboles interne pour contenir les annotations de type.

En C et C++, même l'analyse du langage nécessite une table de symboles, car vous devez stocker les types et les déclarations de globales et de fonctions.

Les symboles de portée lexicale ne sont pas stockés dans la liste de noms de symtab mais sous forme de liste indexée dans des blocs de blocs, comme dans les langages fonctionnels. Ces indices sont calculés à la compilation. L'accès à l'exécution est donc immédiat. Si vous quittez la portée, ces variables sont automatiquement inaccessibles. Vous n'avez donc pas besoin d'appuyer sur les noms des espaces de noms/symtabs.

Les langages moins fonctionnels sans fonctions de première classe ont souvent besoin de stocker leurs noms de fonctions dans des tables de symboles. En tant que concepteur de langage, vous essayez à la place de lier des fonctions à des lexiques, pour pouvoir vous débarrasser de la recherche dynamique de noms dans symtabs.