1 回答
错误来自在您需要 a 时
v1
有一个类型,因为您正在与每个or进行比较,它们都有 type 。问题的根源是您的构造函数有错误的类型,它应该是,因为在您的语言的构造中应该是一个变量,它用您的实现中的类型表示。expr
char
v1
v
Var v
char
Bes
Bes of char * expr * expr
v
let v = x in y
char
使用预处理来实现 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
语言的原语并正确编译它。如果您决定坚持预处理阶段,那么您不应该
Bes
首先添加到原语集,并且每次解析器看到 let 语句时都执行 AST->AST 转换。那么你将永远不会Bes
在编译器代码中看到。这本质上会产生let
一个语法糖或一个宏,这又是一个不正确的 Let 语义,参见上面的 (1) 和 (2)。