0
4

1 回答 1

0
  1. 错误来自在您需要 a 时v1有一个类型,因为您正在与每个or进行比较,它们都有 type 。问题的根源是您的构造函数有错误的类型,它应该是,因为在您的语言的构造中应该是一个变量,它用您的实现中的类型表示。exprcharv1vVar vcharBesBes of char * expr * exprvlet v = x in ychar

  2. 使用预处理来实现 let 并不是一个好主意:

    2.1。它将爆炸您的代码,请考虑以下示例:

    let x = <very-big-expr> in
    let y = x + x + x in
    y + y
    

    最终将重复<very-big-exp>6 次。一般来说,这将是一个指数爆炸,这将导致 AST 的千兆字节

    2.2. 复制表达式并不总是有效的,例如在表达式可能有副作用的语言中,这将破坏程序的语义,请考虑以下示例

    let x = read_int () in
    let y = read_int () in
    x*x + y
    

    假设输入是"3\n4\n",正确的实现应该返回 3*3+4=13,而你的实现会导致代码,

    read_int () * read_int () + read_int ()
    

    这将读取两个整数将它们相乘并要求第三个整数并因通道错误结束而失败。

    这意味着,您必须保留Bes语言的原语并正确编译它。

  3. 如果您决定坚持预处理阶段,那么您不应该Bes首先添加到原语集,并且每次解析器看到 let 语句时都执行 AST->AST 转换。那么你将永远不会Bes在编译器代码中看到。这本质上会产生let一个语法糖或一个宏,这又是一个不正确的 Let 语义,参见上面的 (1) 和 (2)。

于 2019-02-15T17:29:46.860 回答