在F#中转换抽象语法树(AST)

我正在尝试为决策逻辑表设计AST.我希望能够用代表我的AST的区别联合做的事情之一是由于不同的原因而改变它的一部分.为清楚起见,我将举一个例子

决策逻辑表

@ VAR = 10 ;Y;

以上内容可以理解,因为有一条规则,条件VAR = 10用Y条目输入此规则.

抽象语法树定义(本例简化)

 type expression = 
     | Value of double
     | Variable of string 
     | Equality of expression * expression

type entry =
    | Entry of string

type entries =
    | Entries of entry list

type conditional =
    | ConditionEntries of expression * entries

type condition
    | Condition of expression * string

type rule = 
    | Rule of condition list

渲染(变换前)

ConditionEntries(
    Equality(
        Variable("VAR"), 
        Value(10.0)), 
    Entries(["Y"]))

渲染(变换后)

Rule(
    Condition(
        Equality(
            Variable("VAR"),
            Value(10.0)
        ),
        Entry("Y")
    )
)

现在我想要做的是转换上面的树来扩展条目中表示的规则.我的想法是我可以使用递归函数和模式匹配来做到这一点,但我现在正在绕着它缠绕一点点麻烦.

我想在本质上我想要做的是每当我看到一个ConditionEntries节点时,我想为条目列表中的每个字符串发出一个新规则,其中条件与条目组合.这有任何意义吗?

提前感谢任何建议.

附:我还没有完全尝试编译上面的例子,所以请原谅任何语法错误.

最佳答案 嗯,基于你的AST,这是一个非常分手,这里是一个转换函数,它产生你想要的输入的输出(虽然它不是递归的,只是使用List.map与一些模式匹配.表达式是你唯一的递归类型,但它看起来你不想递归处理它?):

let ex1 =
    ConditionEntries(
        Equality(
            Variable("VAR"), 
            Value(10.0)), 
        Entries([Entry("Y")]))

let ex2 =
    ConditionEntries(
        Equality(
            Variable("VAR"), 
            Value(10.0)), 
        Entries([Entry("X");Entry("Y");Entry("Z")]))

let transform ces =
    match ces with
    | ConditionEntries(x, Entries(entries)) ->
        entries
        |> List.map (function Entry(entry) -> Condition(x, entry))


//FSI output:
> transform ex1;;
val it : condition list =
  [Condition (Equality (Variable "VAR",Value 10.0),"Y")]
> transform ex2;;
val it : condition list =
  [Condition (Equality (Variable "VAR",Value 10.0),"X");
   Condition (Equality (Variable "VAR",Value 10.0),"Y");
   Condition (Equality (Variable "VAR",Value 10.0),"Z")]
点赞