106 votes

Sont GCC et Clang analyseurs vraiment manuscrite?

Un gars nommé Eli Bendersky a écrit dans son blog que GCC et Clang analyseur sont manuscrites, qui n'est pas fait avec l'aide de yacc ou de tout autre compilateur de compilateur. En outre, il semble à-dire qu'ils sont récursives de la descente des analyseurs.

Quelqu'un pourrait-il ici confirment que quelques grands compilateur cadres de toujours recourir à de telles manuscrite analyseurs?

123voto

Ira Baxter Points 48153

Il y a un folk-théorème qui dit que C est difficile à analyser, et le C++ est essentiellement impossible.

Ce n'est pas vrai.

Ce qui est vrai est que le C et le C++ sont assez difficile à analyser à l'aide de LALR(1) les analyseurs sans le piratage de l'analyse de la machinerie et de s'emmêler dans la table des symboles de données. GCC en fait utilisée pour analyser, à l'aide de YACC et supplémentaires hackery comme ça, et oui c'était laid. (Maintenant GCC utilise manuscrite des analyseurs, mais toujours avec le symbole de la table hackery. Oui, c'est toujours aussi moche!)

Ce qui est vrai, c'est que le C et le C++ sont relativement faciles à analyser avec plus d'analyseurs, par exemple, GLR analyseurs, et vous n'avez pas besoin de tous les hacks. L' Elsa analyseur C++ est un exemple. Notre interface C++ est un autre (comme le sont tous nos "compilateur" frontaux, GLR est assez merveilleux analyse de la technologie).

Notre interface C++ n'est pas aussi rapide que du CCG, et certainement plus lent que d'Elsa; nous avons mis peu d'énergie dans le tuning avec précaution car nous avons d'autres questions plus urgentes (néanmoins il a été utilisé sur des millions de lignes de code C++). Elsa est probablement plus lent que GCC simplement parce qu'il est plus général. Compte tenu de la vitesse des processeurs, ces jours, ces différences n'importe pas beaucoup dans la pratique.

Mais la "vraie compilateurs", qui sont largement diffusés aujourd'hui ont leurs racines dans les compilateurs de 10 ou 20 ans ou plus. Les inefficacités puis importait beaucoup plus, et personne n'avait entendu parler de GLR d'analyseurs, de sorte que les gens ont fait ce qu'ils savaient comment faire. Clang est certes plus récente, mais ensuite folk théorèmes de conserver leur "force de persuasion" pour un long moment.

Vous n'avez pas à faire plus de cette façon. Vous pouvez très raisonnablement utiliser GLR et d'autres analyseurs de front se termine, avec une amélioration dans le compilateur de maintenabilité.

Ce qui est vrai, c'est que l'obtention d'une grammaire qui correspond à votre quartier sympathique du compilateur comportement est dur. Alors que pratiquement tous les compilateurs C++ mettre en œuvre (la plupart) de la norme d'origine, ils ont aussi tendance a beaucoup de coin sombre extensions, par exemple, DLL spécifications MS compilateurs, etc. Si vous avez un fort moteur d'analyse, vous pouvez passer votre temps à essayer de faire la finale de la grammaire afin de correspondre à la réalité, plutôt que d'essayer de plier votre grammaire de faire correspondre les limites de votre analyseur générateur.

EDIT de novembre 2012: Depuis la rédaction de cette réponse, nous avons amélioré notre interface C++ pour gérer plein de C++11, ANSI, GNU, et MME variante de dialectes. Alors qu'il y a beaucoup de trucs supplémentaires, nous n'avons pas à changer notre moteur de l'analyse; nous vient de réviser les règles de grammaire. Nous n' avons pour modifier l'analyse sémantique; C++11 est sémantiquement très compliqué, et ce travail marécages de l'effort pour obtenir l'analyseur à exécuter.

84voto

Matthew Slattery Points 21628

Oui:

  • GCC utilisé un yacc (bison) analyseur de once upon a time, mais il a été remplacé par un écrit à la main descente récursive de l'analyseur à un certain point dans le 3.série x: voir http://gcc.gnu.org/wiki/New_C_Parser pour les liens vers les patch présentations.

  • Clang utilise également écrite à la main descente récursive de l'analyseur: voir la section "unique analyseur pour C, Objective C, C++ et Objective-C++" près de la fin de http://clang.llvm.org/features.html .

36voto

Doug Points 151

Bruit de l'analyseur est écrite à la main récursive de la descente de l'analyseur, à l'instar de plusieurs autres et de l'open source commercial de C et de C++ avant se termine.

Clang utilise un appel récursif à la descente de l'analyseur pour plusieurs raisons:

  • Performance: un écrit à la main de l'analyseur permet d'écrire un analyseur rapide, l'optimisation de la chaude chemins d'accès nécessaire, et nous sommes toujours dans le contrôle de la performance. Ayant une forte analyseur a permis de Clang pour être utilisé dans d'autres outils de développement où le "réel" analyseurs ne sont généralement pas utilisés, par exemple, de la syntaxe et de la complétion de code dans un IDE.
  • De diagnostic et de reprise sur erreur: parce que vous êtes en plein contrôle, avec un écrit à la main récursive de la descente de l'analyseur, il est facile d'ajouter des cas spéciaux qui permettent de détecter des problèmes communs et assurer un bon diagnostic et de récupération d'erreur (par exemple, voir http://clang.llvm.org/features.html#expressivediags) générées automatiquement des analyseurs, vous êtes limité à la capacité de la génératrice.
  • Simplicité: récursive de la descente analyseurs sont faciles à écrire, à comprendre et à déboguer. Vous n'avez pas besoin d'être une analyse d'expert ou d'apprendre un nouvel outil pour augmenter/améliorer l'analyseur (ce qui est particulièrement important pour un projet open-source), mais vous pouvez toujours obtenir de grands résultats.

