我将如何实现一种简单的基于堆栈的编程语言

2023-12-28

我有兴趣通过实现基于堆栈的编程语言来扩展我的计算机编程知识。我正在寻求从哪里开始的建议,因为我打算让它具有类似“pushint 1" 会将值为 1 的整数推送到堆栈顶部,并通过诸如 " 之类的标签进行流量控制L01: jump L01:".

到目前为止,我已经实现了我想要的语言的 C# 实现(想要链接到它,但 IDEOne 被阻止),但它非常混乱,需要优化。它将输入转换为 XML,然后对其进行解析。我的目标是使用较低级别的语言(可能是 C/C++),但我的问题是实现一个可以容纳各种数据类型并且没有固定大小的堆栈。

最终我还想实现数组和函数。此外,我认为我需要一个更好的词法分析器,我想知道解析树对于这种简单的语言是否是一个好主意。

欢迎任何建议/批评,请考虑到我对编程仍然相当陌生(我最近刚刚完成 AP CompSci I)。此外,欢迎链接到基于开源堆栈的语言。

这是一个我想尝试解释/编译的基本程序(其中[this is a comment]):

[Hello World!]
pushchar    '\n'
pushstring  "Hello World!"
print
[Count to 5 and then count down!]
pushint     1
setlocal    0
L01:
pushchar    '\n'
getlocal    0
print           [print x + '\n']
getlocal    0
increment
setlocal    0   [x = x + 1]
pushint     5
getlocal    0
lessthan        [x < 5]
iftrue      L01
L02:
pushchar    '\n'
getlocal    0
print           [print x + '\n']
getlocal    0
decrement
setlocal    0   [x = x - 1]
pushint     0
getlocal    0
greaterthan     [x > 0]
iftrue      L02

预期输出为:

Hello World!
1
2
3
4
5
4
3
2
1

基于堆栈的语言,例如Factor http://factorcode.org/具有以下语法:

2 3 + 5 - print

这相当于以下 C 风格代码:

print(2 + 3 - 5);

使用基于堆栈的语言的优点是实现起来很简单。此外,如果该语言使用逆波兰表示法 http://en.wikipedia.org/wiki/Reverse_Polish_notation,就像大多数基于堆栈的语言一样,那么您所需要的一切前端 http://en.wikipedia.org/wiki/Compiler#Front_end你的语言是一个词法分析器。您不需要将标记解析为语法树,因为只有一种方法可以解码标记流。

您试图创建的不是基于堆栈的编程语言,而是基于堆栈的虚拟机 http://en.wikipedia.org/wiki/Comparison_of_application_virtual_machines。应用程序虚拟机可以是基于堆栈 http://en.wikipedia.org/wiki/Stack_machine or 基于寄存器 http://en.wikipedia.org/wiki/Register_machine。例如,Java虚拟机 http://en.wikipedia.org/wiki/Java_Virtual_Machine是基于堆栈的。它执行Java字节码 http://en.wikipedia.org/wiki/Java_bytecode(这就是您正在创建的内容 - 虚拟机的字节码)。然而,编译为该字节码的编程语言(例如 Java、Erlang、Groovy 等)不是基于堆栈的。

您尝试创建的内容就像您自己的虚拟机的汇编级语言,它恰好是基于堆栈的。话虽这么说,这样做相当容易——基于堆栈的虚拟机更容易实现基于寄存器的虚拟机。同样,您所需要的只是一个词法分析器,例如flex http://github.com/westes/flex。这是一个使用 JavaScript 编写的小示例,使用名为lexer https://github.com/aaditmshah/lexer:

var program = "[print(2 + 3)]";
program += "\n push 2";
program += "\n push 3";
program += "\n add";
program += "\n print";

lexer.setInput(program);

var token;
var stack = [];
var push = false;

while (token = lexer.lex()) {
    switch (token) {
    case "NUMBER":
        if (push) stack.push(lexer.yytext);
        else alert("Unexpected number.");
        break;
    case "ADD":
        if (push) alert("Expected number.");
        else stack.push(stack.pop() + stack.pop());
        break;
    case "PRINT":
        if (push) alert("Expected number.");
        else alert(stack.pop());
        break;
    }

    push = token === "PUSH";
}
<script src="https://rawgit.com/aaditmshah/lexer/master/lexer.js"></script>
<script>
var lexer = new Lexer;

