我正在尝试为决策逻辑表设计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节点时,我想为条目列表中的条目与条目组合的每个字符串发出一个新规则。这有什么意义吗?
提前感谢任何建议。
P.S。我还没有完全尝试编译上面的例子,所以请原谅任何语法错误。
答案 0 :(得分: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")]