Dans toutes les langues d'exception, je sais (C ++, Java, C #, Python, Delphi-Pascal, PHP), une exception accrocheuse nécessite un au lieu de ceci: p> existe une raison de mise en œuvre de cette , ou est-ce juste "quelqu'un le conçut d'abord de cette façon et maintenant tout le monde ne le connaît-il que et la copie?" P> La façon dont je le vois, cela n'a aucun sens pour les langues compilées - Le compilateur voit le Taille de code source entier avant de générer n'importe quel code, il pourrait donc facilement insérer le mot-clé code> devant un bloc de la volée lorsqu'un Laissons de côté les langues sans un moyen explicite de déclarer des blocs arbitraires (tels que Python). Dans tous les autres, y a-t-il une raison technique pour nécessiter un Essayer explicite code> Bloquer par
Catch Code > blocs. Je me demandais souvent quelle est la raison technique de cela. Pourquoi ne pouvions-nous pas simplement ajouter
attraper des clauses code> à un bloc de code par ailleurs ordinaire? Comme exemple C ++, pourquoi devons-nous écrire ceci:
Catch code> suit ce bloc (s'il a besoin Pour générer un code spécial pour
essayer code> des blocs en premier lieu). Je pouvais imaginer une certaine utilisation dans des langues interprétées qui ne manquent pas à l'avance et doivent en même temps de prendre des mesures au début d'un
essayer code> bloc, mais je ne sais pas si des langues de ce type existent . P>
essayer code> (ou équivalent)? P> p>
5 Réponses :
L'idée générale lors de la conception des langues doit indiquer le plus tôt possible, quelle construction vous êtes dedans, de sorte que le compilateur n'a pas à effectuer un travail inutile. Ce que vous suggérez, vous devez vous souvenir de chaque bloc {} code> comme étant possible
ESSAYER CODE> BLOCK START, seulement pour constater que la plupart d'entre elles ne sont pas. Vous constaterez que chaque relevé de Pascal, C, C ++, Java, etc. est introduit par un mot clé à l'exception exclusive des relevés d'affectation. P>
Bon point. Cependant, étant donné l'ambiguïté de l'expression / de la déclaration dans la grammaire de C ++, je ne pense pas vraiment "chaque relevé est introduit par un mot-clé." Mais je vois ce que tu veux dire.
@Angew est une raison de plus pour ne pas introduire un autre problème grammaire ou sémantique.
Je crois que la même chose que @ejp. Un autre exemple est le pendant code> boucle. Lorsque vous mettez le mot-clé code> tandis que code> à la fin, vous devez démarrer le bloc avec
faire code>.
@ Mauroh.leggieri qui est légèrement différent, car ce serait ambigu. Est {foo (x); } tandis que (-x); code> a
do-while code> ou un bloc normal suivi d'un
pendant code> boucle avec un corps vide? Aucune ambiguïté ne se pose dans le cas CODE> TRY-CATCH code>.
Parler d'un point de vue pratique: en spécifiant le essayer code>, vous permettez une meilleure modularité dans
attrape code> exceptions. Plus précisément, il permet une nidification plus propre de la manipulation des exceptions. Pour ajouter à La réponse EJP a ajoute à la lisibilité lorsque les blocs de capture sont intégrés à d'autres personnes. Lisibilité est em> une considération importante et lorsqu'il y a plusieurs blocs
{} code> blocks, le
Essayez code> ajoute un excellent point de référence pour discret
code> es. p>
Il existe plusieurs types de réponses à cette question, qui pourraient tous être pertinents.
La première question concerne l'efficacité et la distinction entre les langues compilées et interprétées. L'intuition de base est correcte, que les détails de la syntaxe n'affectent pas le code généré. Les analyseurs génèrent généralement un arbre de syntaxe abstraite (être explicitement ou implicitement), que ce soit pour les compilateurs ou les interprètes. Une fois que l'AST est en place, les détails de la syntaxe utilisée pour générer les AST sont hors de propos. P>
La question suivante est de savoir si une nécessité d'un mot clé explicite aide à analyser ou non. La réponse simple est que ce n'est pas nécessaire, mais peut être utile. Pour comprendre pourquoi ce n'est pas nécessaire, vous devez savoir ce qu'est un "lookahead Set" pour un analyseur. Le lookahead Set est un ensemble de jetons pour chaque état d'analyse qui serait correct grammaire s'ils apparaissaient ensuite dans le flux de jeton. Générateurs d'analyseurs tels que considère maintenant une langue qui, telle que proposée dans la question, utilise la syntaxe suivante pour les exceptions: p> avec cette syntaxe, un bloc peut soit être orné d'un bloc d'exception ou non. La question à propos de l'ambiguïté est de savoir si, après avoir vu un bloc code> code>, que le mot clé code> est ambigu. En supposant que le mot clé code> est unique, il est totalement sans ambiguïté que l'analyseur reconnaisse une déclaration ornée d'exception. P> Maintenant, j'ai dit qu'il est utile de devoir avoir une explicite La dernière question sur un Bison CODE> Modèle Ce lookahead définit explicitement. Les analyseurs de descente récursives ont également un lookahead set, mais ils ne semblent souvent pas explicitement dans une table. p>
Essayez CODE> Mot clé pour l'analyseur. De quelle manière est-il utile? Il contraint le regard sur les lookahead pour certains états d'analyseurs. Le lookahead set après
Essayez code> est le jeton unique
{ code>. Le lookahead set après la correspondance Fermer Brace est le mot clé unique
attrape code>. Un analyseur axé sur la table ne se soucie pas de cela, mais il rend un analyseur de descente récursif écrit à la main un peu plus facile à écrire. Plus important encore, cependant, il améliore la manipulation des erreurs dans l'analyseur. Si une erreur de syntaxe se produit dans le premier bloc, un mot-clé code> ESSAYER CODE> peut rechercher un jeton code> code> comme poste de clôture à laquelle rétablir une Etat d'analyseur, possible exactement parce que c'est le membre unique d'un ensemble lookahead. P>
Essayez code> Mot-clé a à voir avec la conception de la langue. Il suffit de mettre, avoir des mots-clés explicites devant les blocs rend le code plus facile à lire. Les humains doivent encore analyser le code par les yeux, même s'ils n'utilisent pas d'algorithmes informatiques pour le faire. La réduction de la taille de la lookahead définie dans la grammaire formelle réduit également les possibilités de ce qu'une section de code pourrait signifier lors de la première coup d'œil à. Cela améliore la clarté du code. P> p>
J'ai posé une question qui implique une réponse à celle-ci. p>
Explicit La stratégie SETJMP / LONGJMP, nommée pour les fonctions de la bibliothèque standard C, enregistre des informations de contexte lors de la saisie d'un bloc d'essai. Cette information sera approximativement "dans ce contexte, des exceptions de ce type sautent à cette adresse, des exceptions de ce type de type sautent à cette adresse, et d'autres types d'exception bulle de la pile de contexte". Cela permet aux exceptions levées de trouver la capture correspondante rapidement, mais nécessite un sauvegarde de contexte pendant l'exécution, même lorsque aucune exception n'est lancée. P>
Dans la stratégie de coût zéro, essayez des blocs sans frais inhérents, mais trouver le bloc de capture pour une exception lancée est lent. Au lieu d'économiser des informations de contexte au moment de l'exécution lors de la saisie d'un bloc code> ESSAYER CODE>, le compilateur construit des tables au moment de la compilation pouvant être utilisée pour trouver des blocs de capture donnés à l'origine d'une exception lancée. La table spécifie les gammes d'instructions et les blocs de capture associés. Une façon de mettre en œuvre cela serait avec la taille de la plage variable et la recherche binaire. P>
La stratégie SETJMP / LONDJMP nécessite La stratégie de coût zéro ne dépend pas d'essayer des blocs. P>
Étant donné que les deux méthodes ont des compromis en efficacité, il est logique de laisser le choix aux exécutants linguistiques et de fournir les blocs Essayez CODE> Les blocs peuvent permettre une mise en œuvre plus efficace de la manipulation des exceptions, en particulier lorsque des exceptions sont lancées. Les deux stratégies populaires pour mettre en œuvre des exceptions sont "SETJMP / LONGJMP" et "Coût zéro". P>
Essayez CODE> Blocks pour savoir quand enregistrer le contexte. p>
Essayez code> pour la stratégie SETJMP / LONGJMP. P >
Le point de cette question est "Je crois que vous pouvez identifier sans ambiguïté le bloc correct essayer b> même sans le essayer code> mot-clé. Pourquoi avoir le mot-clé, alors?" Votre question semble être le long des lignes de "Pourquoi un bloc essaie B> doit-il être un bloc?"
Exiger que les structures de contrôle qui fixent aux extrémités des blocs soient jumelées avec des indicateurs avant que ces blocs évite la confusion dans des scénarios comme: imagine qu'au lieu de la déclaration tandis que (condition) code> c avait utilisé la déclaration de syntaxe
; jusqu'à ce que (! condition); code> Est-ce que cela rend cela plus ou moins clair? P>
if (condition1)
{
action1();
} until(!condition2);
else
action2();
Cher Downvoter, soin de commenter?
L'a soigné pour vous. Pas besoin de bowvotes sur cette question imo
Maybee améliorer la lisibilité humaine. Il est plus facile de voir dans quelle partie du code que vous attendez d'une exception
Ce n'est pas une réponse, mais simplement pour donner un exemple (je n'ai vu aucun dans les réponses) d'une langue compilée qui n'a pas de "essayer": ada b>. Dans ADA, vous essayez / attraper d'une manière qui pourrait être traduite en C
{..} Catch {...} code>.