lexer.addRule(/\s+/, function () {
    // matched whitespace - discard it
});

lexer.addRule(/\[.*\]/, function () {
    // matched a comment - discard it
});

lexer.addRule(/\d+/, function (lexeme) {
    this.yytext = parseInt(lexeme);
    return "NUMBER";
});

lexer.addRule(/push/, function () {
    return "PUSH";
});

lexer.addRule(/add/, function () {
    return "ADD";
});

lexer.addRule(/print/, function () {
    return "PRINT";
});
</script>

这真的很简单。您可以摆弄该程序并根据您的需要进行修改。祝你好运。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我将如何实现一种简单的基于堆栈的编程语言 的相关文章

  • Python BeautifulSoup XML 解析

    我编写了一个简单的脚本来使用 BeautifulSoup 模块解析 XML 聊天日志 标准 soup prettify 工作正常 只是聊天日志中有很多绒毛 您可以在下面看到我正在使用的脚本代码和一些 XML 输入文件 Code import
  • Beautiful Soup 获取动态表数据

    我有以下代码 url https www basketball reference com leagues NBA 2017 standings html all expanded standings html urlopen url so
  • 如何读取本地 JSON 文件进行测试

    我正在尝试编写用于 json 验证的单元测试 因为该应用程序严重依赖于来自 REST API 的 json 我有一个包含简单 json 的本地文件 goodFeaturedJson txt 内容 test TEST 测试用例 void te
  • serde_json::from_str 错误,其中字符串来自文件

    extern crate serde json use serde json Value use std fs File use std io prelude fn main let filepath map test anhui txt
  • Xtext和ANTLR之间有什么关系?

    我听说Xtext最终使用ANTLR 但他们的语法规范文件的格式有些不同 那么两者之间是什么关系呢 Xtext 依赖于 Antlr 解析器生成器来解析输入文件 除此之外 该框架还提供了许多附加值 例如强类型 AST 链接抽象和静态分析以及 E
  • 从电话号码确定国际电话代码的算法

    我可以使用 iOS 上的地址簿框架从设备中检索联系人的电话号码 如何区分或识别哪个是国家 地区代码 哪个是实际电话号码 是否可以 国家 地区代码是一个相当混乱的主题 但足够标准 通过一些程序员维护就可以解决它 您可以通过其初始子序列来识别国
  • 如何从 pandas 数据框中包含文本的列中提取年份(或日期时间)

    假设我有一个 pandas 数据框 Id Book 1 Harry Potter 1997 2 Of Mice and Men 1937 3 Babe Ruth Story The 1948 Drama 948 Babe Ruth Stor
  • 生成基于内联 HTML 样式的样式表?

    一段时间以来 我一直致力于对网站的不同部分进行样式设计 但是我尚未将内联样式放入样式表中 我想知道是否存在一个工具可以解析 HTML 文件并从中生成样式表 例如 这是我网站的一个片段 div class block style border
  • 在 JavaScript 中解析 PHP 数组

    我有一些 PHP 源代码 它们是简单的键值数组 如下所示 return array var1 gt var2 And return array sub gt array var1 gt var2 我需要将它们解析为 JavaScript 对
  • PHP - 解析具有固定列宽的文本文件

    我是 PHP 和 Laravel 的新手 我需要打开文件并解析内容以将它们传递到数据库 文本文件具有固定的列宽 它没有分隔符或标题 我认为使用子字符串并将每个子字符串分配给变量将是正确的方法 但我仍在学习该语言的过程中 我不知道如何实现这一
  • Scala 组合器解析器 - 区分数字字符串和变量字符串

    我正在做 Cay Horstmann 的组合器解析器练习 我想知道区分代表数字的字符串和代表匹配语句中变量的字符串的最佳方法 def factor Parser ExprTree wholeNumber expr ident case a
  • AWK 中多行的匹配正则表达式。 && 操作员?

    我不确定 运算符在正则表达式中是否有效 我想做的是匹配一行 使其以数字开头并具有字母 a 下一行以数字开头并具有字母 b 并且下一行 字母 c 该 abc 序列将用作开始读取文件的唯一标识符 这就是我在 awk 中想要的东西 0 9 a n
  • String.Format 小数,带有千位分隔符和强制小数位

    我想String Format小数 使其同时具有千位分隔符和强制小数位 3 例如 Input 123456 12 78545 8 Output 123 456 120 78 545 800 我努力了 String Format 0 0 0
  • XAML解析异常

    我有一个简单的 XAML 页面 当它作为 Visual Studio 中任何应用程序的一部分加载时 加载效果良好 但是 当我使用 ClickOnce 部署此应用程序时 出现以下异常 Type System Windows Markup Xa
  • 在压缩存档内的文本文件上运行“head”,而不解压存档

    问候 我接手了之前的团队并编写了处理 csv 文件的 ETL 作业 我在 ubuntu 上结合使用 shell 脚本和 perl csv 文件很大 它们以压缩档案形式到达 解压后 很多都超过 30Gb 是的 那是 G 旧进程是在 cron
  • SimpleDateFormat.parse() 忽略模式中的字符数

    我正在尝试解析一个可以具有不同格式的日期字符串 尽管字符串不应与第二个模式匹配 但它却以某种方式匹配 因此返回错误的日期 这是我的代码 import java text ParseException import java text Sim
  • 在 Delphi 中使用 XML(将特定数据返回到变量)

    过去几天我一直在尝试使用 Delphi 2010 和 MSXML 我是一个极端的新手 需要一点指导 var MemoryStream TMemoryStream XMLPath String sName String XMLDoc vari
  • 使用 Boost Spirit 和 Fusion 以关联方式解析结构

    我正在尝试将键值字符串解析为结构 一些键值可能不存在或者顺序不同 所以我想使用boost fusion调整结构 然后解析它at key lt gt 指示 include
  • 帮我用 PHP 解析这个文件

    Fri Nov 27 10 00 01 EST 2009 974 12506 Fri Nov 27 11 00 01 EST 2009 988 12655 Fri Nov 27 12 00 01 EST 2009 1005 12886 Fr
  • [Nearley]:如何解析匹配的开始和结束标记

    我正在尝试用nearley 解析一种非常简单的语言 您可以在匹配的开始和结束标记之间放置一个字符串 并且可以链接一些标记 它看起来像一种 XML 但带有 代替 lt 标签总是 2 个字符长 并且没有嵌套 aa My text aa ab A

