{"id":2756,"date":"2020-06-13T07:07:13","date_gmt":"2020-06-13T04:07:13","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=2756"},"modified":"2024-12-16T22:32:27","modified_gmt":"2024-12-16T19:32:27","slug":"stack-machine","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/pt\/2020\/06\/13\/stack-machine\/","title":{"rendered":"M\u00e1quina de empilhar e RPN"},"content":{"rendered":"<p>Suponha que precisemos implementar um interpretador de bytecode simples. Que abordagem devemos escolher para implementar essa tarefa?<\/p>\n<p>Estrutura de dados A pilha fornece a capacidade de implementar uma m\u00e1quina de bytecode simples. Os recursos e implementa\u00e7\u00f5es de m\u00e1quinas stack s\u00e3o descritos em muitos artigos na Internet ocidental e dom\u00e9stica. Apenas mencionarei que a m\u00e1quina virtual Java \u00e9 um exemplo de m\u00e1quina stack.<\/p>\n<p>O princ\u00edpio de funcionamento da m\u00e1quina \u00e9 simples, um programa contendo dados e c\u00f3digos de opera\u00e7\u00e3o (opcodes) \u00e9 fornecido \u00e0 entrada e as opera\u00e7\u00f5es necess\u00e1rias s\u00e3o implementadas por meio de manipula\u00e7\u00f5es com a pilha. Vejamos um exemplo de programa de bytecode da minha m\u00e1quina de pilha:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>\u043fMVkcatS olleH\u041f\n \n<\/code><\/pre>\n<\/div>\n<p>Na sa\u00edda receberemos a string \u201cHello StackVM\u201d. A m\u00e1quina de pilha l\u00ea o programa da esquerda para a direita, carregando dados caractere por caractere na pilha quando um opcode aparece no s\u00edmbolo &#8211; implementa o comando usando a pilha.<\/p>\n<p>Exemplo de implementa\u00e7\u00e3o de uma m\u00e1quina stack em nodejs:<\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/repl.it\/repls\/FloralwhiteRoundScreenscraper?lite=true\" width=\"100%\" height=\"400px\" frameborder=\"no\" scrolling=\"no\" sandbox=\"allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<h3>Nota\u00e7\u00e3o polonesa reversa (RPN)<\/h3>\n<p>As m\u00e1quinas Stack tamb\u00e9m s\u00e3o f\u00e1ceis de usar para implementar calculadoras, para isso utilizam a nota\u00e7\u00e3o polonesa reversa (nota\u00e7\u00e3o postfix).<br \/>Exemplo de nota\u00e7\u00e3o infixa regular:<br \/>2*2+3*4<\/p>\n<p>Converte para RPN:<br \/>22*34*+<\/p>\n<p>Para contar o registro postfix usamos uma m\u00e1quina de pilha:<br \/>2&#8211; para o topo da pilha (pilha: 2)<br \/>2&#8211; para o topo da pilha (pilha: 2,2)<br \/>*&#8211; pegue o topo da pilha duas vezes, multiplique o resultado, envie para o topo da pilha (pilha: 4)<br \/>3&#8211; para o topo da pilha (pilha: 4, 3)<br \/>4&#8211; para o topo da pilha (pilha: 4, 3, 4)<br \/>*&#8211; pegue o topo da pilha duas vezes, multiplique o resultado, envie-o para o topo da pilha (pilha: 4, 12)<br \/>+&#8211; pegue o topo da pilha duas vezes, some o resultado, envie-o para o topo da pilha (pilha: 16)<\/p>\n<p>Como voc\u00ea pode ver &#8211; o resultado das opera\u00e7\u00f5es 16 permanece na pilha, ele pode ser impresso implementando opcodes de impress\u00e3o da pilha, por exemplo:<br \/>p22*34*+P<\/p>\n<p>P &#8211; C\u00f3digo de opera\u00e7\u00e3o de in\u00edcio de impress\u00e3o da pilha, p &#8211; opcode para finalizar a impress\u00e3o da pilha e enviar a linha final para renderiza\u00e7\u00e3o.<br \/>Para converter opera\u00e7\u00f5es aritm\u00e9ticas de infixo para p\u00f3s-fixo, \u00e9 usado o algoritmo de Edsger Dijkstra chamado \u201cSorting Yard\u201d. Um exemplo da implementa\u00e7\u00e3o pode ser visto acima, ou no reposit\u00f3rio do projeto de pilha de m\u00e1quinas nodejs abaixo.<\/p>\n<h3>Fontes<\/h3>\n<p><a href=\"https:\/\/tech.badoo.com\/ru\/article\/579\/interpretatory-bajt-kodov-svoimi-rukami\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/ \/tech.badoo.com\/ru\/article\/579\/interpretatory-bajt-kodov-svoimi-rukami\/<\/a><br \/><a href=\"https:\/\/ru.wikipedia.org\/wiki\/\u041e\u0431\u0440\u0430\u0442\u043d\u0430\u044f_\u043f\u043e\u043b\u044c\u0441\u043a\u0430\u044f_\u0437\u0430\u043f\u0438\u0441\u044c\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/ru.wikipedia.org\/wiki\/\u041e\u0431\u0440\u0430\u0442\u043d\u0430\u044f_\u043f\u043e\u043b\u044c\u0441\u043a\u0430\u044f_\u0437\u0430\u043f\u0438\u0441\u044c<\/a><\/p>\n<h3>C\u00f3digo fonte<\/h3>\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/stackvm\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/gitlab.com\/demensdeum\/stackvm\/<\/a>< \/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Suponha que precisemos implementar um interpretador de bytecode simples. Que abordagem devemos escolher para implementar essa tarefa? Estrutura de dados A pilha fornece a capacidade de implementar uma m\u00e1quina de bytecode simples. Os recursos e implementa\u00e7\u00f5es de m\u00e1quinas stack s\u00e3o descritos em muitos artigos na Internet ocidental e dom\u00e9stica. Apenas mencionarei que a m\u00e1quina virtual<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/pt\/2020\/06\/13\/stack-machine\/\">Continue reading <span class=\"screen-reader-text\">&#8220;M\u00e1quina de empilhar e RPN&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,52],"tags":[160,157,158,159],"class_list":["post-2756","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","tag-bytecode","tag-datastructures","tag-stack","tag-vm","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"pt","enabled_languages":["en","ru","zh","de","fr","ja","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2756","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2756"}],"version-history":[{"count":14,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2756\/revisions"}],"predecessor-version":[{"id":3911,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2756\/revisions\/3911"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=2756"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2756"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2756"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}