【问题标题】:Learning DLR (how to implement a language on top of it)学习 DLR(如何在其上实现语言)
【发布时间】:2013-12-15 23:53:54
【问题描述】:

我正在尝试学习如何在 DLR 之上编写一种简单的脚本语言,方法是使用一个非常古老的 DLR 示例,称为 ToyScript。然而,ToyScript 似乎不支持以下脚本结构,我想在我的实现中使用它:

print b()
def b() { 
  return 1 
}

它会引发异常,与大多数静态编译的语言完全相同。'

如果脚本遵循“静态语言范例”:

def b() { 
  return 1 
}
print b()

ToyScript 可以正常运行。

我的问题是:前者应该如何在 DLR 中完成?

[显然我正在寻找解决方案的描述,而不是解决方案本身:)]

【问题讨论】:

  • 关于“在大多数静态编译语言中”:我不知道,但我知道在许多 动态 语言中执行第一个块时会出错也是(JavaScript、Python 和 Ruby,仅举几例)。
  • 我刚刚查看了IronPython,但实现它似乎需要做很多工作。您可能想看看他们是如何做到的,然后反复试验。
  • 你必须做一个更聪明的解释器。它需要使 two 穿过该代码。第一遍必须添加定义,第二遍执行代码。静态编译器这样做的方式:)
  • 脚本通常从上到下解释。因此,对 b 的调用不能在声明之前。

标签: c# dynamic-language-runtime dynamic-languages


【解决方案1】:

有几种可能的实现方式。第一个是要求执行来创建一个函数。通过这种方式,您不能在通过执行创建函数之前调用函数。第二种方法是在解析代码并执行全局脚本时创建所有函数。通过这种方式,函数声明可以出现在代码中的任何位置,因为函数在任何执行之前已经创建。缺点是无论您是否调用它们,您都需要创建所有函数。然后有一种中间方式;第一次解析代码时,会将函数的抽象语法树 (AST) 存储在函数表中。然后当你想调用一个函数时,在函数表中查找函数声明,然后从 AST 编译或解释。比较以下两个 JavaScript sn-ps,你会有一个好主意。

console.log(b());
function b() {
    return 1;
}

console.log(b());
var b = function() {
    return 1;
}

【讨论】:

  • 非常感谢您的建议,但我觉得必须有一个更简单的解决方案可用:)。考虑 C# 中的“动态”关键字。您可以在对象上调用未知成员,并在运行时完成正确的绑定。虽然我根本不是编译器专家,但我想逻辑上相似的东西可以用来实现我的目标:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 2018-04-28
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多