在 F# 中使用 tokens/symbols 实现用于构建非常简单的树 (AST) 的函数

Implementing a function for building a very simple tree (AST) using tokens/symbols in F#

我看了how to make a tree from a given data with F# and https://citizen428.net/blog/learning-fsharp-binary-search-tree/

基本上我试图做的是实现一个函数来构建一个非常简单的 AST,使用可区分的联合 (DU) 来表示树。

我想用tokens/symbols来建树。我觉得这些也可以用DU来代表。我正在努力实现插入功能。

假设我们使用以下来表示树。基本思想是,对于整数的加法和减法,我只需要二叉树。表达式可以是运算符或常量。这可能是实现树的错误方式,但我不确定。

type Tree =
| Node of Tree * Expression * Tree
| Empty
and Expression =
| Operator //could be a token or another type
| Constant of int

让我们使用以下内容来表示令牌。可能有更聪明的方法来做到这一点。这只是一个例子。

type Token =
    | Integer
    | Add
    | Subtract

如何实现插入功能?我写了下面的函数并尝试了不同的插入元素的方法。

let rec insert tree element = 
    match element, tree with
    //use Empty to initalize
    | x, Empty -> Node(Empty, x, Empty)
    | x, Node(Empty,y,Empty) when (*x is something here*) -> Node((*something*))
    | _, _ -> failwith "Missing case"

如果您有什么建议或者 link,我将不胜感激。

我认为从树插入的角度来思考问题不是很有帮助,因为你真正想做的是解析一个标记序列。所以,普通的树插入不是很有用。相反,您需要以更具体的方式构建树(表达式)。

例如,假设我有:

let input = [Integer 1; Add; Integer 2; Subtract; Integer 1;]

假设我想解析这个标记序列以获得 1 + (2 - 1) 的表示(其中有错误的括号,但它更容易解释这个想法)。

我的方法是定义递归 Expression 类型而不是使用一般树:

type Token =
  | Integer of int
  | Add
  | Subtract

type Operator = 
  | AddOp | SubtractOp

type Expression =
  | Binary of Operator * Expression * Expression
  | Constant of int

要解析一系列标记,您可以这样写:

let rec parse input = 
  match input with 
  | Integer i::Add::rest ->
      Binary(AddOp, Constant i, parse rest)
  | Integer i::Subtract::rest ->
      Binary(SubtractOp, Constant i, parse rest)
  | Integer i::[] ->
      Constant i
  | _ -> failwith "Unexpected token"

这会查找以 Integer i; Add; ... 开头或类似减法的列表,并递归地构造树。使用上面的输入,你得到:

> parse input;;
val it : Expression =
  Binary (AddOp, Constant 1, 
    Binary (SubtractOp, Constant 2, Constant 1))