gpt4 book ai didi

haskell - 编译器中中缀运算符的类型检查

转载 作者:行者123 更新时间:2023-12-02 14:02:37 25 4
gpt4 key购买 nike

我正在编写一个编译器(用Haskell),并且在该语言的语法中存在添加中缀运算符的规则(以加法为例):

EAdd . Expr ::= Expr "+" Expr

这意味着EAdd是一个表达式,它由表达式、字符串"+"和另一个表达式组成。

解析器返回抽象语法树(AST):

data Expr = ... | EAdd Expr Expr

我想创建一个类型检查器,检查是否为函数的调用提供了正确类型的参数。

请注意,“+”是一个接受两个整数并返回一个整数的函数。其他运算符类似。

目前,我想出了三种类型检查 EAdd 的方法,所有这些方法都包括将“+”作为函数添加到初始符号表中:

  1. 声明中缀加是用两个参数调用函数“+”的语法糖。将“desugarizer”放在解析器和类型检查器之间,将 AST 从解析器转换为另一种数据类型(不带EAdd)。

  2. (与第一个类似)声明中缀加是语法糖,但脱糖器使用相同的 AST 数据类型。当给定 EAdd 时,类型检查器会返回错误。

  3. 将“脱糖器”内联到类型检查器中。与此类似:

    ...
    typecheck (EAdd a b) = typecheck (ECall infixPlus [a, b])
    ...

请注意,所有二进制中缀运算符均受此约束(其他算术、 bool 运算、比较运算符)。

看来第一种方法是正确的。但这意味着稍后在编译器管道中,特别是在代码生成器中,这些ECalls应该作为特殊情况进行处理,因为在编译器输出中(在我的例子中 - llvm )这些函数应该是内联的(与通常的函数调用不同)。这意味着 codegen 有一个函数列表,其调用的处理方式与其他函数调用不同。

解决这个问题的最佳方法是什么?

UPD

如何在 Haskell 中处理类似的问题(来自 https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/Renamer ):

... renamer does the following things:

  • Sort out fixities. The parser parses all infix applications as left-associative, regardless of fixity. For example "a + b * c" is parsed as "(a + b) * c". The renamer re-associates such nested operator applications, using the fixities declared in the module.

最佳答案

LLVM 支持inline attributes例如

define void @f() alwaysinline { ... }

因此,一种选择是将 + 视为普通函数调用,并让 LLVM 完成其优化工作。

关于haskell - 编译器中中缀运算符的类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29854658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com