4

我正在尝试为决策逻辑表设计 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 节点时,我想为 Entries 列表中的每个字符串发出一个新规则,其中 Condition 与 Entry 结合。这有任何意义吗?

提前感谢您的任何建议。

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

4

1 回答 1

2

嗯,根据你的 AST,它被严重分解了,这是一个tranform从你想要的输入产生输出的函数(虽然它不是递归的,只是List.map与一些模式匹配一​​起使用。expression是你唯一的递归类型,但它看起来不像你想递归处理它吗?):

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")]
于 2011-09-19T02:24:11.820 回答