Maison> développement back-end> Golang> le corps du texte

Phrases imbriquées

王林
Libérer: 2024-07-31 10:27:53
original
508 Les gens l'ont consulté

Sentenças aninhadas

Pour ceux qui ne suivent pas POJ (Pascal sur la JVM) est un compilateur qui transforme unsubsetde Pascal en JASM (Java Assembly) afin que nous puissions utiliser la JVM comme environnement d'exécution.

Dans le dernier post, nous avons résolu quelques bugs importants, notamment dans la génération duassembly. Dans cet article, nous expliquerons comment générer correctement l'assemblypour les phrases imbriquées.

Comme nous compilons pour la JVM, il est nécessaire de détailler le fonctionnement de différents points de cette incroyable machine virtuelle. C'est pourquoi, à plusieurs reprises, je détaille le fonctionnement interne de la JVM ainsi que certaines de ses instructions (opcodes).

Contextes

L'une des fonctionnalités nécessaires pour traiter correctement les phrases imbriquées est la possibilité d'avoir plusieurs contextes dans leparser. En effet, si leparserne suppose qu'un seul contexte, les phrases de contrôle imbriquées qui génèrent deslabelset des sauts (telles queif,for,whileetrepeat) généreraient un adressage de saut incorrect. .

Il existe deux manières de gérer les contextes, à savoir :

  • Analyseur récursif
  • Contextes de pile
Habituellement, j'utiliserais l'approche récursive

parser. Cependant, pour implémenter unanalyseurrécursif avec ANTLR, en raison de la manière dont la grammaire a été structurée en POJ, il serait nécessaire d'injecter du code directement dans la grammaire, une approche qui n'est pas recommandée. En conséquence, nous avons opté pour l’approche d’empilement de contextes.

Comme il existait déjà une implémentation de pile qui surveillait les types que le

parserempilait/dépilait dans la JVM, afin de ne pas avoir à créer une autre pile pour un type spécifique, nous avons décidé de créer unestackgénérique dans ce PR . En plus de pouvoir profiter de cette implémentation plus tard, je peux toujours refactoriser l'ancien code et supprimer lastackspécifique existante.

Dans ce

commit, leparsera été modifié pour empiler/dépiler correctement les contextes de fonctions. Fondamentalement, au début duparserd'une fonction, le contexte est empilé, et à la fin, le contexte est dépilé.

Phrases imbriquées

Les phrases de contrôle telles que

if,pour,pendantetrépéteront fonctionné correctement. Cependant, s'il y avait des phrases imbriquées, POJ ne stockait pas le contexte et finissait par générer par erreur lesétiquetteset les sauts. Ici et ici, il a été discuté du fonctionnement de la génération deassemblypour ces phrases de contrôle.

Pour l'exemple ci-dessous, qui contient un

ifimbriqué dans un autre, POJ a généré par erreur lesétiquetteset les sauts nécessaires :

program NestedIfs; begin if (1 > 2) then if (2 > 3 ) then writeln('1 > 2 and 2 > 3') else writeln('1 > 2 and 2 <= 3') else writeln('1 <= 2'); end.
Copier après la connexion
Ce bug était connu et j'ai choisi de le résoudre lorsque l'analyseur prenait en charge les contextes.

Dans ce commit, la structure LabelsContext a été créée contenant les

labelssuivants :

  • Else: nécessaire dans le cas deifavecelse;
  • NextStatement: contient lelabelde la prochaine déclaration ;
  • IterationStart: indique le test de la structure de répétition dans le cas dewhile,repeatetfor.
Pour valider la génération correcte de l'

assembly, des tests ont été créés pour valider lesif'simbriqués, lesrepeat'simbriqués, les while imbriqués ainsi que lespourimbriqués. Des tests ont été créés ici pour valider la génération duassemblydans le cas de fonctions récursives. De plus, il a fallu mettre à jour leassemblyattendu de tous les tests existants. Enfin, dans ce PR, leparsera été mis à jour pour utiliser la nouvelle structure de contexte.

Voici le PR complet de ces changements. Ici nous avons le

commitcontenant les changements pour le bon fonctionnement de la phraseif, ici lecommitfaisant référence àrepeat, ici lecommitfaisant référence àwhileet ici lecommitfaisant référence àpour.

Prochaines étapes

Dans le prochain article, nous parlerons de la saisie des données. Il ne faudra plus longtemps avant d'atteindre l'un des objectifs de ce projet : lire un nombre à partir d'une entrée standard et calculer sa factorielle.

Code de projet complet

Le référentiel avec le code complet et la documentation du projet est ici.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!