9
votes

Mise en œuvre goto dans une ASTO

arrière-plan: En tant que court projet sur la pause hivernale, j'essaie de mettre en œuvre une langue de programmation appelée AX (conçue pour les calculatrices graphiques) en utilisant Python et Ply. BREF NOTE: La langue n'autorise que des variables globales et utilise une forte utilisation de pointeurs.

J'essaie de mettre en œuvre GOTO dans cette langue, mais je ne sais pas comment le faire. STRUT> P >

Ma méthode générale est d'abord utiliser la plie pour analyser le code dans une AST, puis la promenade à l'exécution de celle-ci comme je vais. p>

Par exemple, la déclaration P>

['PROGRAM', 
  ['BLOCK', 
    ['IF', 
      ['CONDITION', 3], 
      ['BLOCK', 
        ['DISP', 4], 
        ['DISP', 6]
      ]
    ]
  ]
]


5 commentaires

"Saut"? Que pensez-vous que vous voulez dire par "saut"? Pourquoi voudriez-vous "sauter" entre les nœuds? Veuillez fournir un exemple spécifique dans lequel vous «sauteriez» à un nœud arbitraire. Il est difficile de trouver un besoin sensible pour un saut dans une langue basée sur des arbres.


La langue que je choisise de mettre en œuvre a des déclarations goto. Je voulais faire correspondre la spécification, c'est pourquoi j'ai besoin de goto. J'ai fait cette arborescence, car cela semblait être une chose sensible à faire à l'époque. Je suppose que c'était une erreur: quelles autres formes de langues y a-t-il?


Axe vraiment nécessite un goto? Semble étrange. Il y a un nombre infini de "formes" de langues: procédural, fonctionnel, etc., etc. Parmi les langues de procédure, Python et Java (entre autres) n'ont pas de goto. C'est une chose assez rare.


Ast est bon à la compilation, pas à l'évaluation. Sauf goto Il y a d'autres problèmes - boucles. Comment voulez-vous mettre en œuvre des boucles sans une sorte de compteur de programme?


C'est une langue de bas niveau. En outre, j'ai mis en œuvre des boucles plus tôt en utilisant une boucle "tandis que".


3 Réponses :


9
votes

"Exécuter récursivement" ne convient pas bien avec goto . Pour goto pour fonctionner, vous avez besoin d'un PC, d'un "compteur de programme" et de chaque instruction de votre programme doit avoir une adresse distincte. Comme il est exécuté, l'adresse de chaque instruction est attribuée au PC. Lorsque goto est rencontré, l'adresse cible de la goto (son argument) est mise au point sur le PC et l'exécution reprend à partir de là.

Ceci est presque impossible à réaliser avec une approche de pile et récursive. Vous avez deux options:

  • aplatir votre ast dans une séquence où vous pouvez affecter une adresse distincte à chaque relevé

  • Ajouter un mode "Skip" à votre interprète. Lorsque goto est rencontré, lancez un gotoexception qui éclate de toutes les cadres de pile et retourne à la racine. Déclarations de processus (sautez-les sans exécuter) jusqu'à ce que vous atteigniez l'adresse cible.

    Je pense que vous pouvez imaginer que cette implémentation de goto n'est pas très performante et probablement fragile à mettre en œuvre.


1 commentaires

Ok, merci pour les suggestions! Je pense que je vais aller avec aplatissement de l'arbre.



3
votes

J'ai envisagé peut-être de convertir l'arbre en une matrice plate-ish ... mais cela semble manquer d'élégance certaine et ressemble presque à un pas en arrière (bien que je puisse me tromper).

Vous avez tort. Le code de la machine est toujours plat. Les langues comme c sont aplaties pour créer un code de machine.

Une calculatrice (comme d'autres machines simples) est plate.

Cependant. L'aplatissement de votre arbre de syntaxe AX n'est pas complètement nécessaire .

Vous devez simplement appliquer les étiquettes source de programmation à chaque nœud de votre arbre.

Puis un "goto" cherche simplement l'arborescence pour cette étiquette et reprend l'exécution sur cette étiquette.


2 commentaires

Ah, bon point sur le code de la machine. Je suppose que j'avais tort à ce sujet alors :)


Parce que le code de la machine est plat, nous ne l'utilisons pas souvent pour la programmation de nos jours. Nous préférons les langages structurés et utilisons des outils pour aplatir une belle langue structurée dans le monde plat de l'exécution de la machine.



0
votes

Vous pouvez également aplatir l'AST à un graphique dirigé (le graphe de contrôle). Un exemple de la manière dont cela peut être fait pour produire un NetworkX graphique qui peut être traversé par le L'interprète peut être trouvé dans le package Python Promela . Notez que vous devrez écrire des classes AST à cette fin.


0 commentaires