F# 在F中转换抽象语法树(AST)#
我正在尝试为决策逻辑表设计一个AST。对于代表AST的受歧视的联合,我希望能够做的一件事是出于不同的原因转换它的部分。为了清楚起见,我将给你举个例子 决策逻辑表F# 在F中转换抽象语法树(AST)#,f#,pattern-matching,abstract-syntax-tree,discriminated-union,F#,Pattern Matching,Abstract Syntax Tree,Discriminated Union,我正在尝试为决策逻辑表设计一个AST。对于代表AST的受歧视的联合,我希望能够做的一件事是出于不同的原因转换它的部分。为了清楚起见,我将给你举个例子 决策逻辑表 type expression = | Value of double | Variable of string | Equality of expression * expression type entry = | Entry of string type entries =
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
@VAR=10;Y
上述内容可以理解为有一条规则,条件VAR=10以Y条目输入该规则
抽象语法树定义(本例简化)
渲染(变换前)
渲染(变换后)
现在我想做的是转换上面的树,以扩展条目中表示的规则。我的想法是,我可以使用递归函数和模式匹配来实现这一点,但我现在有一点麻烦
我想本质上我要做的是,每当我看到ConditionEntries节点时,我想为Entries列表中的每个字符串发出一个新规则,其中条件与条目相结合。这有什么意义吗
提前谢谢你的建议
p、 我还没有试着编译上面的例子,所以请原谅任何语法错误。Hmm,根据您的AST,它被严重破坏了,这里有一个
transform
函数,它根据您想要的输入生成输出(虽然它不是递归的,但只使用带有一些模式匹配的List.map
。expression
是您唯一的递归类型,但看起来您不想递归地处理它。):
很抱歉AST被破坏了,为了简洁起见,我想我只会包括相关部分。谢谢你的回答,我稍后会尝试一下。不过还有一个问题:如果ConditionEntries和Condition位于另一个节点下,转换函数会有很大变化吗?(即,我只想更改“部分”)Hi Jeffrey,别担心,拆分的AST对我来说并不冒犯,我只是担心您建模语言的方式可能太复杂(AST中构建了太多语义?).关于你的后续问题,我不确定是否看不到大局,但一般来说,如果你只想变换一棵树的一部分,你可以有一个最终的全包匹配,它只返回树的分支不变,类似于
。|branch->branch
谢谢Stephen,我会测试它。
ConditionEntries(
Equality(
Variable("VAR"),
Value(10.0)),
Entries(["Y"]))
Rule(
Condition(
Equality(
Variable("VAR"),
Value(10.0)
),
Entry("Y")
)
)
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")]