词法作用域是如何实现的? [关闭]

2023-12-29

几年前,我开始为一种小型领域特定语言编写解释器,其中包括程序员定义的函数。

起初,我使用简单的符号表堆栈实现了变量作用域。但现在我想转向正确的词法范围(带有闭包选项)。谁能解释词法范围背后的数据结构和算法?


要在解释器中获得正确的词法作用域和闭包,您需要做的就是遵循以下规则:

  • 在你的解释器中,变量总是在环境表中查找由调用者传入或保存为变量,而不是一些全局环境堆栈。您的 eval 操作的签名就像eval(expression, env) => value.
  • 当解释代码调用函数时,环境是NOT传递给该函数。您的函数应用程序操作的签名如下apply(function, arguments) => value.
  • 当调用解释函数时,其函数体求值的环境是函数定义的环境,与调用者没有任何关系。所以如果你有一个局部函数,那么它就是一个closure,即包含字段的数据结构{function definition, env-at-definition-time}.

扩展 Python 式语法的最后一点:

x = 1
return lambda y: x + y

应该像执行一样执行

x = 1
return make_closure(<AST for "lambda y: x + y">, {"x": x})

其中第二个 dict 参数可能只是 current-env 而不是当时构造的数据结构。 (另一方面,保留整个环境而不仅仅是封闭变量可能意味着程序会出现令人惊讶的内存泄漏,因为闭包保留了不需要的东西。这在任何“实用”语言实现中都值得修复,但不值得当你刚刚尝试语言语义时。)

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

词法作用域是如何实现的? [关闭] 的相关文章

  • 左/右旋转进位的实际用途

    循环左进位和循环右进位指令有哪些实际用途 在我的汇编课上 我们无法想出一个有用的好例子 如果要将位从一个操作数移出并移入另一个操作数 SHL EAX 1 move sign bit of EAX RCL EDX into LSB of ED
  • 如何使用谷歌趋势查找编程语言流行总体趋势的统计数据

    我喜欢关注趋势浏览器 操作系统 语言等 我发现谷歌趋势是一个非常有用的资源有时但有时我无法获得我想要的信息 与多年来其他主要 Linux 发行版相比 Ubuntu 的增长非常明显 在发布日期附近有 6 个月度峰值 由于非编程相关事件而出现偏
  • 被调用的函数在被调用后如何返回给调用者?

    我读到 当程序进行函数调用时 被调用的函数必须知道如何返回其调用者 我的问题是 被调用的函数如何知道如何返回其调用者 是否有一种机制通过编译器在幕后工作 编译器遵循特定的 调用约定 该约定定义为您所针对的 ABI 的一部分 该调用约定将包括
  • Javascript 闭包问题

    所以 我仍在阅读 Apress Pro Javascript 技术 但我在闭包方面遇到了麻烦 正如约翰 雷西格所说 闭包允许您引用父函数中存在的变量 然而 它在创建变量时并不提供变量的值 它提供父函数中变量的最后一个值 这是最常见的问题 您
  • 如何在代码生成过程中简化包含变量的 C 风格算术表达式?

    我正在尝试优化编译器中的表达式求值 算术表达式都是C风格的 并且它们可以包含变量 我希望尽可能简化表达 例如 3 100 A B 100 3 100可以简化为409 300 A B 主要取决于分配律 结合律和交换律 我遇到的主要困难是如何将
  • 扩展 Mono C# 编译器:有任何文档或先例吗?

    我目前正在参与一些有趣的编程语言研究 到目前为止 这些研究的重点是通过一些非常强大的基于程序员生产力的功能来扩展即将推出的 Java 7 0 编译器 这项工作应该同样适用于 C 等相关编程语言 我目前正在研究用于对该功能的 C 端口进行原型
  • 向 Java 类添加编程注释

    使用示例 我想在类字段上添加一个自定义注释 MyContainer 然后在所有此类字段上自动添加相关的 Hibernate 注释 取决于字段类型和属性 另外 我需要向类添加 JAXB XmlType 注释 并使类型名称基于类名称 我还想根据
  • 错误:在 Java 中声明布尔值时不是一个语句

    下面的代码 boolean continue false 返回以下错误 error not a statement boolean continue false 为什么会发生这种情况 我对布尔值非常熟悉 试试这个 boolean cont
  • 你能克隆一个闭包吗?

    A FnMut由于显而易见的原因 闭包无法被克隆 但是Fn闭包具有不可变的范围 有没有办法创建一个 重复 Fn关闭 尝试克隆它会导致 error E0599 no method named clone found for type std
  • 实现词法分析器时,DFA 与正则表达式?

    我刚刚学习如何编写编译器 所以如果我有任何错误的说法 请纠正我 当人们可以简单地使用正则表达式时 为什么还要在代码中实现 DFA goto 语句 表驱动实现 据我了解 词法分析器接收一串字符并生成一个标记列表 这些标记在语言的语法定义中是终
  • JavaScript:事件处理程序:在哪里声明变量 - 本地变量还是闭包(与开销)?

    我发现自己编写了各种包含事件处理程序的函数 感觉最好在父函数 闭包 的根部声明处理函数所需的变量 特别是如果它们是 jQuery 选择 多个处理程序所需的常量 或者需要一些我不想要的预计算每次触发事件时重复 一个简单的例子 var touc
  • 如何将这段 javascript 代码重写为 C++11?

    这是我在 Javascript Definitive Guide 中看到的 javascript 闭包代码 我想把它写成C 11 var uniqueID1 function var id 0 return function return
  • 使用 Yew 回调作为 wasm_bindgen 闭包

    这个问题是为 Yew v0 19 编写的 异步外部 JavaScript 函数可以通过以下方式在 Rust 中使用Closures https rustwasm github io wasm bindgen api wasm bindgen
  • 我收到此警告: com.sun.org.apache.xml.internal.serialize.OutputFormat 是 Sun 专有 API,可能会在未来版本中删除

    我的代码是 OutputFormat wOf new OutputFormat XML ISO 8859 1 true 帮我解决这个警告 提前致谢 一种解决方案是不使用该类 另一种解决方案是忽略该警告 看看这个类 我怀疑这是唯一可行的解 决
  • Java 拥有闭包后 Scala 的优势 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 随着 Java 中添加了闭包 作为语言选择 Scala 相对于 Java 的优势是什么 有人可以详细说明一下有什么优点吗 除了闭包 J
  • 不明白 Swift 中的闭包示例

    我正在尝试了解 swift 和闭包 我被这个例子困住了 numbers map number Int gt Int in let result 3 number return result 什么是 number Int gt Int 它是一
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • C# 中的编译器

    我正在寻找一个可定制的解析器和 或词法分析器 它可以让我在 C 中构建自定义语法检查器 本质上 用户将输入一行代码 自定义 语法检查器将能够响应是否编写正确 That s Irony http irony codeplex com 请务必阅
  • ARM NEON 矢量化失败

    我想在 ARM cortex a9 上启用 NEON 矢量化 但在编译时得到以下输出 未矢量化 不支持相关 stmt D 14140 82 D 14143 77 D 14141 81 这是我的循环 void my mul float32 t
  • 为什么需要数字后缀?

    C 语言 我确信还有其他语言 需要在数字文字末尾添加后缀 这些后缀指示文字的类型 例如 5m是一个小数 5f是一个浮点数 我的问题是 这些后缀真的有必要吗 或者是否可以从上下文中推断出文字的类型 例如 代码decimal d 5 0应该推断

随机推荐