我正在尝试为决策逻辑表设计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")]