随机推荐

  • XCode自动生成注释?

    每次当我在 XCode 中创建一个新文件时 它都会在文件顶部做出一些注释 最近它发生了某种变化 我不知道为什么以及如何重置它 现在是这样的 Filename cpp Projectname Created by Name on Date C
  • 为什么 setMap(null) 不起作用 google 地图 api v3?

    我正在使用谷歌地图 API 3 9 在应用程序中 用户可以添加标记或删除标记 当用户单击地图时 将显示信息窗口 用户可以在其中输入名称 纬度 经度 然后单击保存图像 如下所示 google maps event addListener ma
  • Git:创建新分支并推送到远程的有效步骤

    我想出了步骤 但看起来很麻烦 采取bitbucket例如 假设我已经有一个名为prj 我从服务器端 bitbucket com 分支一个新项目 名为prj bz 从本地我添加添加远程git remote add prj bz https b
  • 在 SLURM 中运行没有顶级脚本的二进制文件

    在 SGE PBS 中 我可以像在本地一样向集群提交二进制可执行文件 例如 qsub b y cwd echo hello 将提交一个名为 echo 的作业 该作业将单词 hello 写入其输出文件 我如何向 SLURM 提交类似的工作 它
  • 删除所有行,从 /pattern/ 之后的两行开始

    假设我有一个文件如下 drink eat XXX pizza blunzn sushi 我想从文件中删除所有行 从模式后的第三行开始XXX 所以结果应该是这样的 drink eat XXX pizza blunzn 删除之后的所有行XXX很
  • Hibernate Criteria n+1 最大结果问题

    使用 hibernate ctiteria 我想选择一个对象及其关联的 oneToMany 对象列表 我想对此列表进行分页 以避免可怕的休眠 n 1 选择问题 这是一个可行的解决方案 需要 10 个父对象对数据库进行 11 次访问 Crit
  • PHP登录系统硬编码用户名和密码

    我必须做一个基本的登录系统来保护页面 并且我无法访问数据库 所以我将用户名和密码硬编码存储在 php 页面中 我的问题是 这个登录系统能抵御攻击吗 我需要它保持大约1个月 任何改进建议都会有所帮助 该代码不在 Laravel 中 即使它看起
  • Nuxt部署错误:服务器资源不可用

    为了在 ssr 模式下部署我们的 nuxt 网站 我们首先在 bitbucket 管道中构建和单元测试网站 如果测试成功 我们将构建文件从 bitbucket 服务器复制到我们的生产服务器并触发启动 问题是 Nuxt 文档没有说明服务器上需
  • 与同时使用 minmax_element 相比 min_element 和 max_element 是否有任何效率优势?

    std minmax element 返回一个对 其中包含一个到最小元素的迭代器作为第一个元素 一个到最大元素的迭代器作为第二个元素 std min element 返回一个迭代器到范围 first last 中的最小元素 std max
  • 如何向我的 Linq 选择添加唯一的行号?

    我有以下代码 public IEnumerable
  • Django 1.5:访问 models.py 中的自定义用户模型字段

    我正在开发 Django 1 5 项目 我有一个自定义用户模型 我们称之为CustomUser 另一个应用程序 SomeApp 需要引用此自定义用户模型 为了ForeignKey等的目的 Django文档说使用 User settings
  • 连接两个字符数组?

    如果我有两个像这样的字符数组 char one 200 char two 200 然后我想做第三个连接这些的我该怎么做呢 我努力了 char three 400 strcpy three one strcat three two 但这似乎不
  • 使用 MultipartEntity 构造 POST 请求

    我想构造一个多部分请求 具有以下参数 名称 字符串 电子邮件 字符串 和文件上传 文件 我正在使用下面的 Java 代码 在 Android 中工作 httppost getRequestLine 打印 POST http www myur
  • Shell 重定向与显式文件处理代码

    我的母语不是英语 所以请原谅这个问题的尴尬标题 我只是不知道如何更好地表达它 我在 FreeBSD 机器上 我有一个用以下语言编写的小过滤工具C它通过读取数据列表stdin并通过输出处理后的列表stdout 我像这样调用它 find typ
  • 为什么微调器中的 onNothingSelected 没有被调用?

    我有一个 Android Spinner 当用户在显示 Spinner 的选择面板时按 后退键 时 我想监听该事件 我已经实现了 OnItemSelectedListener 但按后退键时未调用 onNothingSelected Adap
  • Django 的 mod_wsgi 错误:从守护进程读取响应标头时超时

    我正在运行 Django 2 0 4 和 mod wsgi 4 5 20 当我尝试将站点部署到我们的开发环境时 出现错误 parature 奇怪的是 该站点部署在根目录下VirtualHost正在正常响应 Tue Apr 10 13 34
  • 如何在字段级别创建元注释?

    我有这个带注释的休眠类 Entity public class SimponsFamily Id TableGenerator name ENTITY ID GENERATOR table ENTITY ID GENERATOR TABLE
  • Python有效地找到多个多项式的局部最大值/最小值

    我正在寻找一种有效的方法来查找多个 gt 100万 但独立的四阶多项式的局部最小值给定 指定范围 边界 我有两个要求 R1 即使对于 100 万个不同的多项式方程也有效 R2 局部最小值精确到 0 01 即 2dp 这是我使用创建的一些代码
  • 按计划手动触发 GitHub 操作

    我想按计划手动触发 GitHub 操作 但出现以下代码并出现错误 name Update data on workflow dispatch schedule cron 0 5 30 我正在寻找如何正确执行此操作的解决方案 并且有两种选择
  • 我将如何实现一种简单的基于堆栈的编程语言

    我有兴趣通过实现基于堆栈的编程语言来扩展我的计算机编程知识 我正在寻求从哪里开始的建议 因为我打算让它具有类似 pushint 1 会将值为 1 的整数推送到堆栈顶部 并通过诸如 之类的标签进行流量控制L01 jump L01 到目前为止