Dans l'ensemble, pour un compilateur C++, il n'a tout simplement pas beaucoup d'importance: l'analyse de la partie de C++ est non-trivial, mais cela reste une de la plus facile des pièces, de sorte qu'il paie pour rester simple. L'analyse sémantique---en particulier la recherche d'un nom, d'initialisation, de résolution de surcharge, et l'instanciation d'un modèle---est un ordre de grandeur plus compliqué que de l'analyse. Si vous voulez la preuve, allez vérifier la distribution de ce code et s'engage dans Clang "Sema" (composante sémantique pour l'analyse) par rapport à son "Analyser" composant (pour l'analyse).

10voto

user1952009 Points 89

bizarre les réponses il y !

C/C++ grammaires ne sont pas sans contexte. Ils sont sensibles au contexte et en raison de la Foo * bar; ambiguïté. Nous avons à construire une liste de typedefs de savoir si Toto est un type ou pas.

Ira Baxter: je ne vois pas le point avec votre GLR chose. Pourquoi construire un arbre d'analyse qui comporte des ambiguïtés. L'analyse des moyens de résolution des ambiguïtés, la construction de l'arbre syntaxique. Vous résoudre ces ambiguïtés dans un second passage, donc ce n'est pas moins moche. Pour moi, c'est beaucoup plus moche ...

Yacc est une LR(1) analyseur générateur (ou LALR(1)), mais il peut être facilement modifié pour être sensibles au contexte. Et il n'y a rien de laid. Yacc/Bison a été créé pour aider dans l'analyse C langage, et c'est probablement ce n'est pas le plus laid de l'outil pour générer un C analyseur ...

Jusqu'à ce que GCC 3.x le C de l'analyseur généré par yacc/bison, avec des typedefs tableau construit au cours de l'analyse. Avec "analyser" typedefs table bâtiment C de la grammaire devient localement contexte libre et en outre "localement LR(1)".

Maintenant, dans Gcc 4.x, c'est un appel récursif à la descente de l'analyseur. C'est exactement le même analyseur de Gcc 3.x, il est toujours LR(1), et a les mêmes règles de grammaire. La différence est que la yacc analyseur a été réécrit, le shift/reduce sont cachés dans la pile d'appel, et il n'y a pas de "state454 : si (nextsym == '(') goto state398" comme dans gcc 3.x yacc de l'analyseur, de sorte qu'il est plus facile de patch, de gérer les erreurs et de les imprimer plus beau des messages, et de réaliser une partie de la prochaine compilation de mesures au cours de l'analyse. Au prix de beaucoup moins "facile à lire" le code pour une gcc noob.

Pourquoi ont-ils changé à partir de yacc récursif descente ? Parce qu'il est tout à fait nécessaire pour éviter yacc pour analyser le C++, et parce que GCC rêves d'être multi langage compilateur, c'est à dire maximum de partage de code entre les différents langages, il peut compiler. C'est pourquoi le C++ et le C de l'analyseur sont écrits de la même manière.

C++ est plus difficile à analyser que C parce qu'il n'est pas "local" LR(1) (C, il n'est même pas LR(k). Regardez func<4 > 2>, qui est une fonction de modèle instancié avec 4 > 2, c'est à dire func<4 > 2> doit être readen func<1>. Ce n'est certainement pas LR(1). Considérons maintenant, func<4 > 2 > 1 > 3 > 3 > 8 > 9 > 8 > 7 > 8>. C'est là une descente récursive peut facilement résoudre l'ambiguïté, au prix d'un peu plus d'appels de fonction (parse_template_parameter est le ambiguë analyseur de fonction. Si parse_template_parameter(17tokens) a échoué, essayez à nouveau parse_template_parameter(15tokens), parse_template_parameter(13tokens) ... jusqu'à ce qu'il fonctionne).

Je ne sais pas pourquoi il ne serait pas possible d'ajouter dans yacc/bison récursive des sous grammaires, peut-être que ce sera la prochaine étape de la gcc/GNU analyseurs de développement ?

9voto

Rafe Kettler Points 29389

gcc est un analyseur de la main.. Je soupçonne la même chose pour clang. C'est probablement pour quelques raisons:

  • Performance: quelque chose que vous avez à la main optimisée pour votre tâche particulière sera presque toujours faire mieux que une solution générale. L'Abstraction a généralement un gain de performance
  • Calendrier: au moins dans le cas de la GCC, GCC est antérieure à beaucoup de libre des outils de développement (sorti en 1987). Il n'y a pas de version gratuite de yacc, etc. à l'époque, j'imagine que ce serait une priorité pour les personnes à la FSF.

Ce n'est probablement pas un cas de "pas inventé ici" syndrome, mais de plus le long des lignes de "il n'y a rien de spécifiquement optimisées pour ce dont nous avions besoin, et nous avons écrit notre propre".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X