修复带有可区分联合的直接循环引用

Fix immediate cyclic references with discriminated unions

我正在制作一个迷你 Pascal 解析器,this Pascal syntax 支持声明无限类型:

program ::= program identifier ; block .

block ::= variable-declaration-part procedure-declaration-part statement-part

procedure-declaration-part ::= { procedure-declaration ; }

procedure-declaration ::= procedure identifier ; block

我尝试为此语法创建 AST 域类型:

type Program = Identifier * Block
and Block = VariableDeclaration list option * ProcedureDeclaration list option * Statement list
and ProcedureDeclaration = Identifier * Block

但是编译器会抛出错误,因为我使用了类型别名,并且它们在编译时被删除了:

This type definition involves an immediate cyclic reference through an abbreviation

有人说我可以用包装的可区分联合类型解决这个问题,我该怎么办?

and ProcedureDeclaration = ProcedureDeclaration of Identifier * Block

现在它不仅仅是一个元组,而是一个单一大小写的 DU 类型,您可以使用例如

创建它
ProcedureDeclaration(someID, someBlock)

并分解为

match somePD with
| ProcedureDeclaration(i,b) -> ...